]> granicus.if.org Git - libvpx/commitdiff
Multi-arf: Add code to turn it on and off.
authorPaul Wilkins <paulwilkins@google.com>
Mon, 30 Jun 2014 09:35:00 +0000 (10:35 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Wed, 2 Jul 2014 16:53:23 +0000 (17:53 +0100)
Add test code to turn multi-arf on and off depending
on group length and zero motion.

Changes to active max group length for mult-arf.

Fund second arf only from normal frame bits.

Change-Id: I920287fac1c886428c15a39f731a25d07c2b796c

vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_encoder.h
vp9/encoder/vp9_firstpass.c

index 4f17a15a9c9450e4e1c5ca5f3e15164396e7b5ad..897edbb9f89560168b43dfe041a675dd40e0daa1 100644 (file)
@@ -790,6 +790,7 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
   // For the current check in all the execution paths are defaulted to 0
   // pending further tuning and testing. The code is left in place here
   // as a place holder in regard to the required paths.
+  cpi->multi_arf_last_grp_enabled = 0;
   if (cpi->pass == 2) {
     if (cpi->use_svc) {
       cpi->multi_arf_allowed = 0;
index b38f9c2460f02897110d7afcb3fe4aa53c612f80..6f6c3bb300f007911e518be00ac9089819c7bba5 100644 (file)
@@ -428,6 +428,7 @@ typedef struct VP9_COMP {
 
   int multi_arf_allowed;
   int multi_arf_enabled;
+  int multi_arf_last_grp_enabled;
 
 #if CONFIG_DENOISING
   VP9_DENOISER denoiser;
index f90c9df5e26274a8823223f5a2de37c4f82dd8c0..b025559319035d4899729856af882704d67c2caf 100644 (file)
@@ -1407,13 +1407,6 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
 
   // Store the bits to spend on the ARF if there is one.
   if (rc->source_alt_ref_pending) {
-    if (cpi->multi_arf_enabled) {
-      // A portion of the gf / arf extra bits are set asside for lower level
-      // boosted frames in the middle of the group.
-      mid_boost_bits += gf_arf_bits >> 5;
-      gf_arf_bits -= (gf_arf_bits >> 5);
-    }
-
     twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
     twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
     twopass->gf_group.bit_allocation[frame_index] = gf_arf_bits;
@@ -1421,7 +1414,8 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
       (unsigned char)(rc->baseline_gf_interval - 1);
     twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0];
     twopass->gf_group.arf_ref_idx[frame_index] =
-      arf_buffer_indices[cpi->multi_arf_enabled && rc->source_alt_ref_active];
+      arf_buffer_indices[cpi->multi_arf_last_grp_enabled &&
+                         rc->source_alt_ref_active];
     ++frame_index;
 
     if (cpi->multi_arf_enabled) {
@@ -1496,6 +1490,9 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
     twopass->gf_group.update_type[frame_index] = GF_UPDATE;
     twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
   }
+
+  // Note whether multi-arf was enabled this group for next time.
+  cpi->multi_arf_last_grp_enabled = cpi->multi_arf_enabled;
 }
 
 // Analyse and define a gf/arf group.
@@ -1560,18 +1557,21 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   // Motion breakout threshold for loop below depends on image size.
   mv_ratio_accumulator_thresh = (cpi->common.width + cpi->common.height) / 10.0;
 
-  // Work out a maximum interval for the GF.
-  // If the image appears completely static we can extend beyond this.
-  // The value chosen depends on the active Q range. At low Q we have
-  // bits to spare and are better with a smaller interval and smaller boost.
-  // At high Q when there are few bits to spare we are better with a longer
-  // interval to spread the cost of the GF.
-  //
-  active_max_gf_interval =
-    12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5);
-
-  if (active_max_gf_interval > rc->max_gf_interval)
+  // Work out a maximum interval for the GF group.
+  // If the image appears almost completely static we can extend beyond this.
+  if (cpi->multi_arf_allowed) {
     active_max_gf_interval = rc->max_gf_interval;
+  } else {
+   // The value chosen depends on the active Q range. At low Q we have
+   // bits to spare and are better with a smaller interval and smaller boost.
+   // At high Q when there are few bits to spare we are better with a longer
+   // interval to spread the cost of the GF.
+   active_max_gf_interval =
+     12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5);
+
+   if (active_max_gf_interval > rc->max_gf_interval)
+     active_max_gf_interval = rc->max_gf_interval;
+  }
 
   i = 0;
   while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
@@ -1679,6 +1679,10 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
                                    &b_boost);
     rc->source_alt_ref_pending = 1;
 
+    // Test to see if multi arf is appropriate.
+    cpi->multi_arf_enabled =
+      (cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) &&
+      (zero_motion_accumulator < 0.995)) ? 1 : 0;
   } else {
     rc->gfu_boost = (int)boost_score;
     rc->source_alt_ref_pending = 0;
@@ -1838,8 +1842,10 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   // Is this a forced key frame by interval.
   rc->this_key_frame_forced = rc->next_key_frame_forced;
 
-  // Clear the alt ref active flag as this can never be active on a key frame.
+  // Clear the alt ref active flag and last group multi arf flags as they
+  // can never be set for a key frame.
   rc->source_alt_ref_active = 0;
+  cpi->multi_arf_last_grp_enabled = 0;
 
   // KF is always a GF so clear frames till next gf counter.
   rc->frames_till_gf_update_due = 0;