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

Commit 8bae3aa3 authored by Ronghua Wu's avatar Ronghua Wu Committed by Android (Google) Code Review
Browse files

Merge "libstagefright: report special error when codec is released by resource...

Merge "libstagefright: report special error when codec is released by resource manager." into mnc-dev
parents 3af8a321 47a2e875
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -163,6 +163,11 @@ protected:
    virtual ~MediaCodec();
    virtual void onMessageReceived(const sp<AMessage> &msg);

private:
    // used by ResourceManagerClient
    status_t reclaim();
    friend struct ResourceManagerClient;

private:
    enum State {
        UNINITIALIZED,
@@ -262,6 +267,7 @@ private:
    };

    State mState;
    bool mReleasedByResourceManager;
    sp<ALooper> mLooper;
    sp<ALooper> mCodecLooper;
    sp<CodecBase> mCodec;
@@ -321,7 +327,7 @@ private:
    static status_t PostAndAwaitResponse(
            const sp<AMessage> &msg, sp<AMessage> *response);

    static void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);
    void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);

    status_t init(const AString &name, bool nameIsType, bool encoder);

+44 −12
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ static int64_t getId(sp<IResourceManagerClient> client) {
}

static bool isResourceError(status_t err) {
    return (err == OMX_ErrorInsufficientResources);
    return (err == NO_MEMORY);
}

static const int kMaxRetry = 2;
@@ -76,7 +76,7 @@ struct ResourceManagerClient : public BnResourceManagerClient {
            // codec is already gone.
            return true;
        }
        status_t err = codec->release();
        status_t err = codec->reclaim();
        if (err != OK) {
            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
        }
@@ -336,6 +336,7 @@ sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {

MediaCodec::MediaCodec(const sp<ALooper> &looper)
    : mState(UNINITIALIZED),
      mReleasedByResourceManager(false),
      mLooper(looper),
      mCodec(NULL),
      mReplyID(0),
@@ -377,10 +378,15 @@ status_t MediaCodec::PostAndAwaitResponse(
    return err;
}

// static
void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
    int32_t finalErr = err;
    if (mReleasedByResourceManager) {
        // override the err code if MediaCodec has been released by ResourceManager.
        finalErr = DEAD_OBJECT;
    }

    sp<AMessage> response = new AMessage;
    response->setInt32("err", err);
    response->setInt32("err", finalErr);
    response->postReply(replyID);
}

@@ -654,6 +660,14 @@ status_t MediaCodec::stop() {
    return PostAndAwaitResponse(msg, &response);
}

status_t MediaCodec::reclaim() {
    sp<AMessage> msg = new AMessage(kWhatRelease, this);
    msg->setInt32("reclaimed", 1);

    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

status_t MediaCodec::release() {
    sp<AMessage> msg = new AMessage(kWhatRelease, this);

@@ -920,6 +934,10 @@ status_t MediaCodec::getBufferAndFormat(
        sp<ABuffer> *buffer, sp<AMessage> *format) {
    // use mutex instead of a context switch

    if (mReleasedByResourceManager) {
        return DEAD_OBJECT;
    }

    buffer->clear();
    format->clear();
    if (!isExecuting()) {
@@ -1009,20 +1027,19 @@ bool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool n
}

bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
    sp<AMessage> response = new AMessage;

    if (!isExecuting() || (mFlags & kFlagIsAsync)
            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
        response->setInt32("err", INVALID_OPERATION);
        PostReplyWithError(replyID, INVALID_OPERATION);
    } else if (mFlags & kFlagStickyError) {
        response->setInt32("err", getStickyError());
        PostReplyWithError(replyID, getStickyError());
    } else if (mFlags & kFlagOutputBuffersChanged) {
        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
        PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
        mFlags &= ~kFlagOutputBuffersChanged;
    } else if (mFlags & kFlagOutputFormatChanged) {
        response->setInt32("err", INFO_FORMAT_CHANGED);
        PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
        mFlags &= ~kFlagOutputFormatChanged;
    } else {
        sp<AMessage> response = new AMessage;
        ssize_t index = dequeuePortBuffer(kPortIndexOutput);

        if (index < 0) {
@@ -1057,9 +1074,8 @@ bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool
        }

        response->setInt32("flags", flags);
    }

        response->postReply(replyID);
    }

    return true;
}
@@ -1818,6 +1834,20 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            sp<AReplyToken> replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            // already stopped/released
            if (mState == UNINITIALIZED && mReleasedByResourceManager) {
                sp<AMessage> response = new AMessage;
                response->setInt32("err", OK);
                response->postReply(replyID);
                break;
            }

            int32_t reclaimed = 0;
            msg->findInt32("reclaimed", &reclaimed);
            if (reclaimed) {
                mReleasedByResourceManager = true;
            }

            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
                    && mState != INITIALIZED
                    && mState != CONFIGURED && !isExecuting()) {
@@ -1831,6 +1861,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                // and it should be in this case, no harm to allow a release()
                // if we're already uninitialized.
                sp<AMessage> response = new AMessage;
                // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
                // the previous stop/release completes and then reply with OK.
                status_t err = mState == targetState ? OK : INVALID_OPERATION;
                response->setInt32("err", err);
                if (err == OK && targetState == UNINITIALIZED) {