Merge "Fix MediaCodec.flush()" into jb-mr2-dev
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 6490608..ee49033 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3659,7 +3659,6 @@
                      (status_t)OK);
 
             mCodec->changeState(mCodec->mFlushingState);
-
             handled = true;
             break;
         }
@@ -4174,6 +4173,10 @@
 
         mCodec->mInputEOSResult = OK;
 
+        if (mCodec->mSkipCutBuffer != NULL) {
+            mCodec->mSkipCutBuffer->clear();
+        }
+
         mCodec->changeState(mCodec->mExecutingState);
     }
 }
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 = 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 @@
             notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
             return;
         }
+
         inQueue.erase(inQueue.begin());
         info->mOwnedByUs = false;
         notifyEmptyBufferDone(header);
@@ -358,7 +359,7 @@
             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 @@
                                            outBuffer,
                                            outHeader->nAllocLen,
                                            AACDEC_FLUSH);
+                mDecoderHasData = false;
 
                 if (decoderErr != AAC_DEC_OK) {
                     mSignalledError = true;
@@ -385,9 +387,7 @@
                             * 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 @@
                             inBuffer,
                             inBufferLength,
                             bytesValid);
+            mDecoderHasData = true;
 
             decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
                                                 outBuffer,
@@ -484,45 +485,6 @@
             }
         }
 
-        /*
-         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
-         * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
-         * rate system and the sampling rate in the final output is actually
-         * doubled compared with the core AAC decoder sampling rate.
-         *
-         * Explicit signalling is done by explicitly defining SBR audio object
-         * type in the bitstream. Implicit signalling is done by embedding
-         * SBR content in AAC extension payload specific to SBR, and hence
-         * requires an AAC decoder to perform pre-checks on actual audio frames.
-         *
-         * Thus, we could not say for sure whether a stream is
-         * AAC+/eAAC+ until the first data frame is decoded.
-         */
-        if (mInputBufferCount <= 2) {
-            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;
-
-                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
-                mOutputPortSettingsChange = AWAITING_DISABLED;
-                return;
-            }
-        } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
-            ALOGW("Invalid AAC stream");
-            mSignalledError = true;
-            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
-            return;
-        }
-
         size_t numOutBytes =
             mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
 
@@ -544,17 +506,51 @@
             // 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
+         * rate system and the sampling rate in the final output is actually
+         * doubled compared with the core AAC decoder sampling rate.
+         *
+         * Explicit signalling is done by explicitly defining SBR audio object
+         * type in the bitstream. Implicit signalling is done by embedding
+         * SBR content in AAC extension payload specific to SBR, and hence
+         * requires an AAC decoder to perform pre-checks on actual audio frames.
+         *
+         * Thus, we could not say for sure whether a stream is
+         * AAC+/eAAC+ until the first data frame is decoded.
+         */
+        if (mInputBufferCount <= 2) {
+            if (mStreamInfo->sampleRate != prevSampleRate ||
+                mStreamInfo->numChannels != prevNumChannels) {
+                maybeConfigureDownmix();
+                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
+                      prevSampleRate, mStreamInfo->sampleRate,
+                      prevNumChannels, mStreamInfo->numChannels);
+
+                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+                mOutputPortSettingsChange = AWAITING_DISABLED;
+                return;
+            }
+        } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
+            ALOGW("Invalid AAC stream");
+            mSignalledError = true;
+            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+            return;
+        }
+
         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 @@
             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 @@
     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) {
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 6957ade..2d960ab 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -52,7 +52,7 @@
     HANDLE_AACDECODER mAACDecoder;
     CStreamInfo *mStreamInfo;
     bool mIsADTS;
-    bool mIsFirst;
+    bool mDecoderHasData;
     size_t mInputBufferCount;
     bool mSignalledError;
     int64_t mAnchorTimeUs;
@@ -68,6 +68,7 @@
     status_t initDecoder();
     bool isConfigured() const;
     void maybeConfigureDownmix() const;
+    void drainDecoder();
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftAAC2);
 };