Merge "TimedEventQueue: improve wakelock management" into klp-dev
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index f295e5a..a7c5317 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -148,6 +148,18 @@
     }
 }
 
+void GraphicBufferSource::omxIdle() {
+    ALOGV("omxIdle");
+
+    Mutex::Autolock autoLock(mMutex);
+
+    if (mExecuting) {
+        // We are only interested in the transition from executing->idle,
+        // not loaded->idle.
+        mEndOfStream = mEndOfStreamSent = true;
+    }
+}
+
 void GraphicBufferSource::omxLoaded(){
     Mutex::Autolock autoLock(mMutex);
     if (!mExecuting) {
@@ -213,7 +225,12 @@
     // see if the GraphicBuffer reference was null, which should only ever
     // happen for EOS.
     if (codecBuffer.mGraphicBuffer == NULL) {
-        CHECK(mEndOfStream && mEndOfStreamSent);
+        if (!(mEndOfStream && mEndOfStreamSent)) {
+            // This can happen when broken code sends us the same buffer
+            // twice in a row.
+            ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer "
+                    "(buffer emptied twice?)");
+        }
         // No GraphicBuffer to deal with, no additional input or output is
         // expected, so just return.
         return;
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 244a843..9e5eee6 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -69,6 +69,11 @@
     // sitting in the BufferQueue, this will send them to the codec.
     void omxExecuting();
 
+    // This is called when OMX transitions to OMX_StateIdle, indicating that
+    // the codec is meant to return all buffers back to the client for them
+    // to be freed. Do NOT submit any more buffers to the component.
+    void omxIdle();
+
     // This is called when OMX transitions to OMX_StateLoaded, indicating that
     // we are shutting down.
     void omxLoaded();
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 46e5d71..5f104fc 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -243,13 +243,18 @@
 status_t OMXNodeInstance::sendCommand(
         OMX_COMMANDTYPE cmd, OMX_S32 param) {
     const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
-    if (bufferSource != NULL
-            && cmd == OMX_CommandStateSet
-            && param == OMX_StateLoaded) {
-        // Initiating transition from Executing -> Loaded
-        // Buffers are about to be freed.
-        bufferSource->omxLoaded();
-        setGraphicBufferSource(NULL);
+    if (bufferSource != NULL && cmd == OMX_CommandStateSet) {
+        if (param == OMX_StateIdle) {
+            // Initiating transition from Executing -> Idle
+            // ACodec is waiting for all buffers to be returned, do NOT
+            // submit any more buffers to the codec.
+            bufferSource->omxIdle();
+        } else if (param == OMX_StateLoaded) {
+            // Initiating transition from Idle/Executing -> Loaded
+            // Buffers are about to be freed.
+            bufferSource->omxLoaded();
+            setGraphicBufferSource(NULL);
+        }
 
         // fall through
     }