shithub: libvpx

Download patch

ref: 320fb4c34a6d6bed560fbe564e7e1eae328be100
parent: 5774259307902a7d6ea5f2da06fa7d8f6f8284a7
author: angiebird <angiebird@google.com>
date: Thu Feb 20 09:11:25 EST 2020

Add kGoldenFrame and kOverlayFrame to FrameType

Add coding_index to EncodeFrameInfo
Add start_coding_index to GroupOfPicture
Add frame_coding_index_ to SimpleEncode

The definition of coding index is as follows.

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 for each frame is unique.

Change-Id: I43e18434a0dff0d1cd6f927a693d6860e4038337

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -3645,12 +3645,12 @@
 #if CONFIG_RATE_CTRL
 void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame,
                                    int *use_alt_ref, int *coding_frame_count,
-                                   int *first_show_idx) {
+                                   int *first_show_idx,
+                                   int *last_gop_use_alt_ref) {
   // We make a copy of rc here because we want to get information from the
   // encoder without changing its state.
   // TODO(angiebird): Avoid copying rc here.
   RATE_CONTROL rc = cpi->rc;
-  const int last_gop_use_alt_ref = rc.source_alt_ref_active;
   const int multi_layer_arf = 0;
   const int allow_alt_ref = 1;
   // We assume that current_video_frame is updated to the show index of the
@@ -3658,6 +3658,7 @@
   // the end of encode_frame_to_data_rate().
   // TODO(angiebird): Avoid this kind of fragile style.
   *first_show_idx = cpi->common.current_video_frame;
+  *last_gop_use_alt_ref = rc.source_alt_ref_active;
 
   *first_is_key_frame = 0;
   if (rc.frames_to_key == 0) {
@@ -3671,7 +3672,7 @@
   *coding_frame_count = vp9_get_gop_coding_frame_count(
       &cpi->oxcf, &cpi->frame_info, &cpi->twopass.first_pass_info, &rc,
       *first_show_idx, multi_layer_arf, allow_alt_ref, *first_is_key_frame,
-      last_gop_use_alt_ref, use_alt_ref);
+      *last_gop_use_alt_ref, use_alt_ref);
 }
 
 int vp9_get_gop_coding_frame_count(const VP9EncoderConfig *oxcf,
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -260,8 +260,8 @@
  */
 void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi,
                                    int *first_is_key_frame, int *use_alt_ref,
-                                   int *coding_frame_count,
-                                   int *first_show_idx);
+                                   int *coding_frame_count, int *first_show_idx,
+                                   int *last_gop_use_alt_ref);
 
 /*!\brief Call this function before coding a new group of pictures to get
  * information about it.
--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -132,12 +132,16 @@
 
 static INLINE FrameType
 get_frame_type_from_update_type(FRAME_UPDATE_TYPE update_type) {
-  // TODO(angiebird): Figure out if we need frame type other than key frame,
-  // alternate reference and inter frame
   switch (update_type) {
-    case KF_UPDATE: return kKeyFrame; break;
-    case ARF_UPDATE: return kAlternateReference; break;
-    default: return kInterFrame; break;
+    case KF_UPDATE: return kKeyFrame;
+    case ARF_UPDATE: return kAlternateReference;
+    case GF_UPDATE: return kGoldenFrame;
+    case OVERLAY_UPDATE: return kOverlayFrame;
+    case LF_UPDATE: return kInterFrame;
+    default:
+      fprintf(stderr, "Unsupported update_type %d\n", update_type);
+      abort();
+      return kInterFrame;
   }
 }
 
@@ -507,6 +511,7 @@
 
 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,
                               GroupOfPicture *group_of_picture) {
   // Clean up the state of previous group of picture.
   group_of_picture->encode_frame_list.clear();
@@ -513,6 +518,7 @@
   group_of_picture->next_encode_frame_index = 0;
   group_of_picture->show_frame_count = coding_frame_count - use_alt_ref;
   group_of_picture->start_show_index = first_show_idx;
+  group_of_picture->start_coding_index = start_coding_index;
   {
     // First frame in the group of pictures. It's either key frame or show inter
     // frame.
@@ -520,9 +526,14 @@
     if (first_is_key_frame) {
       encode_frame_info.frame_type = kKeyFrame;
     } else {
-      encode_frame_info.frame_type = kInterFrame;
+      if (last_gop_use_alt_ref) {
+        encode_frame_info.frame_type = kOverlayFrame;
+      } else {
+        encode_frame_info.frame_type = kGoldenFrame;
+      }
     }
     encode_frame_info.show_idx = first_show_idx;
+    encode_frame_info.coding_index = start_coding_index;
     group_of_picture->encode_frame_list.push_back(encode_frame_info);
   }
 
@@ -533,6 +544,7 @@
     EncodeFrameInfo encode_frame_info;
     encode_frame_info.frame_type = kAlternateReference;
     encode_frame_info.show_idx = first_show_idx + show_frame_count;
+    encode_frame_info.coding_index = start_coding_index + 1;
     group_of_picture->encode_frame_list.push_back(encode_frame_info);
   }
 
@@ -541,20 +553,24 @@
     EncodeFrameInfo encode_frame_info;
     encode_frame_info.frame_type = kInterFrame;
     encode_frame_info.show_idx = first_show_idx + i;
+    encode_frame_info.coding_index = start_coding_index + use_alt_ref + i;
     group_of_picture->encode_frame_list.push_back(encode_frame_info);
   }
 }
 
-static void UpdateGroupOfPicture(const VP9_COMP *cpi,
+static void UpdateGroupOfPicture(const VP9_COMP *cpi, int start_coding_index,
                                  GroupOfPicture *group_of_picture) {
   int first_is_key_frame;
   int use_alt_ref;
   int coding_frame_count;
   int first_show_idx;
+  int last_gop_use_alt_ref;
   vp9_get_next_group_of_picture(cpi, &first_is_key_frame, &use_alt_ref,
-                                &coding_frame_count, &first_show_idx);
+                                &coding_frame_count, &first_show_idx,
+                                &last_gop_use_alt_ref);
   SetGroupOfPicture(first_is_key_frame, use_alt_ref, coding_frame_count,
-                    first_show_idx, group_of_picture);
+                    first_show_idx, last_gop_use_alt_ref, start_coding_index,
+                    group_of_picture);
 }
 
 SimpleEncode::SimpleEncode(int frame_width, int frame_height,
@@ -568,6 +584,7 @@
   frame_rate_den_ = frame_rate_den;
   target_bitrate_ = target_bitrate;
   num_frames_ = num_frames;
+  frame_coding_index_ = 0;
   // TODO(angirbid): Should we keep a file pointer here or keep the file_path?
   in_file_ = fopen(infile_path, "r");
   if (outfile_path != nullptr) {
@@ -672,7 +689,8 @@
   impl_ptr_->cpi = init_encoder(&oxcf, impl_ptr_->img_fmt);
   vpx_img_alloc(&impl_ptr_->tmp_img, impl_ptr_->img_fmt, frame_width_,
                 frame_height_, 1);
-  UpdateGroupOfPicture(impl_ptr_->cpi, &group_of_picture_);
+  frame_coding_index_ = 0;
+  UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, &group_of_picture_);
   rewind(in_file_);
 
   if (out_file_ != nullptr) {
@@ -771,10 +789,13 @@
       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, &group_of_picture_);
+      UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_,
+                           &group_of_picture_);
     }
   } else {
     // TODO(angiebird): Clean up encode_frame_result.
--- a/vp9/simple_encode.h
+++ b/vp9/simple_encode.h
@@ -23,15 +23,18 @@
   kKeyFrame = 0,
   kInterFrame,
   kAlternateReference,
+  kOverlayFrame,
+  kGoldenFrame,
 };
 
 // The enum type is similar to vp9: |MV_REFERENCE_FRAME|.
+// TODO(angiebird): Clarify the difference between FrameType and RefFrameType.
 enum RefFrameType {
-  kIntraFrame = 0,
-  kLastFrame = 1,
-  kGoldenFrame = 2,
+  kIntraRefFrame = 0,
+  kLastRefFrame = 1,
+  kGoldenRefFrame = 2,
   kAltRefFrame = 3,
-  kNoneRefFrame = -1,
+  kNoneRefRefFrame = -1,
 };
 
 // The frame is split to 4x4 blocks.
@@ -68,6 +71,11 @@
 
 struct EncodeFrameInfo {
   int show_idx;
+
+  // 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 for each frame is unique.
+  int coding_index;
   FrameType frame_type;
 };
 
@@ -237,6 +245,8 @@
   // The show index/timestamp of the earliest show frame in the group of
   // pictures.
   int start_show_index;
+  // The coding index of the first coding frame in the group of picture.
+  int start_coding_index;
 };
 
 class SimpleEncode {
@@ -309,11 +319,17 @@
   int frame_rate_den_;
   int target_bitrate_;
   int num_frames_;
+
   std::FILE *in_file_;
   std::FILE *out_file_;
   std::unique_ptr<EncodeImpl> impl_ptr_;
 
   GroupOfPicture group_of_picture_;
+
+  // 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.
+  int frame_coding_index_;
 };
 
 }  // namespace vp9