aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Yu Huang <akahuang@google.com>2020-09-17 04:04:19 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-09-17 04:04:19 +0000
commitc9623695df1080e25bbe506d1a39346f048dddf9 (patch)
treef089358122872072a2db56fd57927282a10377ae
parentd68c5a8c64d22a5f6e2a12b748358f996f37e1b4 (diff)
parent5424e3b0d27e01c1a2f5bfaaa9e5b4219ffee1ac (diff)
downloadv4l2_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.cpp53
-rw-r--r--components/include/v4l2_codec2/components/V4L2Decoder.h1
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();