Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b34662b authored by Andreas Huber's avatar Andreas Huber Committed by android-build SharedAccount
Browse files

Squashed commit of the following:

commit 4abf16bb04dc9695fedf4007a84f903074312ccd
Author: Andreas Huber <andih@google.com>
Date:   Tue Jul 20 09:21:17 2010 -0700

    Support a single format change at the beginning of audio playback. This way the AAC+ decoder may change its output format from what is originally encoded in the audio stream and we'll still play it back correctly.

    Change-Id: Icc790122744745e9a88099788d4818ca1e265a82
    related-to-bug: 2826841

commit 09c74da63e6ad5cb5dafb70f62696d75d2978967
Author: James Dong <jdong@google.com>
Date:   Sun Jul 18 17:57:01 2010 -0700

    Fix MPEG4Extractor to extract sampling frequency correctly when SBR is enabled.

    Change-Id: I883c81dad3ea465e71cb5590e89d763671a90ff8

commit f672bf2a782dc7d5fb6325d611a7fe17045dfe9a
Author: James Dong <jdong@google.com>
Date:   Thu Jul 8 20:56:13 2010 -0700

    Enable the support for decoding audio with AAC+ and eAAC+ features

    bug - 282684

    Change-Id: I73c8377af3cc4edd3ee7cea86dc3b1c369fbd78b

Change-Id: I012f1179e933b6d1345d2368f357576c722485f7
parent eb2e0954
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -86,6 +86,10 @@ private:

    bool mStarted;

    bool mIsFirstBuffer;
    status_t mFirstBufferResult;
    MediaBuffer *mFirstBuffer;

    sp<MediaPlayerBase::AudioSink> mAudioSink;

    static void AudioCallback(int event, void *user, void *info);
+63 −3
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>

@@ -41,6 +42,9 @@ AudioPlayer::AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink)
      mReachedEOS(false),
      mFinalStatus(OK),
      mStarted(false),
      mIsFirstBuffer(false),
      mFirstBufferResult(OK),
      mFirstBuffer(NULL),
      mAudioSink(audioSink) {
}

@@ -68,6 +72,24 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
        }
    }

    // We allow an optional INFO_FORMAT_CHANGED at the very beginning
    // of playback, if there is one, getFormat below will retrieve the
    // updated format, if there isn't, we'll stash away the valid buffer
    // of data to be used on the first audio callback.

    CHECK(mFirstBuffer == NULL);

    mFirstBufferResult = mSource->read(&mFirstBuffer);
    if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
        LOGV("INFO_FORMAT_CHANGED!!!");

        CHECK(mFirstBuffer == NULL);
        mFirstBufferResult = OK;
        mIsFirstBuffer = false;
    } else {
        mIsFirstBuffer = true;
    }

    sp<MetaData> format = mSource->getFormat();
    const char *mime;
    bool success = format->findCString(kKeyMIMEType, &mime);
@@ -87,7 +109,14 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
                DEFAULT_AUDIOSINK_BUFFERCOUNT,
                &AudioPlayer::AudioSinkCallback, this);
        if (err != OK) {
            if (mFirstBuffer != NULL) {
                mFirstBuffer->release();
                mFirstBuffer = NULL;
            }

            if (!sourceAlreadyStarted) {
                mSource->stop();
            }

            return err;
        }
@@ -108,7 +137,14 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
            delete mAudioTrack;
            mAudioTrack = NULL;

            if (mFirstBuffer != NULL) {
                mFirstBuffer->release();
                mFirstBuffer = NULL;
            }

            if (!sourceAlreadyStarted) {
                mSource->stop();
            }

            return err;
        }
@@ -159,6 +195,12 @@ void AudioPlayer::stop() {

    // Make sure to release any buffer we hold onto so that the
    // source is able to stop().

    if (mFirstBuffer != NULL) {
        mFirstBuffer->release();
        mFirstBuffer = NULL;
    }

    if (mInputBuffer != NULL) {
        LOGV("AudioPlayer releasing input buffer.");

@@ -243,6 +285,14 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
            Mutex::Autolock autoLock(mLock);

            if (mSeeking) {
                if (mIsFirstBuffer) {
                    if (mFirstBuffer != NULL) {
                        mFirstBuffer->release();
                        mFirstBuffer = NULL;
                    }
                    mIsFirstBuffer = false;
                }

                options.setSeekTo(mSeekTimeUs);

                if (mInputBuffer != NULL) {
@@ -255,7 +305,17 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
        }

        if (mInputBuffer == NULL) {
            status_t err = mSource->read(&mInputBuffer, &options);
            status_t err;

            if (mIsFirstBuffer) {
                mInputBuffer = mFirstBuffer;
                mFirstBuffer = NULL;
                err = mFirstBufferResult;

                mIsFirstBuffer = false;
            } else {
                err = mSource->read(&mInputBuffer, &options);
            }

            CHECK((err == OK && mInputBuffer != NULL)
                   || (err != OK && mInputBuffer == NULL));
+65 −45
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include "AACDecoder.h"
#define LOG_TAG "AACDecoder"

#include "../../include/ESDS.h"

@@ -36,26 +37,33 @@ AACDecoder::AACDecoder(const sp<MediaSource> &source)
      mAnchorTimeUs(0),
      mNumSamplesOutput(0),
      mInputBuffer(NULL) {
}

AACDecoder::~AACDecoder() {
    if (mStarted) {
        stop();
    }
    sp<MetaData> srcFormat = mSource->getFormat();

    delete mConfig;
    mConfig = NULL;
}
    int32_t sampleRate;
    CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));

status_t AACDecoder::start(MetaData *params) {
    CHECK(!mStarted);
    mMeta = new MetaData;
    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);

    mBufferGroup = new MediaBufferGroup;
    mBufferGroup->add_buffer(new MediaBuffer(2048 * 2));
    // We'll always output stereo, regardless of how many channels are
    // present in the input due to decoder limitations.
    mMeta->setInt32(kKeyChannelCount, 2);
    mMeta->setInt32(kKeySampleRate, sampleRate);

    int64_t durationUs;
    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
        mMeta->setInt64(kKeyDuration, durationUs);
    }
    mMeta->setCString(kKeyDecoderComponent, "AACDecoder");

    mInitCheck = initCheck();
}

status_t AACDecoder::initCheck() {
    memset(mConfig, 0, sizeof(tPVMP4AudioDecoderExternal));
    mConfig->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
    mConfig->aacPlusUpsamplingFactor = 0;
    mConfig->aacPlusEnabled = false;
    mConfig->aacPlusEnabled = 1;

    // The software decoder doesn't properly support mono output on
    // AACplus files. Always output stereo.
@@ -64,8 +72,11 @@ status_t AACDecoder::start(MetaData *params) {
    UInt32 memRequirements = PVMP4AudioDecoderGetMemRequirements();
    mDecoderBuf = malloc(memRequirements);

    CHECK_EQ(PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf),
             MP4AUDEC_SUCCESS);
    status_t err = PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf);
    if (err != MP4AUDEC_SUCCESS) {
        LOGE("Failed to initialize MP4 audio decoder");
        return UNKNOWN_ERROR;
    }

    uint32_t type;
    const void *data;
@@ -83,18 +94,29 @@ status_t AACDecoder::start(MetaData *params) {
        mConfig->pInputBuffer = (UChar *)codec_specific_data;
        mConfig->inputBufferCurrentLength = codec_specific_data_size;
        mConfig->inputBufferMaxLength = 0;
        mConfig->inputBufferUsedLength = 0;
        mConfig->remainderBits = 0;

        mConfig->pOutputBuffer = NULL;
        mConfig->pOutputBuffer_plus = NULL;
        mConfig->repositionFlag = false;

        if (PVMP4AudioDecoderConfig(mConfig, mDecoderBuf)
                != MP4AUDEC_SUCCESS) {
            return ERROR_UNSUPPORTED;
        }
    }
    return OK;
}

AACDecoder::~AACDecoder() {
    if (mStarted) {
        stop();
    }

    delete mConfig;
    mConfig = NULL;
}

status_t AACDecoder::start(MetaData *params) {
    CHECK(!mStarted);

    mBufferGroup = new MediaBufferGroup;
    mBufferGroup->add_buffer(new MediaBuffer(4096 * 2));

    mSource->start();

@@ -127,28 +149,7 @@ status_t AACDecoder::stop() {
}

sp<MetaData> AACDecoder::getFormat() {
    sp<MetaData> srcFormat = mSource->getFormat();

    int32_t sampleRate;
    CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));

    sp<MetaData> meta = new MetaData;
    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);

    // We'll always output stereo, regardless of how many channels are
    // present in the input due to decoder limitations.
    meta->setInt32(kKeyChannelCount, 2);

    meta->setInt32(kKeySampleRate, sampleRate);

    int64_t durationUs;
    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
        meta->setInt64(kKeyDuration, durationUs);
    }

    meta->setCString(kKeyDecoderComponent, "AACDecoder");

    return meta;
    return mMeta;
}

status_t AACDecoder::read(
@@ -200,13 +201,32 @@ status_t AACDecoder::read(
    mConfig->remainderBits = 0;

    mConfig->pOutputBuffer = static_cast<Int16 *>(buffer->data());
    mConfig->pOutputBuffer_plus = NULL;
    mConfig->pOutputBuffer_plus = &mConfig->pOutputBuffer[2048];
    mConfig->repositionFlag = false;

    Int decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf);

    // Check on the sampling rate to see whether it is changed.
    int32_t sampleRate;
    CHECK(mMeta->findInt32(kKeySampleRate, &sampleRate));
    if (mConfig->samplingRate != sampleRate) {
        mMeta->setInt32(kKeySampleRate, mConfig->samplingRate);
        LOGW("Sample rate was %d, but now is %d",
                sampleRate, mConfig->samplingRate);
        buffer->release();
        mInputBuffer->release();
        mInputBuffer = NULL;
        return INFO_FORMAT_CHANGED;
    }

    size_t numOutBytes =
        mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels;
    if (mConfig->aacPlusUpsamplingFactor == 2) {
        if (mConfig->desiredChannels == 1) {
            memcpy(&mConfig->pOutputBuffer[1024], &mConfig->pOutputBuffer[2048], numOutBytes * 2);
        }
        numOutBytes *= 2;
    }

    if (decoderErr != MP4AUDEC_SUCCESS) {
        LOGW("AAC decoder returned error %d, substituting silence", decoderErr);
+4 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ struct tPVMP4AudioDecoderExternal;
namespace android {

struct MediaBufferGroup;
struct MetaData;

struct AACDecoder : public MediaSource {
    AACDecoder(const sp<MediaSource> &source);
@@ -41,6 +42,7 @@ protected:
    virtual ~AACDecoder();

private:
    sp<MetaData>    mMeta;
    sp<MediaSource> mSource;
    bool mStarted;

@@ -50,9 +52,11 @@ private:
    void *mDecoderBuf;
    int64_t mAnchorTimeUs;
    int64_t mNumSamplesOutput;
    status_t mInitCheck;

    MediaBuffer *mInputBuffer;

    status_t initCheck();
    AACDecoder(const AACDecoder &);
    AACDecoder &operator=(const AACDecoder &);
};