shithub: libvpx

Download patch

ref: 9c46931645db1ef28f4f4577a1c222d9432ff148
parent: b7e03724b3afb83d8bb7e19bbf0fc8ccdcc1b3b6
parent: 38a4e46fd3029c903e124c9f47e88063eb7a4018
author: Angie Chiang <angiebird@google.com>
date: Mon Dec 9 17:15:50 EST 2019

Merge changes I41ff04bb,I3d88d719

* changes:
  Set frames_since_key in vp9_get_coding_frame_num
  Add vp9_get_gop_coding_frame_count()

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2458,6 +2458,22 @@
   int max;
 } RANGE;
 
+/* get_gop_coding_frame_num() depends on several fields in RATE_CONTROL *rc as
+ * follows.
+ * Static fields:
+ * (The following fields will remain unchanged after initialization of encoder.)
+ *   rc->static_scene_max_gf_interval
+ *   rc->min_gf_interval
+ *
+ * Dynamic fields:
+ * (The following fields will be updated before or after coding each frame.)
+ *   rc->frames_to_key
+ *   rc->frames_since_key
+ *   rc->source_alt_ref_active
+ *
+ * TODO(angiebird): Separate the dynamic fields and static fields into two
+ * structs.
+ */
 static int get_gop_coding_frame_num(
     int *use_alt_ref, const FRAME_INFO *frame_info,
     const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc,
@@ -3627,56 +3643,66 @@
 }
 
 #if CONFIG_RATE_CTRL
+int vp9_get_gop_coding_frame_count(
+    int *use_alt_ref, const VP9EncoderConfig *oxcf,
+    const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info,
+    const RATE_CONTROL *rc, int show_idx, int multi_layer_arf,
+    int allow_alt_ref, int first_is_key_frame, int last_gop_use_alt_ref) {
+  int frame_count;
+  double gop_intra_factor;
+  const int arf_active_or_kf = last_gop_use_alt_ref || first_is_key_frame;
+  RANGE active_gf_interval = get_active_gf_inverval_range(
+      frame_info, rc, arf_active_or_kf, show_idx, /*active_worst_quality=*/0,
+      /*last_boosted_qindex=*/0);
+
+  const int arf_layers = get_arf_layers(multi_layer_arf, oxcf->enable_auto_arf,
+                                        active_gf_interval.max);
+  if (multi_layer_arf) {
+    gop_intra_factor = 1.0 + 0.25 * arf_layers;
+  } else {
+    gop_intra_factor = 1.0;
+  }
+
+  frame_count = get_gop_coding_frame_num(
+      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;
+  return frame_count;
+}
+
 // 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 struct VP9EncoderConfig *oxcf,
+int vp9_get_coding_frame_num(const VP9EncoderConfig *oxcf,
                              const FRAME_INFO *frame_info,
                              const FIRST_PASS_INFO *first_pass_info,
                              int multi_layer_arf, int allow_alt_ref) {
   int coding_frame_num = 0;
   RATE_CONTROL rc;
-  RANGE active_gf_interval;
-  int arf_layers;
-  double gop_intra_factor;
-  int use_alt_ref;
-  int gop_coding_frames;
+  int gop_coding_frame_count;
   int gop_show_frames;
   int show_idx = 0;
-  int arf_active_or_kf = 1;
+  int last_gop_use_alt_ref = 0;
   rc.static_scene_max_gf_interval = 250;
   vp9_rc_init(oxcf, 1, &rc);
 
   while (show_idx < first_pass_info->num_frames) {
+    int use_alt_ref;
+    int first_is_key_frame = 0;
     if (rc.frames_to_key == 0) {
       rc.frames_to_key = vp9_get_frames_to_next_key(
           oxcf, frame_info, first_pass_info, show_idx, rc.min_gf_interval);
-      arf_active_or_kf = 1;
-    } else {
+      rc.frames_since_key = 0;
+      first_is_key_frame = 1;
     }
 
-    {
-      int dummy = 0;
-      active_gf_interval = get_active_gf_inverval_range(
-          frame_info, &rc, arf_active_or_kf, show_idx, dummy, dummy);
-    }
+    gop_coding_frame_count = vp9_get_gop_coding_frame_count(
+        &use_alt_ref, oxcf, frame_info, first_pass_info, &rc, show_idx,
+        multi_layer_arf, allow_alt_ref, first_is_key_frame,
+        last_gop_use_alt_ref);
 
-    arf_layers = get_arf_layers(multi_layer_arf, oxcf->enable_auto_arf,
-                                active_gf_interval.max);
-    if (multi_layer_arf) {
-      gop_intra_factor = 1.0 + 0.25 * arf_layers;
-    } else {
-      gop_intra_factor = 1.0;
-    }
-
-    gop_coding_frames = get_gop_coding_frame_num(
-        &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;
-
     rc.source_alt_ref_active = use_alt_ref;
-    arf_active_or_kf = use_alt_ref;
-    gop_show_frames = gop_coding_frames - use_alt_ref;
+    last_gop_use_alt_ref = use_alt_ref;
+    gop_show_frames = gop_coding_frame_count - use_alt_ref;
     rc.frames_to_key -= gop_show_frames;
     rc.frames_since_key += gop_show_frames;
     show_idx += gop_show_frames;
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -252,6 +252,28 @@
                                const FIRST_PASS_INFO *first_pass_info,
                                int kf_show_idx, int min_gf_interval);
 #if CONFIG_RATE_CTRL
+/*!\brief Call this function before coding a new group of pictures to get
+ * information about it.
+ * \param[in] oxcf                 Encoder config
+ * \param[in] frame_info           Frame info
+ * \param[in] first_pass_info      First pass stats
+ * \param[in] rc                   Rate control state
+ * \param[in] show_idx             Show index of the first frame in the group
+ * \param[in] multi_layer_arf      Is multi-layer alternate reference used
+ * \param[in] allow_alt_ref        Is alternate reference allowed
+ * \param[in] first_is_key_frame   Is the first frame in the group a key frame
+ * \param[in] last_gop_use_alt_ref Does the last group use alternate reference
+ *
+ * \param[out] use_alt_ref         Does this group use alternate reference
+ *
+ * \return Returns coding frame count
+ */
+int vp9_get_gop_coding_frame_count(
+    int *use_alt_ref, const struct VP9EncoderConfig *oxcf,
+    const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info,
+    const RATE_CONTROL *rc, int show_idx, int multi_layer_arf,
+    int allow_alt_ref, int first_is_key_frame, int last_gop_use_alt_ref);
+
 int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf,
                              const FRAME_INFO *frame_info,
                              const FIRST_PASS_INFO *first_pass_info,