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

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

Merge "libstagefright: don't reclaim codec when there's buffer owned by...

Merge "libstagefright: don't reclaim codec when there's buffer owned by client. Notify the client and try to reclaim again in 0.5s." into mnc-dr-dev
parents c4c68f63 4b710f08
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -176,7 +176,7 @@ protected:

private:
    // used by ResourceManagerClient
    status_t reclaim();
    status_t reclaim(bool force = false);
    friend struct ResourceManagerClient;

private:
@@ -385,6 +385,9 @@ private:
    uint64_t getGraphicBufferSize();
    void addResource(const String8 &type, const String8 &subtype, uint64_t value);

    bool hasPendingBuffer(int portIndex);
    bool hasPendingBuffer();

    /* called to get the last codec error when the sticky flag is set.
     * if no such codec error is found, returns UNKNOWN_ERROR.
     */
+41 −1
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ static bool isResourceError(status_t err) {
}

static const int kMaxRetry = 2;
static const int kMaxReclaimWaitTimeInUs = 500000;  // 0.5s

struct ResourceManagerClient : public BnResourceManagerClient {
    ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
@@ -74,6 +75,12 @@ struct ResourceManagerClient : public BnResourceManagerClient {
            return true;
        }
        status_t err = codec->reclaim();
        if (err == WOULD_BLOCK) {
            ALOGD("Wait for the client to release codec.");
            usleep(kMaxReclaimWaitTimeInUs);
            ALOGD("Try to reclaim again.");
            err = codec->reclaim(true /* force */);
        }
        if (err != OK) {
            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
        }
@@ -571,10 +578,26 @@ status_t MediaCodec::stop() {
    return PostAndAwaitResponse(msg, &response);
}

status_t MediaCodec::reclaim() {
bool MediaCodec::hasPendingBuffer(int portIndex) {
    const Vector<BufferInfo> &buffers = mPortBuffers[portIndex];
    for (size_t i = 0; i < buffers.size(); ++i) {
        const BufferInfo &info = buffers.itemAt(i);
        if (info.mOwnedByClient) {
            return true;
        }
    }
    return false;
}

bool MediaCodec::hasPendingBuffer() {
    return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput);
}

status_t MediaCodec::reclaim(bool force) {
    ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str());
    sp<AMessage> msg = new AMessage(kWhatRelease, this);
    msg->setInt32("reclaimed", 1);
    msg->setInt32("force", force ? 1 : 0);

    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
@@ -1787,6 +1810,23 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            msg->findInt32("reclaimed", &reclaimed);
            if (reclaimed) {
                mReleasedByResourceManager = true;

                int32_t force = 0;
                msg->findInt32("force", &force);
                if (!force && hasPendingBuffer()) {
                    ALOGW("Can't reclaim codec right now due to pending buffers.");

                    // return WOULD_BLOCK to ask resource manager to retry later.
                    sp<AMessage> response = new AMessage;
                    response->setInt32("err", WOULD_BLOCK);
                    response->postReply(replyID);

                    // notify the async client
                    if (mFlags & kFlagIsAsync) {
                        onError(DEAD_OBJECT, ACTION_CODE_FATAL);
                    }
                    break;
                }
            }

            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1