diff options
| -rw-r--r-- | include/media/stagefright/MediaCodec.h | 9 | ||||
| -rw-r--r-- | media/libstagefright/MediaCodec.cpp | 43 | 
2 files changed, 52 insertions, 0 deletions
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index a0ff997..3f7508b 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<AMessage> mInputFormat;      sp<AMessage> 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 24fd7ad..7a9cb0b 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  | 
