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