media/gpu/v4l2vea: 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 encoder.
BUG=b:159688625
BUG=b:167412992
TEST=video.EncodeAccel.h264_360p_i420 passes on Kukui.
(cherry picked from commit b2a7b0cc4ec6752e1ada55112ceefa2097f3d364)
Change-Id: I050c29ecf8b364869f687c3d8632718aef868144
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2415910
Commit-Queue: Alexandre Courbot <[email protected]>
Reviewed-by: Fritz Koenig <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#813514}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2459938
Reviewed-by: Alexandre Courbot <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#134}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index 6b845df..f715029 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -1029,7 +1029,21 @@
encoder_state_ = kFlushing;
break;
}
- auto input_buffer = input_queue_->GetFreeBuffer();
+
+ base::Optional<V4L2WritableBufferRef> input_buffer;
+ switch (input_memory_type_) {
+ case V4L2_MEMORY_DMABUF:
+ input_buffer = input_queue_->GetFreeBufferForFrame(
+ *encoder_input_queue_.front().frame);
+ // We may have failed to preserve buffer affinity, fallback to any
+ // buffer in that case.
+ if (!input_buffer)
+ input_buffer = input_queue_->GetFreeBuffer();
+ break;
+ default:
+ input_buffer = input_queue_->GetFreeBuffer();
+ break;
+ }
// input_buffer cannot be base::nullopt since we checked for
// input_queue_->FreeBuffersCount() > 0 before entering the loop.
DCHECK(input_buffer);