From 671160ffe81592efa376dc1ff0fc3f4ddcdebc35 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Tue, 15 Jul 2014 07:56:04 -0700 Subject: [PATCH] stagefright: add MediaCodec.reset() Bug: 12034929 Change-Id: I326f1356df89474aa088c1c87f8505b33654139d --- include/media/stagefright/MediaCodec.h | 9 +++++++ media/libstagefright/MediaCodec.cpp | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index a0ff997d5c..3f7508b466 100644 --- a/include/media/stagefright/MediaCodec.h +++ b/include/media/stagefright/MediaCodec.h @@ -73,6 +73,10 @@ struct MediaCodec : public AHandler { // unconfigured. status_t stop(); + // Resets the codec to the INITIALIZED state. Can be called after an error + // has occured to make the codec usable. + status_t reset(); + // Client MUST call release before releasing final reference to this // object. status_t release(); @@ -221,6 +225,11 @@ private: sp mInputFormat; sp mCallback; + // initial create parameters + AString mInitName; + bool mInitNameIsType; + bool mInitIsEncoder; + // Used only to synchronize asynchronous getBufferAndFormat // across all the other (synchronous) buffer state change // operations, such as de/queueIn/OutputBuffer, start and diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 24fd7ad66e..7a9cb0b5a6 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -106,6 +106,11 @@ void MediaCodec::PostReplyWithError(int32_t replyID, int32_t err) { } status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) { + // save init parameters for reset + mInitName = name; + mInitNameIsType = nameIsType; + mInitIsEncoder = encoder; + // Current video decoders do not return from OMX_FillThisBuffer // quickly, violating the OpenMAX specs, until that is remedied // we need to invest in an extra looper to free the main event @@ -235,6 +240,40 @@ status_t MediaCodec::release() { return PostAndAwaitResponse(msg, &response); } +status_t MediaCodec::reset() { + /* When external-facing MediaCodec object is created, + it is already initialized. Thus, reset is essentially + release() followed by init(), plus clearing the state */ + + status_t err = release(); + + // unregister handlers + if (mCodec != NULL) { + if (mCodecLooper != NULL) { + mCodecLooper->unregisterHandler(mCodec->id()); + } else { + mLooper->unregisterHandler(mCodec->id()); + } + mCodec = NULL; + } + mLooper->unregisterHandler(id()); + + mFlags = 0; // clear all flags + + // reset state not reset by setState(UNINITIALIZED) + mReplyID = 0; + mDequeueInputReplyID = 0; + mDequeueOutputReplyID = 0; + mDequeueInputTimeoutGeneration = 0; + mDequeueOutputTimeoutGeneration = 0; + mHaveInputSurface = false; + + if (err == OK) { + err = init(mInitName.c_str(), mInitNameIsType, mInitIsEncoder); + } + return err; +} + status_t MediaCodec::queueInputBuffer( size_t index, size_t offset, @@ -1553,6 +1592,7 @@ void MediaCodec::setState(State newState) { mCrypto.clear(); setNativeWindow(NULL); + mInputFormat.clear(); mOutputFormat.clear(); mFlags &= ~kFlagOutputFormatChanged; mFlags &= ~kFlagOutputBuffersChanged; @@ -1566,6 +1606,9 @@ void MediaCodec::setState(State newState) { } if (newState == UNINITIALIZED) { + // return any straggling buffers, e.g. if we got here on an error + returnBuffersToCodec(); + mComponentName.clear(); // The component is gone, mediaserver's probably back up already -- 2.11.0