OSDN Git Service

stagefright: try to free codec instance if MediaCodec.release hangs
authorLajos Molnar <lajos@google.com>
Tue, 21 Oct 2014 23:07:52 +0000 (16:07 -0700)
committerLajos Molnar <lajos@google.com>
Tue, 21 Oct 2014 23:14:11 +0000 (16:14 -0700)
Bug: 18033275
Change-Id: If86cd26566d7b75941976f37829bbec619800778

include/media/stagefright/ACodec.h
media/libstagefright/ACodec.cpp
media/libstagefright/omx/OMXNodeInstance.cpp

index d77ddaf..fcccc6d 100644 (file)
@@ -120,6 +120,7 @@ private:
         kWhatSetParameters           = 'setP',
         kWhatSubmitOutputMetaDataBufferIfEOS = 'subm',
         kWhatOMXDied                 = 'OMXd',
+        kWhatReleaseCodecInstance    = 'relC',
     };
 
     enum {
index 2048808..2f2f9cf 100644 (file)
@@ -498,6 +498,10 @@ void ACodec::initiateShutdown(bool keepComponentAllocated) {
     sp<AMessage> msg = new AMessage(kWhatShutdown, id());
     msg->setInt32("keepComponentAllocated", keepComponentAllocated);
     msg->post();
+    if (!keepComponentAllocated) {
+        // ensure shutdown completes in 3 seconds
+        (new AMessage(kWhatReleaseCodecInstance, id()))->post(3000000);
+    }
 }
 
 void ACodec::signalRequestIDRFrame() {
@@ -3797,6 +3801,19 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
             break;
         }
 
+        case ACodec::kWhatReleaseCodecInstance:
+        {
+            ALOGI("[%s] forcing the release of codec",
+                    mCodec->mComponentName.c_str());
+            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
+            ALOGE_IF("[%s] failed to release codec instance: err=%d",
+                       mCodec->mComponentName.c_str(), err);
+            sp<AMessage> notify = mCodec->mNotify->dup();
+            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
+            notify->post();
+            break;
+        }
+
         default:
             return false;
     }
@@ -4456,6 +4473,13 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
             break;
         }
 
+        case ACodec::kWhatReleaseCodecInstance:
+        {
+            // nothing to do, as we have already signaled shutdown
+            handled = true;
+            break;
+        }
+
         default:
             return BaseState::onMessageReceived(msg);
     }
index d07ec14..f9c84e2 100644 (file)
@@ -149,6 +149,11 @@ static status_t StatusFromOMXError(OMX_ERRORTYPE err) {
 status_t OMXNodeInstance::freeNode(OMXMaster *master) {
     static int32_t kMaxNumIterations = 10;
 
+    // exit if we have already freed the node
+    if (mHandle == NULL) {
+        return OK;
+    }
+
     // Transition the node from its current state all the way down
     // to "Loaded".
     // This ensures that all active buffers are properly freed even