OSDN Git Service

Fixed a native crash due to unexpected state at destroy time when encoder component...
authorJames Dong <jdong@google.com>
Fri, 24 Aug 2012 17:53:31 +0000 (10:53 -0700)
committerJames Dong <jdong@google.com>
Fri, 24 Aug 2012 20:10:16 +0000 (13:10 -0700)
o Encoder component initializes to be in the state of EXECUTING before its source gets started, because we wanted to be able
  to configure the source to use the advertised number of input buffers. However, if the source fails to start, then the encoder
  ends up in the state of EXECUTING when OMXCodec object gets destroyed. As a result, the assertion on the expected state in
  OMXCodec's constructor fails. The fix is to stop the video encoder component right way when its source fails to start so to
  bring the state of the encoder component back to the expected state.

o related-to-bug: 7045494

Change-Id: I6d4a221eb809d7137f53e58098a04816998f7a25

include/media/stagefright/OMXCodec.h
media/libstagefright/OMXCodec.cpp

index bb9e595..e6739ae 100644 (file)
@@ -354,6 +354,8 @@ private:
             const void *data, size_t size,
             unsigned *profile, unsigned *level);
 
+    status_t stopOmxComponent_l();
+
     OMXCodec(const OMXCodec &);
     OMXCodec &operator=(const OMXCodec &);
 };
index 5615d0f..d0e306c 100755 (executable)
@@ -3621,7 +3621,11 @@ status_t OMXCodec::start(MetaData *meta) {
         }
 
         params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size());
-        return mSource->start(params.get());
+        err = mSource->start(params.get());
+        if (err != OK) {
+            stopOmxComponent_l();
+        }
+        return err;
     }
 
     // Decoder case
@@ -3633,8 +3637,16 @@ status_t OMXCodec::start(MetaData *meta) {
 
 status_t OMXCodec::stop() {
     CODEC_LOGV("stop mState=%d", mState);
-
     Mutex::Autolock autoLock(mLock);
+    status_t err = stopOmxComponent_l();
+    mSource->stop();
+
+    CODEC_LOGV("stopped in state %d", mState);
+    return err;
+}
+
+status_t OMXCodec::stopOmxComponent_l() {
+    CODEC_LOGV("stopOmxComponent_l mState=%d", mState);
 
     while (isIntermediateState(mState)) {
         mAsyncCompletion.wait(mLock);
@@ -3732,10 +3744,6 @@ status_t OMXCodec::stop() {
         mLeftOverBuffer = NULL;
     }
 
-    mSource->stop();
-
-    CODEC_LOGV("stopped in state %d", mState);
-
     return OK;
 }