summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
diff options
context:
space:
mode:
authorMarco Nelissen <marcone@google.com>2013-04-09 14:57:38 -0700
committerMarco Nelissen <marcone@google.com>2013-04-12 09:33:40 -0700
commitf3bd1972e039c6ded5154db715e5a32f1813a239 (patch)
tree7527b8e92891c725ae007eb87143281dac26ebf8 /media/libstagefright/codecs/aacdec/SoftAAC2.cpp
parentec77122351b4e78c1fe5b60a208f76baf8c67591 (diff)
downloadframeworks_av-f3bd1972e039c6ded5154db715e5a32f1813a239.zip
frameworks_av-f3bd1972e039c6ded5154db715e5a32f1813a239.tar.gz
frameworks_av-f3bd1972e039c6ded5154db715e5a32f1813a239.tar.bz2
Fix MediaCodec.flush()
There were two problems here. One was that the skip/cut buffer wasn't cleared when it should be, and the second was that we were always sending the first buffer of encoded data to the AAC decoder twice. b/8543366 Change-Id: Ic040edabf16cccd1f6ef8c9e5c9cfbacbdd8a089
Diffstat (limited to 'media/libstagefright/codecs/aacdec/SoftAAC2.cpp')
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC2.cpp103
1 files changed, 49 insertions, 54 deletions
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index a8ab2ac..8ba2afb 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -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) {