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);