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

Commit 089edf2e authored by Marco Nelissen's avatar Marco Nelissen Committed by Android (Google) Code Review
Browse files

Merge "Fix MediaCodec.flush()" into jb-mr2-dev

parents 5157b1e8 f3bd1972
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -3659,7 +3659,6 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
                     (status_t)OK);

            mCodec->changeState(mCodec->mFlushingState);

            handled = true;
            break;
        }
@@ -4174,6 +4173,10 @@ void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {

        mCodec->mInputEOSResult = OK;

        if (mCodec->mSkipCutBuffer != NULL) {
            mCodec->mSkipCutBuffer->clear();
        }

        mCodec->changeState(mCodec->mExecutingState);
    }
}
+49 −54
Original line number Diff line number Diff line
@@ -118,7 +118,7 @@ status_t SoftAAC2::initDecoder() {
            status = OK;
        }
    }
    mIsFirst = true;
    mDecoderHasData = false;

    // for streams that contain metadata, use the mobile profile DRC settings unless overridden
    // by platform properties:
@@ -327,6 +327,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
            return;
        }

        inQueue.erase(inQueue.begin());
        info->mOwnedByUs = false;
        notifyEmptyBufferDone(header);
@@ -358,7 +359,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            inInfo->mOwnedByUs = false;
            notifyEmptyBufferDone(inHeader);

            if (!mIsFirst) {
            if (mDecoderHasData) {
                // flush out the decoder's delayed data by calling DecodeFrame
                // one more time, with the AACDEC_FLUSH flag set
                INT_PCM *outBuffer =
@@ -370,6 +371,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
                                           outBuffer,
                                           outHeader->nAllocLen,
                                           AACDEC_FLUSH);
                mDecoderHasData = false;

                if (decoderErr != AAC_DEC_OK) {
                    mSignalledError = true;
@@ -385,9 +387,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
                            * sizeof(int16_t)
                            * mStreamInfo->numChannels;
            } else {
                // Since we never discarded frames from the start, we won't have
                // to add any padding at the end either.

                // we never submitted any data to the decoder, so there's nothing to flush out
                outHeader->nFilledLen = 0;
            }

@@ -473,6 +473,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
                            inBuffer,
                            inBufferLength,
                            bytesValid);
            mDecoderHasData = true;

            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
                                                outBuffer,
@@ -484,6 +485,35 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            }
        }

        size_t numOutBytes =
            mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;

        if (decoderErr == AAC_DEC_OK) {
            UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
            inHeader->nFilledLen -= inBufferUsedLength;
            inHeader->nOffset += inBufferUsedLength;
        } else {
            ALOGW("AAC decoder returned error %d, substituting silence",
                  decoderErr);

            memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);

            // Discard input buffer.
            inHeader->nFilledLen = 0;

            aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);

            // fall through
        }

        if (inHeader->nFilledLen == 0) {
            inInfo->mOwnedByUs = false;
            inQueue.erase(inQueue.begin());
            inInfo = NULL;
            notifyEmptyBufferDone(inHeader);
            inHeader = NULL;
        }

        /*
         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
         * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
@@ -502,15 +532,9 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            if (mStreamInfo->sampleRate != prevSampleRate ||
                mStreamInfo->numChannels != prevNumChannels) {
                maybeConfigureDownmix();
                ALOGI("Reconfiguring decoder: %d Hz, %d channels",
                      mStreamInfo->sampleRate,
                      mStreamInfo->numChannels);

                // We're going to want to revisit this input buffer, but
                // may have already advanced the offset. Undo that if
                // necessary.
                inHeader->nOffset -= adtsHeaderSize;
                inHeader->nFilledLen += adtsHeaderSize;
                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
                      prevSampleRate, mStreamInfo->sampleRate,
                      prevNumChannels, mStreamInfo->numChannels);

                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
                mOutputPortSettingsChange = AWAITING_DISABLED;
@@ -523,38 +547,10 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            return;
        }

        size_t numOutBytes =
            mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;

        if (decoderErr == AAC_DEC_OK) {
            UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
            inHeader->nFilledLen -= inBufferUsedLength;
            inHeader->nOffset += inBufferUsedLength;
        } else {
            ALOGW("AAC decoder returned error %d, substituting silence",
                  decoderErr);

            memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);

            // Discard input buffer.
            inHeader->nFilledLen = 0;

            aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);

            // fall through
        }

        if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) {
            // We'll only output data if we successfully decoded it or
            // we've previously decoded valid data, in the latter case
            // (decode failed) we'll output a silent frame.
            if (mIsFirst) {
                mIsFirst = false;
                // the first decoded frame should be discarded to account
                // for decoder delay
                numOutBytes = 0;
            }

            outHeader->nFilledLen = numOutBytes;
            outHeader->nFlags = 0;

@@ -571,14 +567,6 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            outHeader = NULL;
        }

        if (inHeader->nFilledLen == 0) {
            inInfo->mOwnedByUs = false;
            inQueue.erase(inQueue.begin());
            inInfo = NULL;
            notifyEmptyBufferDone(inHeader);
            inHeader = NULL;
        }

        if (decoderErr == AAC_DEC_OK) {
            ++mInputBufferCount;
        }
@@ -589,14 +577,21 @@ void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
    if (portIndex == 0) {
        // Make sure that the next buffer output does not still
        // depend on fragments from the last one decoded.
        aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
        mIsFirst = true;
        // drain all existing data
        drainDecoder();
    }
}

void SoftAAC2::onReset() {
void SoftAAC2::drainDecoder() {
    short buf [2048];
    aacDecoder_DecodeFrame(mAACDecoder, buf, 4096, AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
    aacDecoder_DecodeFrame(mAACDecoder, buf, 4096, AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
    aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
    mIsFirst = true;
    mDecoderHasData = false;
}

void SoftAAC2::onReset() {
    drainDecoder();
}

void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+2 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ private:
    HANDLE_AACDECODER mAACDecoder;
    CStreamInfo *mStreamInfo;
    bool mIsADTS;
    bool mIsFirst;
    bool mDecoderHasData;
    size_t mInputBufferCount;
    bool mSignalledError;
    int64_t mAnchorTimeUs;
@@ -68,6 +68,7 @@ private:
    status_t initDecoder();
    bool isConfigured() const;
    void maybeConfigureDownmix() const;
    void drainDecoder();

    DISALLOW_EVIL_CONSTRUCTORS(SoftAAC2);
};