shithub: libvpx

Download patch

ref: d6f7334abc7cd7f7933f4230317b924adfd40930
parent: 8a96ad8f478ee1a58f5b86e365df21d23a752347
author: angiebird <angiebird@google.com>
date: Mon Feb 24 06:20:10 EST 2020

Keep ref frame coding indexes in SimpleEncode

Change-Id: Id76aeb54ef93b11ca9a582f76289da0e60368e56

--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -524,6 +524,64 @@
          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 @@
   }
   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 @@
       .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 @@
       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");
--- a/vp9/simple_encode.h
+++ b/vp9/simple_encode.h
@@ -339,8 +339,28 @@
 
   // 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