shithub: libvpx

Download patch

ref: 08b01d5e05774bea18348e1f282b940f7fcddb98
parent: 7e665ec96839d33b4943c09f4e4e39962b8afba5
author: Cheng Chen <chengchen@google.com>
date: Tue Feb 18 04:57:46 EST 2020

Allow external arf to determine gop size

When "rate_ctrl" experiment is on, we allow the external arf
passed from outside to determine group of picture size
in define_gf_group().

Change-Id: I0b8c3e1bf3087f21a4e484354168df4967d35bba

--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -518,15 +518,6 @@
 } KMEANS_DATA;
 
 #if CONFIG_RATE_CTRL
-typedef struct ENCODE_COMMAND {
-  int use_external_quantize_index;
-  int external_quantize_index;
-  int use_external_arf;
-  // A list of binary flags set from the external controller.
-  // Each binary flag indicates whether the frame is an arf or not.
-  const int *external_arf_indexes;
-} ENCODE_COMMAND;
-
 typedef struct PARTITION_INFO {
   int row;           // row pixel offset of current 4x4 block
   int column;        // column pixel offset of current 4x4 block
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2471,10 +2471,16 @@
  *   rc->frames_since_key
  *   rc->source_alt_ref_active
  *
+ * Special case: if CONFIG_RATE_CTRL is true, the external arf indexes will
+ * determine the arf position.
+ *
  * TODO(angiebird): Separate the dynamic fields and static fields into two
  * structs.
  */
 static int get_gop_coding_frame_num(
+#if CONFIG_RATE_CTRL
+    const ENCODE_COMMAND *encode_command,
+#endif
     int *use_alt_ref, const FRAME_INFO *frame_info,
     const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc,
     int gf_start_show_idx, const RANGE *active_gf_interval,
@@ -2490,7 +2496,25 @@
       (frame_info->frame_height + frame_info->frame_width) / 4.0;
   double zero_motion_accumulator = 1.0;
   int gop_coding_frames;
+#if CONFIG_RATE_CTRL
+  (void)mv_ratio_accumulator_thresh;
+  (void)active_gf_interval;
+  (void)gop_intra_factor;
 
+  if (encode_command != NULL && encode_command->use_external_arf) {
+    // gop_coding_frames = 1 is necessary to filter out the overlay frame,
+    // since the arf is in this group of picture and its overlay is in the next.
+    gop_coding_frames = 1;
+    *use_alt_ref = 1;
+    while (gop_coding_frames < rc->frames_to_key) {
+      const int frame_index = gf_start_show_idx + gop_coding_frames;
+      ++gop_coding_frames;
+      if (encode_command->external_arf_indexes[frame_index] == 1) break;
+    }
+    return gop_coding_frames;
+  }
+#endif  // CONFIG_RATE_CTRL
+
   *use_alt_ref = 1;
   gop_coding_frames = 0;
   while (gop_coding_frames < rc->static_scene_max_gf_interval &&
@@ -2718,6 +2742,9 @@
 
   {
     gop_coding_frames = get_gop_coding_frame_num(
+#if CONFIG_RATE_CTRL
+        &cpi->encode_command,
+#endif
         &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx,
         &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames);
     use_alt_ref &= allow_alt_ref;
@@ -3670,12 +3697,13 @@
   }
 
   *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);
+      &cpi->encode_command, &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);
 }
 
-int vp9_get_gop_coding_frame_count(const VP9EncoderConfig *oxcf,
+int vp9_get_gop_coding_frame_count(const ENCODE_COMMAND *encode_command,
+                                   const VP9EncoderConfig *oxcf,
                                    const FRAME_INFO *frame_info,
                                    const FIRST_PASS_INFO *first_pass_info,
                                    const RATE_CONTROL *rc, int show_idx,
@@ -3698,6 +3726,9 @@
   }
 
   frame_count = get_gop_coding_frame_num(
+#if CONFIG_RATE_CTRL
+      encode_command,
+#endif
       use_alt_ref, frame_info, first_pass_info, rc, show_idx,
       &active_gf_interval, gop_intra_factor, oxcf->lag_in_frames);
   *use_alt_ref &= allow_alt_ref;
@@ -3706,7 +3737,8 @@
 
 // Under CONFIG_RATE_CTRL, once the first_pass_info is ready, the number of
 // coding frames (including show frame and alt ref) can be determined.
-int vp9_get_coding_frame_num(const VP9EncoderConfig *oxcf,
+int vp9_get_coding_frame_num(const ENCODE_COMMAND *encode_command,
+                             const VP9EncoderConfig *oxcf,
                              const FRAME_INFO *frame_info,
                              const FIRST_PASS_INFO *first_pass_info,
                              int multi_layer_arf, int allow_alt_ref) {
@@ -3730,8 +3762,9 @@
     }
 
     gop_coding_frame_count = vp9_get_gop_coding_frame_count(
-        oxcf, frame_info, first_pass_info, &rc, show_idx, multi_layer_arf,
-        allow_alt_ref, first_is_key_frame, last_gop_use_alt_ref, &use_alt_ref);
+        encode_command, oxcf, frame_info, first_pass_info, &rc, show_idx,
+        multi_layer_arf, allow_alt_ref, first_is_key_frame,
+        last_gop_use_alt_ref, &use_alt_ref);
 
     rc.source_alt_ref_active = use_alt_ref;
     last_gop_use_alt_ref = use_alt_ref;
@@ -3743,7 +3776,7 @@
   }
   return coding_frame_num;
 }
-#endif
+#endif  // CONFIG_RATE_CTRL
 
 FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass) {
   return twopass->this_frame_stats;
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -252,6 +252,14 @@
                                const FIRST_PASS_INFO *first_pass_info,
                                int kf_show_idx, int min_gf_interval);
 #if CONFIG_RATE_CTRL
+typedef struct ENCODE_COMMAND {
+  int use_external_quantize_index;
+  int external_quantize_index;
+  int use_external_arf;
+  // A list of binary flags set from the external controller.
+  // Each binary flag indicates whether the frame is an arf or not.
+  const int *external_arf_indexes;
+} ENCODE_COMMAND;
 
 /* Call this function to get info about the next group of pictures.
  * This function should be called after vp9_create_compressor() when encoding
@@ -265,6 +273,7 @@
 
 /*!\brief Call this function before coding a new group of pictures to get
  * information about it.
+ * \param[in] encode_command       Encode command
  * \param[in] oxcf                 Encoder config
  * \param[in] frame_info           Frame info
  * \param[in] first_pass_info      First pass stats
@@ -279,7 +288,8 @@
  *
  * \return Returns coding frame count
  */
-int vp9_get_gop_coding_frame_count(const struct VP9EncoderConfig *oxcf,
+int vp9_get_gop_coding_frame_count(const ENCODE_COMMAND *encode_command,
+                                   const struct VP9EncoderConfig *oxcf,
                                    const FRAME_INFO *frame_info,
                                    const FIRST_PASS_INFO *first_pass_info,
                                    const RATE_CONTROL *rc, int show_idx,
@@ -287,11 +297,12 @@
                                    int first_is_key_frame,
                                    int last_gop_use_alt_ref, int *use_alt_ref);
 
-int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf,
+int vp9_get_coding_frame_num(const ENCODE_COMMAND *encode_command,
+                             const struct VP9EncoderConfig *oxcf,
                              const FRAME_INFO *frame_info,
                              const FIRST_PASS_INFO *first_pass_info,
                              int multi_layer_arf, int allow_alt_ref);
-#endif
+#endif  // CONFIG_RATE_CTRL
 
 FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass);
 FIRSTPASS_STATS vp9_get_total_stats(const TWO_PASS *twopass);
--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -851,7 +851,8 @@
   FIRST_PASS_INFO first_pass_info;
   fps_init_first_pass_info(&first_pass_info, impl_ptr_->first_pass_stats.data(),
                            num_frames_);
-  return vp9_get_coding_frame_num(&oxcf, &frame_info, &first_pass_info,
+  return vp9_get_coding_frame_num(/*encode_command=*/nullptr, &oxcf,
+                                  &frame_info, &first_pass_info,
                                   multi_layer_arf, allow_alt_ref);
 }