Force shutdown of the omx decoder even if it's in a wedged state...

Change-Id: I5899928a3df4bcf7715769992955a0b834db1e2f
related-to-bug: 6571060
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 66111dc..7fb395e 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2475,7 +2475,12 @@
                 } else {
                     err = allocateBuffersOnPort(portIndex);
                     if (err != OK) {
-                        CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err);
+                        CODEC_LOGE("allocateBuffersOnPort (%s) failed "
+                                   "(err = %d)",
+                                   portIndex == kPortIndexInput
+                                        ? "input" : "output",
+                                   err);
+
                         setState(ERROR);
                     }
                 }
@@ -3658,14 +3663,33 @@
 
         case ERROR:
         {
-            OMX_STATETYPE state = OMX_StateInvalid;
-            status_t err = mOMX->getState(mNode, &state);
-            CHECK_EQ(err, (status_t)OK);
-
-            if (state != OMX_StateExecuting) {
+            if (mPortStatus[kPortIndexOutput] == ENABLING) {
+                // Codec is in a wedged state (technical term)
+                // We've seen an output port settings change from the codec,
+                // We've disabled the output port, then freed the output
+                // buffers, initiated re-enabling the output port but
+                // failed to reallocate the output buffers.
+                // There doesn't seem to be a way to orderly transition
+                // from executing->idle and idle->loaded now that the
+                // output port hasn't been reenabled yet...
+                // Simply free as many resources as we can and pretend
+                // that we're in LOADED state so that the destructor
+                // will free the component instance without asserting.
+                freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */);
+                freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */);
+                setState(LOADED);
                 break;
+            } else {
+                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
             }
-            // else fall through to the idling code
+
             isError = true;
         }