shithub: libvpx

Download patch

ref: bf3f26a93548b37c186d9be7ac2108f4dbcd60c1
parent: c929797b683bb12dbbd4440d83c4e6befa15259d
author: Jingning Han <jingning@google.com>
date: Fri Aug 31 11:54:10 EDT 2018

Adaptive ARF factor decision

Re-count the factors to decide bit boost factor for the
intermediate layer ARFs. Make the gfu_boost factor assigned to
each ARF adapt to its local factors.

This and the recursive change 5bfe9eb together improves the
multi-layer ARF compression performance:

          avg_psnr      ovr_psnr     ssim
lowres    -0.39%        -0.54%       -1.6%
midres    -0.98%        -1.26%       -2.3%
hdres     -0.95%        -1.13%       -2.3%

Change-Id: I5fec3ea75cae58825787dc88dadc7e8697a041ea

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2333,10 +2333,14 @@
   gf_group->brf_src_offset[frame_index] = 0;
 }
 
-static void find_arf_order(GF_GROUP *gf_group, int *index_counter, int depth,
-                           int start, int end) {
+static void find_arf_order(VP9_COMP *cpi, GF_GROUP *gf_group,
+                           int *index_counter, int depth, int start, int end) {
+  TWO_PASS *twopass = &cpi->twopass;
+  const FIRSTPASS_STATS *const start_pos = twopass->stats_in;
+  FIRSTPASS_STATS fpf_frame;
   const int mid = (start + end) >> 1;
   const int min_frame_interval = 3;
+  int idx;
 
   // Process regular P frames
   if (end - start < min_frame_interval) {
@@ -2358,9 +2362,18 @@
   gf_group->update_type[*index_counter] = ARF_UPDATE;
   gf_group->arf_src_offset[*index_counter] = mid - start;
   gf_group->rf_level[*index_counter] = GF_ARF_LOW;
+
+  for (idx = 0; idx <= mid; ++idx)
+    if (EOF == input_stats(twopass, &fpf_frame)) break;
+
+  gf_group->gfu_boost[*index_counter] = VPXMAX(
+      MIN_ARF_GF_BOOST, calc_arf_boost(cpi, end - mid, mid - start) >> depth);
+
+  reset_fpf_position(twopass, start_pos);
+
   ++(*index_counter);
 
-  find_arf_order(gf_group, index_counter, depth + 1, start, mid);
+  find_arf_order(cpi, gf_group, index_counter, depth + 1, start, mid);
 
   gf_group->update_type[*index_counter] = USE_BUF_FRAME;
   gf_group->arf_src_offset[*index_counter] = 0;
@@ -2368,7 +2381,7 @@
   gf_group->layer_depth[*index_counter] = depth;
   ++(*index_counter);
 
-  find_arf_order(gf_group, index_counter, depth + 1, mid + 1, end);
+  find_arf_order(cpi, gf_group, index_counter, depth + 1, mid + 1, end);
 }
 
 static int define_gf_group_structure(VP9_COMP *cpi) {
@@ -2432,7 +2445,8 @@
   if (rc->source_alt_ref_pending && cpi->multi_layer_arf) {
     gf_group->layer_depth[frame_index] = 1;
 
-    find_arf_order(gf_group, &frame_index, 2, 0, rc->baseline_gf_interval - 1);
+    find_arf_order(cpi, gf_group, &frame_index, 2, 0,
+                   rc->baseline_gf_interval - 1);
 
     if (rc->source_alt_ref_pending) {
       gf_group->update_type[frame_index] = OVERLAY_UPDATE;
@@ -2702,36 +2716,29 @@
   else
     normal_frame_bits = (int)total_group_bits;
 
+  gf_group->gfu_boost[1] = rc->gfu_boost;
+
   if (cpi->multi_layer_arf) {
     int idx;
-    int arf_depth_bits[10] = { 0 };
-    int arf_depth_counts[10] = { 0 };
+    int arf_depth_bits[MAX_ARF_LAYERS] = { 0 };
+    int arf_depth_count[MAX_ARF_LAYERS] = { 0 };
+    int arf_depth_boost[MAX_ARF_LAYERS] = { 0 };
     int total_arfs = 1;  // Account for the base layer ARF.
-    int arf_boost_factor = 0;
-    int arf_group_bits;
 
-    for (idx = frame_index; idx < gop_frames; ++idx) {
-      if (gf_group->update_type[idx] == ARF_UPDATE)
-        ++arf_depth_counts[gf_group->layer_depth[idx]];
+    for (idx = 0; idx < gop_frames; ++idx) {
+      if (gf_group->update_type[idx] == ARF_UPDATE) {
+        arf_depth_boost[gf_group->layer_depth[idx]] += gf_group->gfu_boost[idx];
+        ++arf_depth_count[gf_group->layer_depth[idx]];
+      }
     }
 
-    for (idx = 2; idx < 10; ++idx) {
-      int depth_boost_factor =
-          VPXMAX(MIN_ARF_GF_BOOST, rc->gfu_boost >> (idx + 1));
+    for (idx = 2; idx < MAX_ARF_LAYERS; ++idx) {
+      if (arf_depth_boost[idx] == 0) break;
+      arf_depth_bits[idx] = calculate_boost_bits(
+          rc->baseline_gf_interval, arf_depth_boost[idx], total_group_bits);
 
-      if (arf_depth_counts[idx] == 0) break;
-
-      arf_boost_factor = depth_boost_factor * arf_depth_counts[idx];
-
-      arf_group_bits =
-          calculate_boost_bits(rc->baseline_gf_interval - total_arfs,
-                               arf_boost_factor, total_group_bits);
-
-      arf_depth_bits[idx] = (arf_group_bits + (arf_depth_counts[idx] >> 1)) /
-                            arf_depth_counts[idx];
-
-      total_group_bits -= arf_group_bits;
-      total_arfs += arf_depth_counts[idx];
+      total_group_bits -= arf_depth_bits[idx];
+      total_arfs += arf_depth_count[idx];
     }
 
     // offset the base layer arf
@@ -2750,7 +2757,9 @@
       switch (gf_group->update_type[idx]) {
         case ARF_UPDATE:
           gf_group->bit_allocation[idx] =
-              arf_depth_bits[gf_group->layer_depth[idx]];
+              (int)((arf_depth_bits[gf_group->layer_depth[idx]] *
+                     gf_group->gfu_boost[idx]) /
+                    arf_depth_boost[gf_group->layer_depth[idx]]);
           break;
         case USE_BUF_FRAME: gf_group->bit_allocation[idx] = 0; break;
         default: gf_group->bit_allocation[idx] = target_frame_size; break;
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -49,6 +49,7 @@
 #define BFG_INTERVAL 2
 #define MAX_EXT_ARFS 2
 #define MIN_EXT_ARF_INTERVAL 4
+#define MAX_ARF_LAYERS 6
 
 typedef struct {
   double frame_mb_intra_factor;
@@ -144,6 +145,7 @@
   unsigned char brf_src_offset[MAX_STATIC_GF_GROUP_LENGTH + 2];
   unsigned char bidir_pred_enabled[MAX_STATIC_GF_GROUP_LENGTH + 2];
   int bit_allocation[MAX_STATIC_GF_GROUP_LENGTH + 2];
+  int gfu_boost[MAX_STATIC_GF_GROUP_LENGTH + 2];
 
   // TODO(jingning): The array size of arf_stack could be reduced.
   int arf_index_stack[MAX_LAG_BUFFERS * 2];