From 9af5aee9d770e45ba3afa22fbd3fd0ee396362d8 Mon Sep 17 00:00:00 2001 From: Chih-Yu Huang Date: Wed, 31 Mar 2021 15:26:03 +0900 Subject: V4L2DecodeComponent: abandon pending work when drain is done. Originally we forced the component into error state if there are any pending frames when drain is done. That means these frames are either no-show frames or dropped. It doesn't affect the following decoding. This CL changes to abandon pending frames instead of reporting error. Bug: 184211876 Test: android.media.cts.AdaptivePlaybackTest Change-Id: I18511f14f70579718f434f316701ee1b77c1f6f0 --- components/V4L2DecodeComponent.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'components/V4L2DecodeComponent.cpp') diff --git a/components/V4L2DecodeComponent.cpp b/components/V4L2DecodeComponent.cpp index d37d7de..400c765 100644 --- a/components/V4L2DecodeComponent.cpp +++ b/components/V4L2DecodeComponent.cpp @@ -641,25 +641,33 @@ bool V4L2DecodeComponent::reportEOSWork() { ALOGV("%s()", __func__); ALOG_ASSERT(mDecoderTaskRunner->RunsTasksInCurrentSequence()); - // In this moment all works prior to EOS work should be done and returned to listener. - if (mWorksAtDecoder.size() != 1u) { - ALOGE("It shouldn't have remaining works in mWorksAtDecoder except EOS work."); - for (const auto& kv : mWorksAtDecoder) { - ALOGE("bitstreamId(%d) => Work index=%llu, timestamp=%llu", kv.first, - kv.second->input.ordinal.frameIndex.peekull(), - kv.second->input.ordinal.timestamp.peekull()); - } + const auto it = + std::find_if(mWorksAtDecoder.begin(), mWorksAtDecoder.end(), [](const auto& kv) { + return kv.second->input.flags & C2FrameData::FLAG_END_OF_STREAM; + }); + if (it == mWorksAtDecoder.end()) { + ALOGE("Failed to find EOS work."); return false; } - std::unique_ptr eosWork(std::move(mWorksAtDecoder.begin()->second)); - mWorksAtDecoder.clear(); + std::unique_ptr eosWork(std::move(it->second)); + mWorksAtDecoder.erase(it); eosWork->result = C2_OK; eosWork->workletsProcessed = static_cast(eosWork->worklets.size()); eosWork->worklets.front()->output.flags = C2FrameData::FLAG_END_OF_STREAM; if (!eosWork->input.buffers.empty()) eosWork->input.buffers.front().reset(); + if (!mWorksAtDecoder.empty()) { + ALOGW("There are remaining works except EOS work. abandon them."); + for (const auto& kv : mWorksAtDecoder) { + ALOGW("bitstreamId(%d) => Work index=%llu, timestamp=%llu", kv.first, + kv.second->input.ordinal.frameIndex.peekull(), + kv.second->input.ordinal.timestamp.peekull()); + } + reportAbandonedWorks(); + } + return reportWork(std::move(eosWork)); } -- cgit v1.2.3