]> granicus.if.org Git - libvpx/commitdiff
Keep ref frame coding indexes in SimpleEncode
authorangiebird <angiebird@google.com>
Mon, 24 Feb 2020 19:20:10 +0000 (11:20 -0800)
committerangiebird <angiebird@google.com>
Tue, 25 Feb 2020 23:59:49 +0000 (15:59 -0800)
Change-Id: Id76aeb54ef93b11ca9a582f76289da0e60368e56

vp9/simple_encode.cc
vp9/simple_encode.h

index 9d7fa822d8b849d6350fcd741c0f833255e7cf54..214d33cc860579ad87544304146a56d327c284a1 100644 (file)
@@ -524,6 +524,64 @@ static int IsGroupOfPictureFinished(const GroupOfPicture &group_of_picture) {
          group_of_picture.encode_frame_list.size();
 }
 
+static void UpdateRefFrameCodingIndexes(FrameType frame_type,
+                                        int frame_coding_index,
+                                        int *ref_frame_coding_indexes,
+                                        int *ref_frame_valid_list) {
+  // This part is written based on the logics in vp9_configure_buffer_updates()
+  // and update_ref_frames()
+  switch (frame_type) {
+    case kFrameTypeKey:
+      ref_frame_coding_indexes[kRefFrameTypeLast] = frame_coding_index;
+      ref_frame_coding_indexes[kRefFrameTypePast] = frame_coding_index;
+      ref_frame_coding_indexes[kRefFrameTypeFuture] = frame_coding_index;
+      break;
+    case kFrameTypeInter:
+      ref_frame_coding_indexes[kRefFrameTypeLast] = frame_coding_index;
+      break;
+    case kFrameTypeAltRef:
+      ref_frame_coding_indexes[kRefFrameTypeFuture] = frame_coding_index;
+      break;
+    case kFrameTypeOverlay:
+      // Reserve the past coding_index in the future slot. This logic is from
+      // update_ref_frames() with condition vp9_preserve_existing_gf() == 1
+      // TODO(angiebird): Invetegate why we need this.
+      ref_frame_coding_indexes[kRefFrameTypeFuture] =
+          ref_frame_coding_indexes[kRefFrameTypePast];
+      ref_frame_coding_indexes[kRefFrameTypePast] = frame_coding_index;
+      break;
+    case kFrameTypeGolden:
+      ref_frame_coding_indexes[kRefFrameTypePast] = frame_coding_index;
+      ref_frame_coding_indexes[kRefFrameTypeLast] = frame_coding_index;
+      break;
+  }
+
+  //  This part is written based on the logics in get_ref_frame_flags() but we
+  //  rename the flags alt, golden to future, past respectively. Mark
+  //  non-duplicated reference frames as valid. The priorities are
+  //  kRefFrameTypeLast > kRefFrameTypePast > kRefFrameTypeFuture.
+  const int last_index = ref_frame_coding_indexes[kRefFrameTypeLast];
+  const int past_index = ref_frame_coding_indexes[kRefFrameTypePast];
+  const int future_index = ref_frame_coding_indexes[kRefFrameTypeFuture];
+
+  for (int ref_frame_idx = 0; ref_frame_idx < kRefFrameTypeMax;
+       ++ref_frame_idx) {
+    ref_frame_valid_list[ref_frame_idx] = 1;
+  }
+
+  if (past_index == last_index) {
+    ref_frame_valid_list[kRefFrameTypeLast] = 0;
+  }
+
+  if (future_index == last_index) {
+    ref_frame_valid_list[kRefFrameTypeFuture] = 0;
+  }
+
+  if (future_index == past_index) {
+    ref_frame_valid_list[kRefFrameTypeFuture] = 0;
+  }
+}
+
 static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref,
                               int coding_frame_count, int first_show_idx,
                               int last_gop_use_alt_ref, int start_coding_index,
@@ -613,6 +671,11 @@ SimpleEncode::SimpleEncode(int frame_width, int frame_height,
   }
   impl_ptr_->cpi = nullptr;
   impl_ptr_->img_fmt = VPX_IMG_FMT_I420;
+
+  for (int i = 0; i < kRefFrameTypeMax; ++i) {
+    ref_frame_coding_indexes_[i] = 0;
+    ref_frame_valid_list_[i] = 0;
+  }
 }
 
 void SimpleEncode::ComputeFirstPassStats() {
@@ -751,6 +814,21 @@ EncodeFrameInfo SimpleEncode::GetNextEncodeFrameInfo() const {
       .encode_frame_list[group_of_picture_.next_encode_frame_index];
 }
 
+void SimpleEncode::PostUpdateState(
+    const EncodeFrameResult &encode_frame_result) {
+  // This function needs to be called before the increament of
+  // frame_coding_index_
+  UpdateRefFrameCodingIndexes(encode_frame_result.frame_type,
+                              frame_coding_index_, ref_frame_coding_indexes_,
+                              ref_frame_valid_list_);
+  ++frame_coding_index_;
+  IncreaseGroupOfPictureIndex(&group_of_picture_);
+  if (IsGroupOfPictureFinished(group_of_picture_)) {
+    UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_,
+                         &group_of_picture_);
+  }
+}
+
 void SimpleEncode::EncodeFrame(EncodeFrameResult *encode_frame_result) {
   VP9_COMP *cpi = impl_ptr_->cpi;
   struct lookahead_ctx *lookahead = cpi->lookahead;
@@ -815,14 +893,8 @@ void SimpleEncode::EncodeFrame(EncodeFrameResult *encode_frame_result) {
       abort();
     }
 
-    // TODO(angiebird): Add a function to update internal state of SimpleEncode
     update_encode_frame_result(encode_frame_result, &encode_frame_info);
-    ++frame_coding_index_;
-    IncreaseGroupOfPictureIndex(&group_of_picture_);
-    if (IsGroupOfPictureFinished(group_of_picture_)) {
-      UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_,
-                           &group_of_picture_);
-    }
+    PostUpdateState(*encode_frame_result);
   } else {
     // TODO(angiebird): Clean up encode_frame_result.
     fprintf(stderr, "init_encode_frame_result() failed.\n");
index f62648096d75b262de08ac213ddd68a018bbc5d8..6e70e993e3b7fff28645c868a6c5d06d549ab359 100644 (file)
@@ -339,8 +339,28 @@ class SimpleEncode {
 
   // Each show or no show frame is assigned with a coding index based on its
   // coding order (starting from zero) in the coding process of the entire
-  // video. The coding index of to-be-coded frame.
+  // video. The coding index of the to-be-coded frame.
   int frame_coding_index_;
+
+  // Coding indexes of reference frames of to-be-coded-frame.
+  int ref_frame_coding_indexes_[kRefFrameTypeMax];
+
+  // Indicate whether the reference frames are available or not.
+  // When the reference frame type is not valid, it means either the to-be-coded
+  // frame is a key frame or the reference frame already appears in other
+  // reference frame type. vp9 always keeps three types of reference frame
+  // available.  However, the duplicated reference frames will not be
+  // chosen by the encoder. The priorities of choosing reference frames are
+  // kRefFrameTypeLast > kRefFrameTypePast > kRefFrameTypeFuture.
+  // For example, if kRefFrameTypeLast and kRefFrameTypePast both point to the
+  // same frame, kRefFrameTypePast will be set to invalid.
+
+  // TODO(angiebird): Do we need to reset ref_frame_valid_list_ and
+  // ref_frame_valid_list_ when nex key frame appears?
+
+  int ref_frame_valid_list_[kRefFrameTypeMax];
+
+  void PostUpdateState(const EncodeFrameResult &encode_frame_result);
 };
 
 }  // namespace vp9