media/gpu/v4l2: Fix |order_hints| setup for AV1 decode

This CL fixes an issue with |order_hints| setup of
|v4l2_ctrl_av1_frame|. Current setup works correctly for some simple
tests when |order_hint| happens to match with frame number
(b/242337166). However, it will cause md5 mis-matches with general
cases. This CL updates this algorithm by using |ref_order_hint_|
referencing the AV1 spec
(https://aomediacodec.github.io/av1-spec/#uncompressed-header-syntax).
Md5 mismatch is resolved with this fix for
non_uniform_tiling_20201006.ivf test vector.

Bug: b:249104479, b:248551111
TEST: v4l2_stateless_decoder --video=non_uniform_tiling_20201006.ivf using updated ec, kernel
Change-Id: I5fe7e23dae1093f7f1b5e0caf68224f888090b02
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3923977
Commit-Queue: Steve Cho <stevecho@chromium.org>
Reviewed-by: Nathan Hebert <nhebert@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1052459}
diff --git a/media/gpu/v4l2/test/av1_decoder.cc b/media/gpu/v4l2/test/av1_decoder.cc
index b0877b9..796a4b6 100644
--- a/media/gpu/v4l2/test/av1_decoder.cc
+++ b/media/gpu/v4l2/test/av1_decoder.cc
@@ -827,18 +827,13 @@
 
   // The first slot in |order_hints| is reserved for intra frame, so it is not
   // used and will always be 0.
-  // Please reference more details in the below comment for this algorithm to
-  // compute |order_hints|. In summary, we are trying to get frame number here
-  // given a specific reference frame type (L0, L1, L2, G, B, A1, A2) in
-  // the reference frames list.
-  // https://b.corp.google.com/issues/242337166#comment24
   static_assert(std::size(decltype(v4l2_frame_params->order_hints){}) ==
                     libgav1::kNumReferenceFrameTypes,
                 "Invalid size of |order_hints| array");
   if (frm_header.frame_type != libgav1::kFrameKey) {
     for (size_t i = 0; i < libgav1::kNumInterReferenceFrameTypes; i++) {
       v4l2_frame_params->order_hints[i + 1] =
-          ref_frames_[frm_header.reference_frame_index[i]]->frame_number();
+          ref_order_hint_[frm_header.reference_frame_index[i]];
     }
   }
 
@@ -881,10 +876,11 @@
 }
 
 std::set<int> Av1Decoder::RefreshReferenceSlots(
-    uint8_t refresh_frame_flags,
-    libgav1::RefCountedBufferPtr current_frame,
-    scoped_refptr<MmapedBuffer> buffer,
-    uint32_t last_queued_buffer_index) {
+    const uint8_t refresh_frame_flags,
+    const libgav1::RefCountedBufferPtr current_frame,
+    const scoped_refptr<MmapedBuffer> buffer,
+    const uint32_t last_queued_buffer_index,
+    const uint8_t order_hint) {
   state_->UpdateReferenceFrames(current_frame,
                                 base::strict_cast<int>(refresh_frame_flags));
 
@@ -921,6 +917,9 @@
     // reference frame slots in the reference frames list.
     ref_frames_.fill(buffer);
 
+    // TODO(b/249104479): Update |ref_order_hint_| as needed for all reference
+    // frame slots after finding relevant test vector
+
     return reusable_buffer_ids;
   }
 
@@ -951,6 +950,7 @@
       }
     }
     ref_frames_[i] = buffer;
+    ref_order_hint_[i] = order_hint;
   }
 
   return reusable_buffer_ids;
@@ -1071,7 +1071,8 @@
   const std::set<int> reusable_buffer_ids =
       RefreshReferenceSlots(current_frame_header.refresh_frame_flags,
                             current_frame, CAPTURE_queue_->GetBuffer(index),
-                            CAPTURE_queue_->last_queued_buffer_index());
+                            CAPTURE_queue_->last_queued_buffer_index(),
+                            current_frame_header.order_hint);
 
   for (const auto reusable_buffer_id : reusable_buffer_ids) {
     if (!v4l2_ioctl_->QBuf(CAPTURE_queue_, reusable_buffer_id))
diff --git a/media/gpu/v4l2/test/av1_decoder.h b/media/gpu/v4l2/test/av1_decoder.h
index 5b77e35..34a60602 100644
--- a/media/gpu/v4l2/test/av1_decoder.h
+++ b/media/gpu/v4l2/test/av1_decoder.h
@@ -128,17 +128,25 @@
       const libgav1::ObuFrameHeader& frm_header);
 
   // Refreshes |ref_frames_| slots with the current |buffer| and refreshes
-  // |state_| with |current_frame|. Returns |reusable_buffer_slots| to indicate
-  // which CAPTURE buffers can be reused for VIDIOC_QBUF ioctl call.
+  // |state_| with |current_frame|. Updates |ref_order_hint_| using |order_hint|
+  // of current frame header, which is needed for the next frame decoding.
+  // Returns |reusable_buffer_slots| to indicate which CAPTURE buffers can be
+  // reused for VIDIOC_QBUF ioctl call.
   std::set<int> RefreshReferenceSlots(
-      uint8_t refresh_frame_flags,
-      libgav1::RefCountedBufferPtr current_frame,
-      scoped_refptr<MmapedBuffer> buffer,
-      uint32_t last_queued_buffer_index);
+      const uint8_t refresh_frame_flags,
+      const libgav1::RefCountedBufferPtr current_frame,
+      const scoped_refptr<MmapedBuffer> buffer,
+      const uint32_t last_queued_buffer_index,
+      const uint8_t order_hint);
 
   // Reference frames currently in use.
   std::array<scoped_refptr<MmapedBuffer>, kAv1NumRefFrames> ref_frames_;
 
+  // Represents the least significant bits of the expected output order of the
+  // frames. Corresponds to |RefOrderHint| in the AV1 spec.
+  // https://aomediacodec.github.io/av1-spec/#set-frame-refs-process
+  std::array<uint8_t, kAv1NumRefFrames> ref_order_hint_{0};
+
   // Parser for the IVF stream to decode.
   const std::unique_ptr<IvfParser> ivf_parser_;