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

Commit 92df7e4f authored by Wonsik Kim's avatar Wonsik Kim
Browse files

CCodecBufferChannel: stash flushed input buffers from PipelineWatcher

Currently converter code reconstructs a buffer object when it comes
through HAL interface. Using this buffer in flushed work could
confuse lifecycle management of the buffers, so retrieve the input
buffers from the PipelineWatcher which stores the original input
buffer references.

Bug: 196014695
Test: cts/media/device-small
Change-Id: I06128438d0de52e139e939afe7e59b166f404c1a
parent 6100fd64
Loading
Loading
Loading
Loading
+45 −37
Original line number Original line Diff line number Diff line
@@ -1467,6 +1467,16 @@ status_t CCodecBufferChannel::requestInitialInputBuffers() {
    std::list<std::unique_ptr<C2Work>> flushedConfigs;
    std::list<std::unique_ptr<C2Work>> flushedConfigs;
    mFlushedConfigs.lock()->swap(flushedConfigs);
    mFlushedConfigs.lock()->swap(flushedConfigs);
    if (!flushedConfigs.empty()) {
    if (!flushedConfigs.empty()) {
        {
            Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
            PipelineWatcher::Clock::time_point now = PipelineWatcher::Clock::now();
            for (const std::unique_ptr<C2Work> &work : flushedConfigs) {
                watcher->onWorkQueued(
                        work->input.ordinal.frameIndex.peeku(),
                        std::vector(work->input.buffers),
                        now);
            }
        }
        err = mComponent->queue(&flushedConfigs);
        err = mComponent->queue(&flushedConfigs);
        if (err != C2_OK) {
        if (err != C2_OK) {
            ALOGW("[%s] Error while queueing a flushed config", mName);
            ALOGW("[%s] Error while queueing a flushed config", mName);
@@ -1533,31 +1543,33 @@ void CCodecBufferChannel::release() {
    setDescrambler(nullptr);
    setDescrambler(nullptr);
}
}



void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
    ALOGV("[%s] flush", mName);
    ALOGV("[%s] flush", mName);
    std::vector<uint64_t> indices;
    std::list<std::unique_ptr<C2Work>> configs;
    std::list<std::unique_ptr<C2Work>> configs;
    mInput.lock()->lastFlushIndex = mFrameIndex.load(std::memory_order_relaxed);
    mInput.lock()->lastFlushIndex = mFrameIndex.load(std::memory_order_relaxed);
    {
        Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
        for (const std::unique_ptr<C2Work> &work : flushedWork) {
        for (const std::unique_ptr<C2Work> &work : flushedWork) {
        indices.push_back(work->input.ordinal.frameIndex.peeku());
            uint64_t frameIndex = work->input.ordinal.frameIndex.peeku();
            if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
            if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
                watcher->onWorkDone(frameIndex);
                continue;
                continue;
            }
            }
            if (work->input.buffers.empty()
            if (work->input.buffers.empty()
                    || work->input.buffers.front() == nullptr
                    || work->input.buffers.front() == nullptr
                    || work->input.buffers.front()->data().linearBlocks().empty()) {
                    || work->input.buffers.front()->data().linearBlocks().empty()) {
                ALOGD("[%s] no linear codec config data found", mName);
                ALOGD("[%s] no linear codec config data found", mName);
                watcher->onWorkDone(frameIndex);
                continue;
                continue;
            }
            }
            std::unique_ptr<C2Work> copy(new C2Work);
            std::unique_ptr<C2Work> copy(new C2Work);
        copy->input.flags = C2FrameData::flags_t(work->input.flags | C2FrameData::FLAG_DROP_FRAME);
            copy->input.flags = C2FrameData::flags_t(
                    work->input.flags | C2FrameData::FLAG_DROP_FRAME);
            copy->input.ordinal = work->input.ordinal;
            copy->input.ordinal = work->input.ordinal;
            copy->input.ordinal.frameIndex = mFrameIndex++;
            copy->input.ordinal.frameIndex = mFrameIndex++;
        copy->input.buffers.insert(
            for (size_t i = 0; i < work->input.buffers.size(); ++i) {
                copy->input.buffers.begin(),
                copy->input.buffers.push_back(watcher->onInputBufferReleased(frameIndex, i));
                work->input.buffers.begin(),
            }
                work->input.buffers.end());
            for (const std::unique_ptr<C2Param> &param : work->input.configUpdate) {
            for (const std::unique_ptr<C2Param> &param : work->input.configUpdate) {
                copy->input.configUpdate.push_back(C2Param::Copy(*param));
                copy->input.configUpdate.push_back(C2Param::Copy(*param));
            }
            }
@@ -1567,8 +1579,10 @@ void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushe
                    work->input.infoBuffers.end());
                    work->input.infoBuffers.end());
            copy->worklets.emplace_back(new C2Worklet);
            copy->worklets.emplace_back(new C2Worklet);
            configs.push_back(std::move(copy));
            configs.push_back(std::move(copy));
            watcher->onWorkDone(frameIndex);
            ALOGV("[%s] stashed flushed codec config data", mName);
            ALOGV("[%s] stashed flushed codec config data", mName);
        }
        }
    }
    mFlushedConfigs.lock()->swap(configs);
    mFlushedConfigs.lock()->swap(configs);
    {
    {
        Mutexed<Input>::Locked input(mInput);
        Mutexed<Input>::Locked input(mInput);
@@ -1582,12 +1596,6 @@ void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushe
            output->buffers->flushStash();
            output->buffers->flushStash();
        }
        }
    }
    }
    {
        Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
        for (uint64_t index : indices) {
            watcher->onWorkDone(index);
        }
    }
}
}


void CCodecBufferChannel::onWorkDone(
void CCodecBufferChannel::onWorkDone(