Commit 2ca56c59 authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Commit Bot

media/gpu/v4l2vd: use buffer affinity tracker

When using DMABUFs, it is preferable to use the same V4L2 buffer with
the same underlying buffer, as failure to do so results in memory
unmappings/remappings in the driver. Use the newly introduced buffer
affinity tracker and V4L2Queue::GetFreeBufferForFrame() method to
achieve this transparently in the video decoder.

Furthermore, it is a requirement of the V4L2 stateful decoder interface
that V4L2 buffers are always backed by the same underlying memory, lest
some reference frames lifetime tracking might be incorrect.

BUG=b:159688625
BUG=b:167412992
TEST=video.DecodeAccel.h264 passes on Trogdor.

Change-Id: I220a321d5584f50406480c105844a82dd96e63c6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2415909
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
Reviewed-by: default avatarFritz Koenig <frkoenig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#813178}
parent 533eb357
...@@ -258,12 +258,19 @@ void V4L2StatefulVideoDecoderBackend::EnqueueOutputBuffers() { ...@@ -258,12 +258,19 @@ void V4L2StatefulVideoDecoderBackend::EnqueueOutputBuffers() {
DVLOGF(3); DVLOGF(3);
const v4l2_memory mem_type = output_queue_->GetMemoryType(); const v4l2_memory mem_type = output_queue_->GetMemoryType();
while (base::Optional<V4L2WritableBufferRef> buffer = while (true) {
output_queue_->GetFreeBuffer()) {
bool ret = false; bool ret = false;
bool no_buffer = false;
base::Optional<V4L2WritableBufferRef> buffer;
switch (mem_type) { switch (mem_type) {
case V4L2_MEMORY_MMAP: case V4L2_MEMORY_MMAP:
buffer = output_queue_->GetFreeBuffer();
if (!buffer) {
no_buffer = true;
break;
}
ret = std::move(*buffer).QueueMMap(); ret = std::move(*buffer).QueueMMap();
break; break;
case V4L2_MEMORY_DMABUF: { case V4L2_MEMORY_DMABUF: {
...@@ -272,6 +279,12 @@ void V4L2StatefulVideoDecoderBackend::EnqueueOutputBuffers() { ...@@ -272,6 +279,12 @@ void V4L2StatefulVideoDecoderBackend::EnqueueOutputBuffers() {
// once frames are available. // once frames are available.
if (!video_frame) if (!video_frame)
return; return;
buffer = output_queue_->GetFreeBufferForFrame(*video_frame);
if (!buffer) {
no_buffer = true;
break;
}
ret = std::move(*buffer).QueueDMABuf(std::move(video_frame)); ret = std::move(*buffer).QueueDMABuf(std::move(video_frame));
break; break;
} }
...@@ -279,6 +292,11 @@ void V4L2StatefulVideoDecoderBackend::EnqueueOutputBuffers() { ...@@ -279,6 +292,11 @@ void V4L2StatefulVideoDecoderBackend::EnqueueOutputBuffers() {
NOTREACHED(); NOTREACHED();
} }
// Running out of V4L2 buffers is not an error, so just exit the loop
// gracefully.
if (no_buffer)
break;
if (!ret) if (!ret)
client_->OnBackendError(); client_->OnBackendError();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment