Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 671160ff authored by Lajos Molnar's avatar Lajos Molnar
Browse files

stagefright: add MediaCodec.reset()

Bug: 12034929
Change-Id: I326f1356df89474aa088c1c87f8505b33654139d
parent efebe397
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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
+43 −0
Original line number Diff line number Diff line
@@ -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