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

Commit e45a767e authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "Revert "Fix decoder EOS handling"" into klp-dev

parents 6bf9ae20 b6209a3d
Loading
Loading
Loading
Loading
+115 −102
Original line number Diff line number Diff line
@@ -58,8 +58,6 @@ SoftAAC2::SoftAAC2(
      mIsADTS(false),
      mInputBufferCount(0),
      mSignalledError(false),
      mSawInputEos(false),
      mSignalledOutputEos(false),
      mAnchorTimeUs(0),
      mNumSamplesOutput(0),
      mOutputPortSettingsChange(NONE) {
@@ -352,30 +350,65 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
        return;
    }

    while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
        BufferInfo *inInfo = NULL;
        OMX_BUFFERHEADERTYPE *inHeader = NULL;
        if (!inQueue.empty()) {
            inInfo = *inQueue.begin();
            inHeader = inInfo->mHeader;
        }
    while (!inQueue.empty() && !outQueue.empty()) {
        BufferInfo *inInfo = *inQueue.begin();
        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;

        BufferInfo *outInfo = *outQueue.begin();
        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
        outHeader->nFlags = 0;

        if (inHeader) {
        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
                mSawInputEos = true;
            inQueue.erase(inQueue.begin());
            inInfo->mOwnedByUs = false;
            notifyEmptyBufferDone(inHeader);

            if (mDecoderHasData) {
                // flush out the decoder's delayed data by calling DecodeFrame
                // one more time, with the AACDEC_FLUSH flag set
                INT_PCM *outBuffer =
                        reinterpret_cast<INT_PCM *>(
                                outHeader->pBuffer + outHeader->nOffset);

                AAC_DECODER_ERROR decoderErr =
                    aacDecoder_DecodeFrame(mAACDecoder,
                                           outBuffer,
                                           outHeader->nAllocLen,
                                           AACDEC_FLUSH);
                mDecoderHasData = false;

                if (decoderErr != AAC_DEC_OK) {
                    mSignalledError = true;

                    notify(OMX_EventError, OMX_ErrorUndefined, decoderErr,
                           NULL);

                    return;
                }

            if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
                outHeader->nFilledLen =
                        mStreamInfo->frameSize
                            * sizeof(int16_t)
                            * mStreamInfo->numChannels;
            } else {
                // we never submitted any data to the decoder, so there's nothing to flush out
                outHeader->nFilledLen = 0;
            }

            outHeader->nFlags = OMX_BUFFERFLAG_EOS;

            outQueue.erase(outQueue.begin());
            outInfo->mOwnedByUs = false;
            notifyFillBufferDone(outHeader);
            return;
        }

        if (inHeader->nOffset == 0) {
            mAnchorTimeUs = inHeader->nTimeStamp;
            mNumSamplesOutput = 0;
        }

            if (mIsADTS) {
        size_t adtsHeaderSize = 0;
        if (mIsADTS) {
            // skip 30 bits, aac_frame_length follows.
            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????

@@ -427,9 +460,6 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
            inBufferLength[0] = inHeader->nFilledLen;
        }
        } else {
            inBufferLength[0] = 0;
        }

        // Fill and decode
        INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(
@@ -441,41 +471,26 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
        int prevNumChannels = mStreamInfo->numChannels;

        AAC_DECODER_ERROR decoderErr = AAC_DEC_NOT_ENOUGH_BITS;
        while ((bytesValid[0] > 0 || mSawInputEos) && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
            mDecoderHasData |= (bytesValid[0] > 0);
        while (bytesValid[0] > 0 && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
            aacDecoder_Fill(mAACDecoder,
                            inBuffer,
                            inBufferLength,
                            bytesValid);
            mDecoderHasData = true;

            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
                                                outBuffer,
                                                outHeader->nAllocLen,
                                                0 /* flags */);

            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
                if (mSawInputEos && bytesValid[0] <= 0) {
                    if (mDecoderHasData) {
                        // flush out the decoder's delayed data by calling DecodeFrame
                        // one more time, with the AACDEC_FLUSH flag set
                        decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
                                                            outBuffer,
                                                            outHeader->nAllocLen,
                                                            AACDEC_FLUSH);
                        mDecoderHasData = false;
                    }
                    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
                    mSignalledOutputEos = true;
                    break;
                } else {
                ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
            }
        }
        }

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

        if (inHeader) {
        if (decoderErr == AAC_DEC_OK) {
            UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
            inHeader->nFilledLen -= inBufferUsedLength;
@@ -501,7 +516,6 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            notifyEmptyBufferDone(inHeader);
            inHeader = NULL;
        }
        }

        /*
         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
@@ -541,6 +555,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
            // we've previously decoded valid data, in the latter case
            // (decode failed) we'll output a silent frame.
            outHeader->nFilledLen = numOutBytes;
            outHeader->nFlags = 0;

            outHeader->nTimeStamp =
                mAnchorTimeUs
@@ -591,8 +606,6 @@ void SoftAAC2::onReset() {
    mStreamInfo->sampleRate = 0;

    mSignalledError = false;
    mSawInputEos = false;
    mSignalledOutputEos = false;
    mOutputPortSettingsChange = NONE;
}

+0 −2
Original line number Diff line number Diff line
@@ -55,8 +55,6 @@ private:
    bool mDecoderHasData;
    size_t mInputBufferCount;
    bool mSignalledError;
    bool mSawInputEos;
    bool mSignalledOutputEos;
    int64_t mAnchorTimeUs;
    int64_t mNumSamplesOutput;

+53 −61
Original line number Diff line number Diff line
@@ -49,8 +49,6 @@ SoftMP3::SoftMP3(
      mNumChannels(2),
      mSamplingRate(44100),
      mSignalledError(false),
      mSawInputEos(false),
      mSignalledOutputEos(false),
      mOutputPortSettingsChange(NONE) {
    initPorts();
    initDecoder();
@@ -196,36 +194,48 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
    List<BufferInfo *> &inQueue = getPortQueue(0);
    List<BufferInfo *> &outQueue = getPortQueue(1);

    while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
        BufferInfo *inInfo = NULL;
        OMX_BUFFERHEADERTYPE *inHeader = NULL;
        if (!inQueue.empty()) {
            inInfo = *inQueue.begin();
            inHeader = inInfo->mHeader;
        }
    while (!inQueue.empty() && !outQueue.empty()) {
        BufferInfo *inInfo = *inQueue.begin();
        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;

        BufferInfo *outInfo = *outQueue.begin();
        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
        outHeader->nFlags = 0;

        if (inHeader) {
            if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
                mAnchorTimeUs = inHeader->nTimeStamp;
                mNumFramesOutput = 0;
        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
            inQueue.erase(inQueue.begin());
            inInfo->mOwnedByUs = false;
            notifyEmptyBufferDone(inHeader);

            if (!mIsFirst) {
                // pad the end of the stream with 529 samples, since that many samples
                // were trimmed off the beginning when decoding started
                outHeader->nFilledLen =
                    kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);

                memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
            } else {
                // Since we never discarded frames from the start, we won't have
                // to add any padding at the end either.
                outHeader->nFilledLen = 0;
            }

            if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
                mSawInputEos = true;
            outHeader->nFlags = OMX_BUFFERFLAG_EOS;

            outQueue.erase(outQueue.begin());
            outInfo->mOwnedByUs = false;
            notifyFillBufferDone(outHeader);
            return;
        }

        if (inHeader->nOffset == 0) {
            mAnchorTimeUs = inHeader->nTimeStamp;
            mNumFramesOutput = 0;
        }

        mConfig->pInputBuffer =
            inHeader->pBuffer + inHeader->nOffset;

        mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
        } else {
            mConfig->pInputBuffer = NULL;
            mConfig->inputBufferCurrentLength = 0;
        }
        mConfig->inputBufferMaxLength = 0;
        mConfig->inputBufferUsedLength = 0;

@@ -252,28 +262,13 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
                mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
            }

            if (decoderErr == NO_ENOUGH_MAIN_DATA_ERROR && mSawInputEos) {
                if (!mIsFirst) {
                    // pad the end of the stream with 529 samples, since that many samples
                    // were trimmed off the beginning when decoding started
                    outHeader->nOffset = 0;
                    outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);

                    memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
                }
                outHeader->nFlags = OMX_BUFFERFLAG_EOS;
                mSignalledOutputEos = true;
            } else {
            // This is recoverable, just ignore the current frame and
            // play silence instead.
            memset(outHeader->pBuffer,
                   0,
                   mConfig->outputFrameSize * sizeof(int16_t));

                if (inHeader) {
            mConfig->inputBufferUsedLength = inHeader->nFilledLen;
                }
            }
        } else if (mConfig->samplingRate != mSamplingRate
                || mConfig->num_channels != mNumChannels) {
            mSamplingRate = mConfig->samplingRate;
@@ -294,7 +289,7 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {

            outHeader->nFilledLen =
                mConfig->outputFrameSize * sizeof(int16_t) - outHeader->nOffset;
        } else if (!mSignalledOutputEos) {
        } else {
            outHeader->nOffset = 0;
            outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
        }
@@ -303,12 +298,14 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
            mAnchorTimeUs
                + (mNumFramesOutput * 1000000ll) / mConfig->samplingRate;

        if (inHeader) {
        outHeader->nFlags = 0;

        CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);

        inHeader->nOffset += mConfig->inputBufferUsedLength;
        inHeader->nFilledLen -= mConfig->inputBufferUsedLength;

        mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;

        if (inHeader->nFilledLen == 0) {
            inInfo->mOwnedByUs = false;
@@ -317,9 +314,6 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
            notifyEmptyBufferDone(inHeader);
            inHeader = NULL;
        }
        }

        mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;

        outInfo->mOwnedByUs = false;
        outQueue.erase(outQueue.begin());
@@ -368,8 +362,6 @@ void SoftMP3::onReset() {
    pvmp3_InitDecoder(mConfig, mDecoderBuf);
    mIsFirst = true;
    mSignalledError = false;
    mSawInputEos = false;
    mSignalledOutputEos = false;
    mOutputPortSettingsChange = NONE;
}

+0 −2
Original line number Diff line number Diff line
@@ -61,8 +61,6 @@ private:

    bool mIsFirst;
    bool mSignalledError;
    bool mSawInputEos;
    bool mSignalledOutputEos;

    enum {
        NONE,
+34 −39
Original line number Diff line number Diff line
@@ -54,8 +54,6 @@ SoftVorbis::SoftVorbis(
      mAnchorTimeUs(0),
      mNumFramesOutput(0),
      mNumFramesLeftOnPage(-1),
      mSawInputEos(false),
      mSignalledOutputEos(false),
      mOutputPortSettingsChange(NONE) {
    initPorts();
    CHECK_EQ(initDecoder(), (status_t)OK);
@@ -292,47 +290,48 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
        return;
    }

    while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
        BufferInfo *inInfo = NULL;
        OMX_BUFFERHEADERTYPE *inHeader = NULL;
        if (!inQueue.empty()) {
            inInfo = *inQueue.begin();
            inHeader = inInfo->mHeader;
        }
    while (!inQueue.empty() && !outQueue.empty()) {
        BufferInfo *inInfo = *inQueue.begin();
        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;

        BufferInfo *outInfo = *outQueue.begin();
        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;

        int32_t numPageSamples = 0;

        if (inHeader) {
        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
                mSawInputEos = true;
            inQueue.erase(inQueue.begin());
            inInfo->mOwnedByUs = false;
            notifyEmptyBufferDone(inHeader);

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

            outQueue.erase(outQueue.begin());
            outInfo->mOwnedByUs = false;
            notifyFillBufferDone(outHeader);
            return;
        }

            if (inHeader->nFilledLen || !mSawInputEos) {
        int32_t numPageSamples;
        CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples));
        memcpy(&numPageSamples,
               inHeader->pBuffer
                + inHeader->nOffset + inHeader->nFilledLen - 4,
               sizeof(numPageSamples));

        if (numPageSamples >= 0) {
            mNumFramesLeftOnPage = numPageSamples;
        }

        if (inHeader->nOffset == 0) {
            mAnchorTimeUs = inHeader->nTimeStamp;
            mNumFramesOutput = 0;
        }

        inHeader->nFilledLen -= sizeof(numPageSamples);;
            }
        }

        if (numPageSamples >= 0) {
            mNumFramesLeftOnPage = numPageSamples;
        }

        ogg_buffer buf;
        buf.data = inHeader ? inHeader->pBuffer + inHeader->nOffset : NULL;
        buf.size = inHeader ? inHeader->nFilledLen : 0;
        buf.data = inHeader->pBuffer + inHeader->nOffset;
        buf.size = inHeader->nFilledLen;
        buf.refcount = 1;
        buf.ptr.owner = NULL;

@@ -385,13 +384,11 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {

        mNumFramesOutput += numFrames;

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

        outInfo->mOwnedByUs = false;
        outQueue.erase(outQueue.begin());
@@ -428,8 +425,6 @@ void SoftVorbis::onReset() {
        mVi = NULL;
    }

    mSawInputEos = false;
    mSignalledOutputEos = false;
    mOutputPortSettingsChange = NONE;
}

Loading