media/gpu/v4l2ip: let the IP pass the buffer index to the callback itself

We want to make the V4L2IP manage its buffers itself. To allow this,
the client must stop asking for a specific IP buffer to be used to
process a given frame. This means that the process complete callback
can now receive any of the IP's buffers, which the client cannot guess
anymore. This CL thus changes the callback prototype to take the
buffer index, and makes the V4L2IP call it with the right buffer index.

No other change is introduced, so clients will continue receiving the
buffer that they requested when calling Process().

Bug: 792790
Test: Ran VDA (regular and import mode) and VEA unittest on hana and peach_pit.

Change-Id: Ia61c2117e5ca36349d20ee479fad9a8b9b667ead
Reviewed-on: https://chromium-review.googlesource.com/c/1454022
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#633024}
diff --git a/media/gpu/image_processor.cc b/media/gpu/image_processor.cc
index 9cf0ab5..85418c5 100644
--- a/media/gpu/image_processor.cc
+++ b/media/gpu/image_processor.cc
@@ -33,7 +33,7 @@
 bool ImageProcessor::Process(scoped_refptr<VideoFrame> frame,
                              int output_buffer_index,
                              std::vector<base::ScopedFD> output_dmabuf_fds,
-                             FrameReadyCB cb) {
+                             LegacyFrameReadyCB cb) {
   return ProcessInternal(std::move(frame), output_buffer_index,
                          std::move(output_dmabuf_fds),
                          BindToCurrentLoop(std::move(cb)));
diff --git a/media/gpu/image_processor.h b/media/gpu/image_processor.h
index ebff253..4727bb94 100644
--- a/media/gpu/image_processor.h
+++ b/media/gpu/image_processor.h
@@ -64,6 +64,14 @@
   // Process() is responsible for making sure this invariant is
   // respected by using media::BindToCurrentLoop().
   using FrameReadyCB = base::OnceCallback<void(scoped_refptr<VideoFrame>)>;
+  // Callback to be used to return a processed image to the client.
+  // Used when calling the "legacy" Process() method with buffers that are
+  // managed by the IP. The first argument is the index of the returned buffer.
+  // FrameReadyCB is guaranteed to be executed on the "client thread".
+  // Process() is responsible for making sure this invariant is
+  // respected by using media::BindToCurrentLoop().
+  using LegacyFrameReadyCB =
+      base::OnceCallback<void(size_t, scoped_refptr<VideoFrame>)>;
 
   // Callback to be used to notify client when ImageProcess encounters error.
   // It should be assigned in subclass' factory method. ErrorCB is guaranteed to
@@ -114,7 +122,7 @@
   bool Process(scoped_refptr<VideoFrame> frame,
                int output_buffer_index,
                std::vector<base::ScopedFD> output_dmabuf_fds,
-               FrameReadyCB cb);
+               LegacyFrameReadyCB cb);
 #endif
 
   // Called by client to process |input_frame| and store in |output_frame|. This
@@ -159,7 +167,7 @@
   virtual bool ProcessInternal(scoped_refptr<VideoFrame> frame,
                                int output_buffer_index,
                                std::vector<base::ScopedFD> output_dmabuf_fds,
-                               FrameReadyCB cb) = 0;
+                               LegacyFrameReadyCB cb) = 0;
 #endif
   virtual bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
                                scoped_refptr<VideoFrame> output_frame,
diff --git a/media/gpu/libyuv_image_processor.cc b/media/gpu/libyuv_image_processor.cc
index 9654749..6d663ff0 100644
--- a/media/gpu/libyuv_image_processor.cc
+++ b/media/gpu/libyuv_image_processor.cc
@@ -104,7 +104,7 @@
     scoped_refptr<VideoFrame> frame,
     int output_buffer_index,
     std::vector<base::ScopedFD> output_dmabuf_fds,
-    FrameReadyCB cb) {
+    LegacyFrameReadyCB cb) {
   DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
   NOTIMPLEMENTED();
   return false;
diff --git a/media/gpu/libyuv_image_processor.h b/media/gpu/libyuv_image_processor.h
index 386463d..1780fc62 100644
--- a/media/gpu/libyuv_image_processor.h
+++ b/media/gpu/libyuv_image_processor.h
@@ -61,7 +61,7 @@
   bool ProcessInternal(scoped_refptr<VideoFrame> frame,
                        int output_buffer_index,
                        std::vector<base::ScopedFD> output_dmabuf_fds,
-                       FrameReadyCB cb) override;
+                       LegacyFrameReadyCB cb) override;
 #endif
   bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
                        scoped_refptr<VideoFrame> output_frame,
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc
index 60eabd7..7242552d 100644
--- a/media/gpu/v4l2/v4l2_image_processor.cc
+++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -376,13 +376,13 @@
     scoped_refptr<VideoFrame> frame,
     int output_buffer_index,
     std::vector<base::ScopedFD> output_dmabuf_fds,
-    FrameReadyCB cb) {
+    LegacyFrameReadyCB cb) {
   DVLOGF(4) << "ts=" << frame->timestamp().InMilliseconds();
 
   auto job_record = std::make_unique<JobRecord>();
   job_record->input_frame = frame;
   job_record->output_buffer_index = output_buffer_index;
-  job_record->ready_cb = std::move(cb);
+  job_record->legacy_ready_cb = std::move(cb);
 
   switch (output_memory_type_) {
     case V4L2_MEMORY_MMAP:
@@ -802,7 +802,12 @@
 
     DVLOGF(4) << "Processing finished, returning frame, index=" << dqbuf.index;
 
-    std::move(job_record->ready_cb).Run(std::move(output_frame));
+    if (!job_record->legacy_ready_cb.is_null()) {
+      std::move(job_record->legacy_ready_cb)
+          .Run(dqbuf.index, std::move(output_frame));
+    } else {
+      std::move(job_record->ready_cb).Run(std::move(output_frame));
+    }
   }
 }
 
diff --git a/media/gpu/v4l2/v4l2_image_processor.h b/media/gpu/v4l2/v4l2_image_processor.h
index 953f3f46..bc46c1c 100644
--- a/media/gpu/v4l2/v4l2_image_processor.h
+++ b/media/gpu/v4l2/v4l2_image_processor.h
@@ -100,6 +100,7 @@
     int output_buffer_index;
     std::vector<base::ScopedFD> output_dmabuf_fds;
     FrameReadyCB ready_cb;
+    LegacyFrameReadyCB legacy_ready_cb;
   };
 
   V4L2ImageProcessor(scoped_refptr<V4L2Device> device,
@@ -132,7 +133,7 @@
   bool ProcessInternal(scoped_refptr<VideoFrame> frame,
                        int output_buffer_index,
                        std::vector<base::ScopedFD> output_dmabuf_fds,
-                       FrameReadyCB cb) override;
+                       LegacyFrameReadyCB cb) override;
   bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
                        scoped_refptr<VideoFrame> output_frame,
                        FrameReadyCB cb) override;
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index 48d8fca..269a23b 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -2492,8 +2492,7 @@
   image_processor_->Process(
       input_frame, buf->BufferId(), std::move(output_fds),
       base::BindOnce(&V4L2VideoDecodeAccelerator::FrameProcessed,
-                     base::Unretained(this), bitstream_buffer_id,
-                     buf->BufferId()));
+                     base::Unretained(this), bitstream_buffer_id));
   return true;
 }
 
@@ -2677,7 +2676,7 @@
 
 void V4L2VideoDecodeAccelerator::FrameProcessed(
     int32_t bitstream_buffer_id,
-    int ip_buffer_index,
+    size_t ip_buffer_index,
     scoped_refptr<VideoFrame> frame) {
   DVLOGF(4) << "ip_buffer_index=" << ip_buffer_index
             << ", bitstream_buffer_id=" << bitstream_buffer_id;
@@ -2703,8 +2702,8 @@
               << bitstream_buffer_id;
     return;
   }
-  DCHECK_GE(ip_buffer_index, 0);
-  DCHECK_LT(ip_buffer_index, static_cast<int>(output_buffer_map_.size()));
+  DCHECK_GE(ip_buffer_index, 0u);
+  DCHECK_LT(ip_buffer_index, output_buffer_map_.size());
 
   // This is the output record for the buffer received from the IP, which index
   // may differ from the buffer used by the VDA.
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
index 6a22d9c..059a37d2 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
@@ -419,7 +419,7 @@
   // |bitstream_buffer_id| and stored in |output_buffer_index| buffer of
   // image processor.
   void FrameProcessed(int32_t bitstream_buffer_id,
-                      int output_buffer_index,
+                      size_t output_buffer_index,
                       scoped_refptr<VideoFrame> frame);
 
   // Image processor notifies an error.
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index 934d36fd..0b660c3 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -400,8 +400,8 @@
         if (!image_processor_->Process(
                 frame, output_buffer_index, std::vector<base::ScopedFD>(),
                 base::BindOnce(&V4L2VideoEncodeAccelerator::FrameProcessed,
-                               weak_this_, force_keyframe, frame->timestamp(),
-                               output_buffer_index))) {
+                               weak_this_, force_keyframe,
+                               frame->timestamp()))) {
           NOTIFY_ERROR(kPlatformFailureError);
         }
       }
@@ -529,12 +529,12 @@
 void V4L2VideoEncodeAccelerator::FrameProcessed(
     bool force_keyframe,
     base::TimeDelta timestamp,
-    int output_buffer_index,
+    size_t output_buffer_index,
     scoped_refptr<VideoFrame> frame) {
   DCHECK(child_task_runner_->BelongsToCurrentThread());
   DVLOGF(4) << "force_keyframe=" << force_keyframe
             << ", output_buffer_index=" << output_buffer_index;
-  DCHECK_GE(output_buffer_index, 0);
+  DCHECK_GE(output_buffer_index, 0u);
   DCHECK(encoder_thread_.IsRunning());
   DCHECK(!weak_this_.WasInvalidated());
 
@@ -548,7 +548,7 @@
 }
 
 void V4L2VideoEncodeAccelerator::ReuseImageProcessorOutputBuffer(
-    int output_buffer_index) {
+    size_t output_buffer_index) {
   DCHECK(child_task_runner_->BelongsToCurrentThread());
   DVLOGF(4) << "output_buffer_index=" << output_buffer_index;
   free_image_processor_output_buffer_indices_.push_back(output_buffer_index);
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.h b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
index 7e2d30c..aff19bb 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.h
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
@@ -117,7 +117,7 @@
   // encode.
   void FrameProcessed(bool force_keyframe,
                       base::TimeDelta timestamp,
-                      int output_buffer_index,
+                      size_t output_buffer_index,
                       scoped_refptr<VideoFrame> frame);
 
   // Error callback for handling image processor errors.
@@ -218,7 +218,7 @@
   bool AllocateImageProcessorOutputBuffers();
 
   // Recycle output buffer of image processor with |output_buffer_index|.
-  void ReuseImageProcessorOutputBuffer(int output_buffer_index);
+  void ReuseImageProcessorOutputBuffer(size_t output_buffer_index);
 
   // Copy encoded stream data from an output V4L2 buffer at |bitstream_data|
   // of size |bitstream_size| into a BitstreamBuffer referenced by |buffer_ref|,