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

Commit 604bb9ea authored by Lajos Molnar's avatar Lajos Molnar
Browse files

stagefright: handle removal of a tracked buffer in ACodec

Bug: 21815057
Change-Id: Idd1c71b4b0b68028020c3e10615936870ffd2dec
parent 9a922554
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -119,8 +119,9 @@ struct FrameRenderTracker : public RefBase {
    std::list<Info> checkFencesAndGetRenderedFrames(const Info *until, bool dropIncomplete);
    std::list<Info> checkFencesAndGetRenderedFrames(const Info *until, bool dropIncomplete);


    // Stop tracking a queued frame (e.g. if the frame has been discarded). If |info| is NULL or is
    // Stop tracking a queued frame (e.g. if the frame has been discarded). If |info| is NULL or is
    // not tracked, this method is a no-op.
    // not tracked, this method is a no-op. If |index| is specified, all indices larger that |index|
    void untrackFrame(const Info *info);
    // are decremented. This is useful if the untracked frame is deleted from the frame vector.
    void untrackFrame(const Info *info, ssize_t index = SSIZE_MAX);


    void dumpRenderQueue() const;
    void dumpRenderQueue() const;


+10 −5
Original line number Original line Diff line number Diff line
@@ -1271,8 +1271,12 @@ void ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Inf
    // unlink untracked frames
    // unlink untracked frames
    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
            it != done.cend(); ++it) {
            it != done.cend(); ++it) {
        if (it->getIndex() >= 0) {
        ssize_t index = it->getIndex();
            mBuffers[kPortIndexOutput].editItemAt(it->getIndex()).mRenderInfo = NULL;
        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
        } else if (index >= 0) {
            // THIS SHOULD NEVER HAPPEN
            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
        }
        }
    }
    }


@@ -1467,12 +1471,13 @@ status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
        ::close(info->mFenceFd);
        ::close(info->mFenceFd);
    }
    }


    mRenderTracker.untrackFrame(info->mRenderInfo);
    if (portIndex == kPortIndexOutput) {
        mRenderTracker.untrackFrame(info->mRenderInfo, i);
        info->mRenderInfo = NULL;
        info->mRenderInfo = NULL;
    }


    // remove buffer even if mOMX->freeBuffer fails
    // remove buffer even if mOMX->freeBuffer fails
    mBuffers[portIndex].removeAt(i);
    mBuffers[portIndex].removeAt(i);

    return err;
    return err;
}
}


+14 −7
Original line number Original line Diff line number Diff line
@@ -149,14 +149,21 @@ std::list<FrameRenderTracker::Info> FrameRenderTracker::checkFencesAndGetRendere
    return done;
    return done;
}
}


void FrameRenderTracker::untrackFrame(const FrameRenderTracker::Info *info) {
void FrameRenderTracker::untrackFrame(const FrameRenderTracker::Info *info, ssize_t index) {
    if (info != NULL) {
    if (info == NULL && index == SSIZE_MAX) {
        // nothing to do
        return;
    }

    for (std::list<Info>::iterator it = mRenderQueue.begin();
    for (std::list<Info>::iterator it = mRenderQueue.begin();
                it != mRenderQueue.end(); ++it) {
            it != mRenderQueue.end(); ) {
        if (&*it == info) {
        if (&*it == info) {
                mRenderQueue.erase(it);
            mRenderQueue.erase(it++);
                return;
        } else {
            if (it->mIndex > index) {
                --(it->mIndex);
            }
            }
            ++it;
        }
        }
    }
    }
}
}