am 23d64420: Merge "Stagefright: idle OMX after ANW errors" into ics-mr0

* commit '23d644202a44383bf008ff86f6faa3ea7e447290':
  Stagefright: idle OMX after ANW errors
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 02ad703..c4cc947 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -78,6 +78,9 @@
             node_id node, OMX_INDEXTYPE index,
             const void *params, size_t size) = 0;
 
+    virtual status_t getState(
+            node_id node, OMX_STATETYPE* state) = 0;
+
     virtual status_t storeMetaDataInBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
 
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index d3aab08..7d2fbce 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -38,6 +38,7 @@
     SET_PARAMETER,
     GET_CONFIG,
     SET_CONFIG,
+    GET_STATE,
     ENABLE_GRAPHIC_BUFFERS,
     USE_BUFFER,
     USE_GRAPHIC_BUFFER,
@@ -198,6 +199,17 @@
         return reply.readInt32();
     }
 
+    virtual status_t getState(
+            node_id node, OMX_STATETYPE* state) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+        data.writeIntPtr((intptr_t)node);
+        remote()->transact(GET_STATE, data, &reply);
+
+        *state = static_cast<OMX_STATETYPE>(reply.readInt32());
+        return reply.readInt32();
+    }
+
     virtual status_t enableGraphicBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable) {
         Parcel data, reply;
@@ -524,6 +536,20 @@
             return NO_ERROR;
         }
 
+        case GET_STATE:
+        {
+            CHECK_INTERFACE(IOMX, data, reply);
+
+            node_id node = (void*)data.readIntPtr();
+            OMX_STATETYPE state = OMX_StateInvalid;
+
+            status_t err = getState(node, &state);
+            reply->writeInt32(state);
+            reply->writeInt32(err);
+
+            return NO_ERROR;
+        }
+
         case ENABLE_GRAPHIC_BUFFERS:
         {
             CHECK_INTERFACE(IOMX, data, reply);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index f9cb882..7e55790 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -3618,11 +3618,24 @@
         mAsyncCompletion.wait(mLock);
     }
 
+    bool isError = false;
     switch (mState) {
         case LOADED:
-        case ERROR:
             break;
 
+        case ERROR:
+        {
+            OMX_STATETYPE state = OMX_StateInvalid;
+            status_t err = mOMX->getState(mNode, &state);
+            CHECK_EQ(err, (status_t)OK);
+
+            if (state != OMX_StateExecuting) {
+                break;
+            }
+            // else fall through to the idling code
+            isError = true;
+        }
+
         case EXECUTING:
         {
             setState(EXECUTING_TO_IDLE);
@@ -3657,6 +3670,12 @@
                 mAsyncCompletion.wait(mLock);
             }
 
+            if (isError) {
+                // We were in the ERROR state coming in, so restore that now
+                // that we've idled the OMX component.
+                setState(ERROR);
+            }
+
             break;
         }
 
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index d54b1c1..53e764f 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -59,6 +59,9 @@
             node_id node, OMX_INDEXTYPE index,
             const void *params, size_t size);
 
+    virtual status_t getState(
+            node_id node, OMX_STATETYPE* state);
+
     virtual status_t enableGraphicBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable);
 
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 1ccf50d..47ca579 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -49,6 +49,8 @@
     status_t getConfig(OMX_INDEXTYPE index, void *params, size_t size);
     status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size);
 
+    status_t getState(OMX_STATETYPE* state);
+
     status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
 
     status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 33d3f30..3715fe9 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -303,6 +303,12 @@
             index, params, size);
 }
 
+status_t OMX::getState(
+        node_id node, OMX_STATETYPE* state) {
+    return findInstance(node)->getState(
+            state);
+}
+
 status_t OMX::enableGraphicBuffers(
         node_id node, OMX_U32 port_index, OMX_BOOL enable) {
     return findInstance(node)->enableGraphicBuffers(port_index, enable);
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index b612f89..0ff398a 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -266,6 +266,14 @@
     return StatusFromOMXError(err);
 }
 
+status_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
+    Mutex::Autolock autoLock(mLock);
+
+    OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
+
+    return StatusFromOMXError(err);
+}
+
 status_t OMXNodeInstance::enableGraphicBuffers(
         OMX_U32 portIndex, OMX_BOOL enable) {
     Mutex::Autolock autoLock(mLock);