[go: nahoru, domu]

gpu/vp9_dec: Use VP9ReferenceFraameVector for ref pic management

VP9ReferenceFraameVector is the class implemented
for generalising the VP9 reference picture mangament with in
the encoder and decoder similar to the VP8 implementation.
Currenlty VP9ReferenceFraameVector is only utilized in the encoder
implementation. This patch enables the same in decoder too.

Bug:chromium:924804
TEST= video_decode_accelerator_unittest \
    --test_video_data=test-25fps.vp9:320:240:250:250:35:150:12 \
    -v=0 --disable_flush --single-process-tests --ozone-platform=gbm

Change-Id: I725c214c38a5aed1720bd9d91445ac4841f5014b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1540482
Commit-Queue: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#647129}
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc
index 632a967..d0cf58a 100644
--- a/media/gpu/vp9_decoder.cc
+++ b/media/gpu/vp9_decoder.cc
@@ -23,7 +23,6 @@
       container_color_space_(container_color_space),
       accelerator_(std::move(accelerator)),
       parser_(accelerator_->IsFrameContextRequired()) {
-  ref_frames_.resize(kVp9NumRefFrames);
 }
 
 VP9Decoder::~VP9Decoder() = default;
@@ -52,8 +51,8 @@
 
 void VP9Decoder::Reset() {
   curr_frame_hdr_ = nullptr;
-  for (auto& ref_frame : ref_frames_)
-    ref_frame = nullptr;
+
+  ref_frames_.Clear();
 
   parser_.Reset();
 
@@ -108,7 +107,8 @@
       // previously-decoded frames, but has no frame data otherwise. Display
       // and continue decoding subsequent frames.
       size_t frame_to_show = curr_frame_hdr_->frame_to_show_map_idx;
-      if (frame_to_show >= ref_frames_.size() || !ref_frames_[frame_to_show]) {
+      if (frame_to_show >= kVp9NumRefFrames ||
+          !ref_frames_.GetFrame(frame_to_show)) {
         DVLOG(1) << "Request to show an invalid frame";
         SetError();
         return kDecodeError;
@@ -116,7 +116,8 @@
 
       // Duplicate the VP9Picture and set the current bitstream id to keep the
       // correct timestamp.
-      scoped_refptr<VP9Picture> pic = ref_frames_[frame_to_show]->Duplicate();
+      scoped_refptr<VP9Picture> pic =
+          ref_frames_.GetFrame(frame_to_show)->Duplicate();
       if (pic == nullptr) {
         DVLOG(1) << "Failed to duplicate the VP9Picture.";
         SetError();
@@ -160,8 +161,7 @@
       // required, because VDA clients expect all surfaces to be returned before
       // they can cycle surface sets after receiving kAllocateNewSurfaces.
       // This is only an implementation detail of VDAs and can be improved.
-      for (auto& ref_frame : ref_frames_)
-        ref_frame = nullptr;
+      ref_frames_.Clear();
 
       pic_size_ = new_pic_size;
       size_change_failure_counter_ = 0;
@@ -203,14 +203,6 @@
   }
 }
 
-void VP9Decoder::RefreshReferenceFrames(const scoped_refptr<VP9Picture>& pic) {
-  for (size_t i = 0; i < kVp9NumRefFrames; ++i) {
-    DCHECK(!pic->frame_hdr->IsKeyframe() || pic->frame_hdr->RefreshFlag(i));
-    if (pic->frame_hdr->RefreshFlag(i))
-      ref_frames_[i] = pic;
-  }
-}
-
 void VP9Decoder::UpdateFrameContext(
     const scoped_refptr<VP9Picture>& pic,
     const base::Callback<void(const Vp9FrameContext&)>& context_refresh_cb) {
@@ -247,7 +239,7 @@
       return false;
   }
 
-  RefreshReferenceFrames(pic);
+  ref_frames_.Refresh(pic);
   return true;
 }