diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/Android.mk | 1 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 13 | ||||
-rw-r--r-- | media/libmedia/SingleStateQueueInstantiations.cpp | 2 | ||||
-rw-r--r-- | media/libnbaio/Android.mk | 5 | ||||
-rw-r--r-- | media/libnbaio/AudioStreamOutSink.cpp | 15 | ||||
-rw-r--r-- | media/libnbaio/MonoPipe.cpp | 13 | ||||
-rw-r--r-- | media/libnbaio/MonoPipeReader.cpp | 5 | ||||
-rw-r--r-- | media/libnbaio/SourceAudioBufferProvider.cpp | 13 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/codecs/aacdec/SoftAAC2.cpp | 217 | ||||
-rw-r--r-- | media/libstagefright/codecs/aacdec/SoftAAC2.h | 2 | ||||
-rw-r--r-- | media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 114 | ||||
-rw-r--r-- | media/libstagefright/codecs/mp3dec/SoftMP3.h | 2 | ||||
-rw-r--r-- | media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp | 73 | ||||
-rw-r--r-- | media/libstagefright/codecs/vorbis/dec/SoftVorbis.h | 2 |
16 files changed, 271 insertions, 212 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index 96755bb..56e7787 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -62,6 +62,7 @@ LOCAL_SRC_FILES += ../libnbaio/roundup.c LOCAL_CFLAGS += -DANDROID_SMP=$(if $(findstring true,$(TARGET_CPU_SMP)),1,0) LOCAL_SRC_FILES += SingleStateQueue.cpp LOCAL_CFLAGS += -DSINGLE_STATE_QUEUE_INSTANTIATIONS='"SingleStateQueueInstantiations.cpp"' +# Consider a separate a library for SingleStateQueueInstantiations. LOCAL_SHARED_LIBRARIES := \ libui liblog libcutils libutils libbinder libsonivox libicuuc libexpat \ diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 176197c..744faee 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -1714,7 +1714,18 @@ status_t AudioTrack::setParameters(const String8& keyValuePairs) status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp) { AutoMutex lock(mLock); - return mAudioTrack->getTimestamp(timestamp); + // FIXME not implemented for fast tracks; should use proxy and SSQ + if (mFlags & AUDIO_OUTPUT_FLAG_FAST) { + return INVALID_OPERATION; + } + if (mState != STATE_ACTIVE && mState != STATE_PAUSED) { + return INVALID_OPERATION; + } + status_t status = mAudioTrack->getTimestamp(timestamp); + if (status == NO_ERROR) { + timestamp.mPosition += mProxy->getEpoch(); + } + return status; } String8 AudioTrack::getParameters(const String8& keys) diff --git a/media/libmedia/SingleStateQueueInstantiations.cpp b/media/libmedia/SingleStateQueueInstantiations.cpp index 2afebe9..0265c8c 100644 --- a/media/libmedia/SingleStateQueueInstantiations.cpp +++ b/media/libmedia/SingleStateQueueInstantiations.cpp @@ -16,11 +16,13 @@ #include <media/SingleStateQueue.h> #include <private/media/StaticAudioTrackState.h> +#include <media/AudioTimestamp.h> // FIXME hack for gcc namespace android { template class SingleStateQueue<StaticAudioTrackState>; // typedef StaticAudioTrackSingleStateQueue +template class SingleStateQueue<AudioTimestamp>; // typedef AudioTimestampSingleStateQueue } diff --git a/media/libnbaio/Android.mk b/media/libnbaio/Android.mk index 5d00d15..69c75b8 100644 --- a/media/libnbaio/Android.mk +++ b/media/libnbaio/Android.mk @@ -31,6 +31,9 @@ LOCAL_SHARED_LIBRARIES := \ libcommon_time_client \ libcutils \ libutils \ - liblog + liblog \ + libmedia +# This dependency on libmedia is for SingleStateQueueInstantiations. +# Consider a separate a library for SingleStateQueueInstantiations. include $(BUILD_SHARED_LIBRARY) diff --git a/media/libnbaio/AudioStreamOutSink.cpp b/media/libnbaio/AudioStreamOutSink.cpp index 6f525e5..e4341d7 100644 --- a/media/libnbaio/AudioStreamOutSink.cpp +++ b/media/libnbaio/AudioStreamOutSink.cpp @@ -79,4 +79,19 @@ status_t AudioStreamOutSink::getNextWriteTimestamp(int64_t *timestamp) { return mStream->get_next_write_timestamp(mStream, timestamp); } +status_t AudioStreamOutSink::getTimestamp(AudioTimestamp& timestamp) +{ + if (mStream->get_presentation_position == NULL) { + return INVALID_OPERATION; + } + // FIXME position64 won't be needed after AudioTimestamp.mPosition is changed to uint64_t + uint64_t position64; + int ok = mStream->get_presentation_position(mStream, &position64, ×tamp.mTime); + if (ok != 0) { + return INVALID_OPERATION; + } + timestamp.mPosition = position64; + return OK; +} + } // namespace android diff --git a/media/libnbaio/MonoPipe.cpp b/media/libnbaio/MonoPipe.cpp index e8d3d9b..de0ad28 100644 --- a/media/libnbaio/MonoPipe.cpp +++ b/media/libnbaio/MonoPipe.cpp @@ -42,7 +42,10 @@ MonoPipe::MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock) : // mWriteTs mSetpoint((reqFrames * 11) / 16), mWriteCanBlock(writeCanBlock), - mIsShutdown(false) + mIsShutdown(false), + // mTimestampShared + mTimestampMutator(&mTimestampShared), + mTimestampObserver(&mTimestampShared) { CCHelper tmpHelper; status_t res; @@ -310,4 +313,12 @@ bool MonoPipe::isShutdown() return mIsShutdown; } +status_t MonoPipe::getTimestamp(AudioTimestamp& timestamp) +{ + if (mTimestampObserver.poll(timestamp)) { + return OK; + } + return INVALID_OPERATION; +} + } // namespace android diff --git a/media/libnbaio/MonoPipeReader.cpp b/media/libnbaio/MonoPipeReader.cpp index 394f6ac..851341a 100644 --- a/media/libnbaio/MonoPipeReader.cpp +++ b/media/libnbaio/MonoPipeReader.cpp @@ -86,4 +86,9 @@ ssize_t MonoPipeReader::read(void *buffer, size_t count, int64_t readPTS) return red; } +void MonoPipeReader::onTimestamp(const AudioTimestamp& timestamp) +{ + mPipe->mTimestampMutator.push(timestamp); +} + } // namespace android diff --git a/media/libnbaio/SourceAudioBufferProvider.cpp b/media/libnbaio/SourceAudioBufferProvider.cpp index d11a86c..062fa0f 100644 --- a/media/libnbaio/SourceAudioBufferProvider.cpp +++ b/media/libnbaio/SourceAudioBufferProvider.cpp @@ -25,7 +25,7 @@ namespace android { SourceAudioBufferProvider::SourceAudioBufferProvider(const sp<NBAIO_Source>& source) : mSource(source), // mFrameBitShiftFormat below - mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0) + mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0), mFramesReleased(0) { ALOG_ASSERT(source != 0); @@ -90,6 +90,7 @@ void SourceAudioBufferProvider::releaseBuffer(Buffer *buffer) (mOffset + mRemaining <= mSize)); mOffset += buffer->frameCount; mRemaining -= buffer->frameCount; + mFramesReleased += buffer->frameCount; buffer->raw = NULL; buffer->frameCount = 0; mGetCount = 0; @@ -101,4 +102,14 @@ size_t SourceAudioBufferProvider::framesReady() const return avail < 0 ? 0 : (size_t) avail; } +size_t SourceAudioBufferProvider::framesReleased() const +{ + return mFramesReleased; +} + +void SourceAudioBufferProvider::onTimestamp(const AudioTimestamp& timestamp) +{ + mSource->onTimestamp(timestamp); +} + } // namespace android diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index f412dc8..66a0b4e 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -106,6 +106,8 @@ status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) { needDedicatedLooper = true; } else if (!nameIsType && !strncmp(name, "OMX.TI.DUCATI1.VIDEO.", 21)) { needDedicatedLooper = true; + } else if (!nameIsType && !strncmp(name, "OMX.qcom.video.decoder.avc.secure", 33)) { + needDedicatedLooper = true; } if (needDedicatedLooper) { diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp index c9b5d26..1b20cbb 100644 --- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp +++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp @@ -58,8 +58,6 @@ SoftAAC2::SoftAAC2( mIsADTS(false), mInputBufferCount(0), mSignalledError(false), - mSawInputEos(false), - mSignalledOutputEos(false), mAnchorTimeUs(0), mNumSamplesOutput(0), mOutputPortSettingsChange(NONE) { @@ -352,83 +350,115 @@ 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; - } + if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { + 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); - if (inHeader->nOffset == 0 && inHeader->nFilledLen) { - mAnchorTimeUs = inHeader->nTimeStamp; - mNumSamplesOutput = 0; + return; + } + + 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; } - if (mIsADTS) { - size_t adtsHeaderSize = 0; - // skip 30 bits, aac_frame_length follows. - // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? + outHeader->nFlags = OMX_BUFFERFLAG_EOS; - const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset; + outQueue.erase(outQueue.begin()); + outInfo->mOwnedByUs = false; + notifyFillBufferDone(outHeader); + return; + } - bool signalError = false; - if (inHeader->nFilledLen < 7) { - ALOGE("Audio data too short to contain even the ADTS header. " - "Got %ld bytes.", inHeader->nFilledLen); + if (inHeader->nOffset == 0) { + mAnchorTimeUs = inHeader->nTimeStamp; + mNumSamplesOutput = 0; + } + + size_t adtsHeaderSize = 0; + if (mIsADTS) { + // skip 30 bits, aac_frame_length follows. + // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? + + const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset; + + bool signalError = false; + if (inHeader->nFilledLen < 7) { + ALOGE("Audio data too short to contain even the ADTS header. " + "Got %ld bytes.", inHeader->nFilledLen); + hexdump(adtsHeader, inHeader->nFilledLen); + signalError = true; + } else { + bool protectionAbsent = (adtsHeader[1] & 1); + + unsigned aac_frame_length = + ((adtsHeader[3] & 3) << 11) + | (adtsHeader[4] << 3) + | (adtsHeader[5] >> 5); + + if (inHeader->nFilledLen < aac_frame_length) { + ALOGE("Not enough audio data for the complete frame. " + "Got %ld bytes, frame size according to the ADTS " + "header is %u bytes.", + inHeader->nFilledLen, aac_frame_length); hexdump(adtsHeader, inHeader->nFilledLen); signalError = true; } else { - bool protectionAbsent = (adtsHeader[1] & 1); - - unsigned aac_frame_length = - ((adtsHeader[3] & 3) << 11) - | (adtsHeader[4] << 3) - | (adtsHeader[5] >> 5); - - if (inHeader->nFilledLen < aac_frame_length) { - ALOGE("Not enough audio data for the complete frame. " - "Got %ld bytes, frame size according to the ADTS " - "header is %u bytes.", - inHeader->nFilledLen, aac_frame_length); - hexdump(adtsHeader, inHeader->nFilledLen); - signalError = true; - } else { - adtsHeaderSize = (protectionAbsent ? 7 : 9); - - inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize; - inBufferLength[0] = aac_frame_length - adtsHeaderSize; - - inHeader->nOffset += adtsHeaderSize; - inHeader->nFilledLen -= adtsHeaderSize; - } + adtsHeaderSize = (protectionAbsent ? 7 : 9); + + inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize; + inBufferLength[0] = aac_frame_length - adtsHeaderSize; + + inHeader->nOffset += adtsHeaderSize; + inHeader->nFilledLen -= adtsHeaderSize; } + } - if (signalError) { - mSignalledError = true; + if (signalError) { + mSignalledError = true; - notify(OMX_EventError, - OMX_ErrorStreamCorrupt, - ERROR_MALFORMED, - NULL); + notify(OMX_EventError, + OMX_ErrorStreamCorrupt, + ERROR_MALFORMED, + NULL); - return; - } - } else { - inBuffer[0] = inHeader->pBuffer + inHeader->nOffset; - inBufferLength[0] = inHeader->nFilledLen; + return; } } else { - inBufferLength[0] = 0; + inBuffer[0] = inHeader->pBuffer + inHeader->nOffset; + inBufferLength[0] = inHeader->nFilledLen; } // Fill and decode @@ -441,66 +471,50 @@ 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]); - } + 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; - inHeader->nOffset += inBufferUsedLength; - } else { - ALOGW("AAC decoder returned error %d, substituting silence", - decoderErr); + 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); + memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes); - // Discard input buffer. - inHeader->nFilledLen = 0; + // Discard input buffer. + inHeader->nFilledLen = 0; - aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1); + aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1); - // fall through - } + // fall through + } - if (inHeader->nFilledLen == 0) { - inInfo->mOwnedByUs = false; - inQueue.erase(inQueue.begin()); - inInfo = NULL; - notifyEmptyBufferDone(inHeader); - inHeader = NULL; - } + if (inHeader->nFilledLen == 0) { + inInfo->mOwnedByUs = false; + inQueue.erase(inQueue.begin()); + inInfo = NULL; + notifyEmptyBufferDone(inHeader); + inHeader = NULL; } /* @@ -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; } diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h index a7ea1e2..2d960ab 100644 --- a/media/libstagefright/codecs/aacdec/SoftAAC2.h +++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h @@ -55,8 +55,6 @@ private: bool mDecoderHasData; size_t mInputBufferCount; bool mSignalledError; - bool mSawInputEos; - bool mSignalledOutputEos; int64_t mAnchorTimeUs; int64_t mNumSamplesOutput; diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp index 5749733..ff2b503 100644 --- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp +++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp @@ -292,6 +292,10 @@ static AUDIO_OBJECT_TYPE getAOTFromProfile(OMX_U32 profile) { return AOT_AAC_LC; } else if (profile == OMX_AUDIO_AACObjectHE) { return AOT_SBR; + } else if (profile == OMX_AUDIO_AACObjectHE_PS) { + return AOT_PS; + } else if (profile == OMX_AUDIO_AACObjectLD) { + return AOT_ER_AAC_LD; } else if (profile == OMX_AUDIO_AACObjectELD) { return AOT_ER_AAC_ELD; } else { diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index 877e3cb..7c382fb 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -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 (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { - mSawInputEos = true; + 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; } - mConfig->pInputBuffer = - inHeader->pBuffer + inHeader->nOffset; + outHeader->nFlags = OMX_BUFFERFLAG_EOS; - mConfig->inputBufferCurrentLength = inHeader->nFilledLen; - } else { - mConfig->pInputBuffer = NULL; - mConfig->inputBufferCurrentLength = 0; + 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; 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; - } - } + // This is recoverable, just ignore the current frame and + // play silence instead. + memset(outHeader->pBuffer, + 0, + mConfig->outputFrameSize * sizeof(int16_t)); + + 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,24 +298,23 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) { mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mConfig->samplingRate; - if (inHeader) { - CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength); - - inHeader->nOffset += mConfig->inputBufferUsedLength; - inHeader->nFilledLen -= mConfig->inputBufferUsedLength; + outHeader->nFlags = 0; + CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength); - if (inHeader->nFilledLen == 0) { - inInfo->mOwnedByUs = false; - inQueue.erase(inQueue.begin()); - inInfo = NULL; - notifyEmptyBufferDone(inHeader); - inHeader = NULL; - } - } + inHeader->nOffset += mConfig->inputBufferUsedLength; + inHeader->nFilledLen -= mConfig->inputBufferUsedLength; mNumFramesOutput += mConfig->outputFrameSize / mNumChannels; + if (inHeader->nFilledLen == 0) { + inInfo->mOwnedByUs = false; + inQueue.erase(inQueue.begin()); + inInfo = NULL; + notifyEmptyBufferDone(inHeader); + inHeader = NULL; + } + outInfo->mOwnedByUs = false; outQueue.erase(outQueue.begin()); outInfo = NULL; @@ -368,8 +362,6 @@ void SoftMP3::onReset() { pvmp3_InitDecoder(mConfig, mDecoderBuf); mIsFirst = true; mSignalledError = false; - mSawInputEos = false; - mSignalledOutputEos = false; mOutputPortSettingsChange = NONE; } diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h index f9e7b53..4af91ea 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.h +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h @@ -61,8 +61,6 @@ private: bool mIsFirst; bool mSignalledError; - bool mSawInputEos; - bool mSignalledOutputEos; enum { NONE, diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp index a377b23..51bb958 100644 --- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp @@ -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; - } - - if (inHeader->nFilledLen || !mSawInputEos) { - CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples)); - memcpy(&numPageSamples, - inHeader->pBuffer - + inHeader->nOffset + inHeader->nFilledLen - 4, - sizeof(numPageSamples)); + if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { + inQueue.erase(inQueue.begin()); + inInfo->mOwnedByUs = false; + notifyEmptyBufferDone(inHeader); - if (inHeader->nOffset == 0) { - mAnchorTimeUs = inHeader->nTimeStamp; - mNumFramesOutput = 0; - } + outHeader->nFilledLen = 0; + outHeader->nFlags = OMX_BUFFERFLAG_EOS; - inHeader->nFilledLen -= sizeof(numPageSamples);; - } + outQueue.erase(outQueue.begin()); + outInfo->mOwnedByUs = false; + notifyFillBufferDone(outHeader); + return; } + 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);; + 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; - } + 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; } diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h index 1d00816..cb628a0 100644 --- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h @@ -59,8 +59,6 @@ private: int64_t mAnchorTimeUs; int64_t mNumFramesOutput; int32_t mNumFramesLeftOnPage; - bool mSawInputEos; - bool mSignalledOutputEos; enum { NONE, |