diff options
author | Chih-Yu Huang <akahuang@google.com> | 2020-09-17 04:04:19 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-09-17 04:04:19 +0000 |
commit | c9623695df1080e25bbe506d1a39346f048dddf9 (patch) | |
tree | f089358122872072a2db56fd57927282a10377ae | |
parent | d68c5a8c64d22a5f6e2a12b748358f996f37e1b4 (diff) | |
parent | 5424e3b0d27e01c1a2f5bfaaa9e5b4219ffee1ac (diff) | |
download | v4l2_codec2-c9623695df1080e25bbe506d1a39346f048dddf9.tar.gz |
V4L2Decoder: Recycle the empty buffer back to V4L2 output queue am: de44698180 am: 5424e3b0d2
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/v4l2_codec2/+/12559028
Change-Id: I0038cf87a89c506063efb20ee48149d7ca887d34
-rw-r--r-- | components/V4L2Decoder.cpp | 53 | ||||
-rw-r--r-- | components/include/v4l2_codec2/components/V4L2Decoder.h | 1 |
2 files changed, 31 insertions, 23 deletions
diff --git a/components/V4L2Decoder.cpp b/components/V4L2Decoder.cpp index 0df4e50..b9b4f6c 100644 --- a/components/V4L2Decoder.cpp +++ b/components/V4L2Decoder.cpp @@ -387,15 +387,39 @@ void V4L2Decoder::serviceDeviceTask(bool event) { outputDequeued = true; + const size_t bufferId = dequeuedBuffer->BufferId(); + const int32_t bitstreamId = static_cast<int32_t>(dequeuedBuffer->GetTimeStamp().tv_sec); + const size_t bytesUsed = dequeuedBuffer->GetPlaneBytesUsed(0); + const bool isLast = dequeuedBuffer->IsLast(); ALOGV("DQBUF from output queue, bufferId=%zu, corresponding bitstreamId=%d, bytesused=%zu", - dequeuedBuffer->BufferId(), - static_cast<int32_t>(dequeuedBuffer->GetTimeStamp().tv_sec), - dequeuedBuffer->GetPlaneBytesUsed(0)); - if (dequeuedBuffer->GetPlaneBytesUsed(0) > 0) { - sendOutputBuffer(dequeuedBuffer); + bufferId, bitstreamId, bytesUsed); + + // Get the corresponding VideoFrame of the dequeued buffer. + auto it = mFrameAtDevice.find(bufferId); + ALOG_ASSERT(it != mFrameAtDevice.end(), "buffer %zu is not found at mFrameAtDevice", + bufferId); + auto frame = std::move(it->second); + mFrameAtDevice.erase(it); + + if (bytesUsed > 0) { + ALOGV("Send output frame(bitstreamId=%d) to client", bitstreamId); + frame->setBitstreamId(bitstreamId); + frame->setVisibleRect(mVisibleRect); + mOutputCb.Run(std::move(frame)); + } else { + // Workaround(b/168750131): If the buffer is not enqueued before the next drain is done, + // then the driver will fail to notify EOS. So we recycle the buffer immediately. + ALOGV("Recycle empty buffer %zu back to V4L2 output queue.", bufferId); + dequeuedBuffer.reset(); + auto outputBuffer = mOutputQueue->GetFreeBuffer(bufferId); + ALOG_ASSERT(outputBuffer, "V4L2 output queue slot %zu is not freed.", bufferId); + + std::move(*outputBuffer).QueueDMABuf(frame->getFDs()); + mFrameAtDevice.insert(std::make_pair(bufferId, std::move(frame))); } - if (mDrainCb && dequeuedBuffer->IsLast()) { - ALOGD("All buffers are drained."); + + if (mDrainCb && isLast) { + ALOGV("All buffers are drained."); sendV4L2DecoderCmd(true); std::move(mDrainCb).Run(VideoDecoder::DecodeStatus::kOk); setState(State::Idle); @@ -422,21 +446,6 @@ void V4L2Decoder::serviceDeviceTask(bool event) { } } -void V4L2Decoder::sendOutputBuffer(media::V4L2ReadableBufferRef buffer) { - ALOGV("%s(bufferId=%zu)", __func__, buffer->BufferId()); - ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence()); - - size_t bufferId = buffer->BufferId(); - auto it = mFrameAtDevice.find(bufferId); - ALOG_ASSERT(it != mFrameAtDevice.end(), "buffer %zu is not found at mFrameAtDevice", bufferId); - auto block = std::move(it->second); - mFrameAtDevice.erase(it); - - block->setBitstreamId(buffer->GetTimeStamp().tv_sec); - block->setVisibleRect(mVisibleRect); - mOutputCb.Run(std::move(block)); -} - bool V4L2Decoder::dequeueResolutionChangeEvent() { ALOGV("%s()", __func__); ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence()); diff --git a/components/include/v4l2_codec2/components/V4L2Decoder.h b/components/include/v4l2_codec2/components/V4L2Decoder.h index 5539042..bdddc7f 100644 --- a/components/include/v4l2_codec2/components/V4L2Decoder.h +++ b/components/include/v4l2_codec2/components/V4L2Decoder.h @@ -62,7 +62,6 @@ private: void pumpDecodeRequest(); void serviceDeviceTask(bool event); - void sendOutputBuffer(media::V4L2ReadableBufferRef buffer); bool dequeueResolutionChangeEvent(); bool changeResolution(); |