]> granicus.if.org Git - libvpx/commitdiff
Dual ARF changes: Buffer index selection.
authorPaul Wilkins <paulwilkins@google.com>
Mon, 23 Jun 2014 12:07:24 +0000 (13:07 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Tue, 24 Jun 2014 15:30:44 +0000 (16:30 +0100)
Add indirection to the section of buffer indices.
This is to help simplify things in the future if we
have other codec features that switch indices.

Limit the max GF interval for static sections to fit
the gf_group structures.

Change-Id: I38310daaf23fd906004c0e8ee3e99e15570f84cb

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

index ed52999dd007bd2c74066ae522eb9498959d72ef..c69ed16a70bdbd98c53b5293d3a62a41e88b5bec 100644 (file)
@@ -904,8 +904,7 @@ static int get_refresh_mask(VP9_COMP *cpi) {
              (cpi->refresh_golden_frame << cpi->alt_fb_idx);
     } else {
       int arf_idx = cpi->alt_fb_idx;
-
-      if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
+      if (cpi->pass == 2) {
         const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
         arf_idx = gf_group->arf_update_idx[gf_group->index];
       }
index e917a4724f0fb0716966abf514655fdc5b2e0d3e..ca3946c284df4838b0da015c942b23a4d828b524 100644 (file)
@@ -1514,7 +1514,7 @@ void vp9_update_reference_frames(VP9_COMP *cpi) {
   } else { /* For non key/golden frames */
     if (cpi->refresh_alt_ref_frame) {
       int arf_idx = cpi->alt_fb_idx;
-      if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
+      if (cpi->pass == 2) {
         const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
         arf_idx = gf_group->arf_update_idx[gf_group->index];
       }
index f2e89b81911aae16c76187bc937227b26e96ec95..6fb263fd6c52b628b7a594f0f9b95f9501eb8f49 100644 (file)
@@ -1282,6 +1282,18 @@ static int calculate_boost_bits(int frame_count,
   return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0);
 }
 
+// Current limit on maximum number of active arfs in a GF/ARF group.
+#define MAX_ACTIVE_ARFS 2
+#define ARF_SLOT1 2
+#define ARF_SLOT2 3
+// This function indirects the choice of buffers for arfs.
+// At the moment the values are fixed but this may change as part of
+// the integration process with other codec features that swap buffers around.
+static void get_arf_buffer_indices(unsigned char *arf_buffer_indices) {
+  arf_buffer_indices[0] = ARF_SLOT1;
+  arf_buffer_indices[1] = ARF_SLOT2;
+}
+
 static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
                                    double group_error, int gf_arf_bits) {
   RATE_CONTROL *const rc = &cpi->rc;
@@ -1298,10 +1310,13 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
   double err_fraction;
   int mid_boost_bits = 0;
   int middle_frame_idx;
+  unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
 
   key_frame = cpi->common.frame_type == KEY_FRAME ||
               vp9_is_upper_layer_key_frame(cpi);
 
+  get_arf_buffer_indices(arf_buffer_indices);
+
   // For key frames the frame target rate is already set and it
   // is also the golden frame.
   if (!key_frame) {
@@ -1309,14 +1324,14 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
       twopass->gf_group.update_type[0] = OVERLAY_UPDATE;
       twopass->gf_group.rf_level[0] = INTER_NORMAL;
       twopass->gf_group.bit_allocation[0] = 0;
-      twopass->gf_group.arf_update_idx[0] = 2;
-      twopass->gf_group.arf_ref_idx[0] = 2;
+      twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0];
+      twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0];
     } else {
       twopass->gf_group.update_type[0] = GF_UPDATE;
       twopass->gf_group.rf_level[0] = GF_ARF_STD;
       twopass->gf_group.bit_allocation[0] = gf_arf_bits;
-      twopass->gf_group.arf_update_idx[0] = 2;
-      twopass->gf_group.arf_ref_idx[0] = 2;
+      twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0];
+      twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0];
     }
 
     // Step over the golden frame / overlay frame
@@ -1331,18 +1346,20 @@ 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) {
-    // 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);
+    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;
     twopass->gf_group.arf_src_offset[frame_index] =
       (unsigned char)(rc->baseline_gf_interval - 1);
-    twopass->gf_group.arf_update_idx[frame_index] = 2;
-    twopass->gf_group.arf_ref_idx[frame_index] = 2;
+    twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0];
+    twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
     ++frame_index;
 
     if (cpi->multi_arf_enabled) {
@@ -1351,8 +1368,8 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
       twopass->gf_group.rf_level[frame_index] = GF_ARF_LOW;
       twopass->gf_group.arf_src_offset[frame_index] =
         (unsigned char)((rc->baseline_gf_interval >> 1) - 1);
-      twopass->gf_group.arf_update_idx[frame_index] = 3;
-      twopass->gf_group.arf_ref_idx[frame_index] = 2;
+      twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[1];
+      twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
       ++frame_index;
     }
   }
@@ -1362,6 +1379,7 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
 
   // Allocate bits to the other frames in the group.
   for (i = 0; i < rc->baseline_gf_interval - 1; ++i) {
+    int arf_idx = 0;
     if (EOF == input_stats(twopass, &frame_stats))
       break;
 
@@ -1378,17 +1396,11 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
       mid_boost_bits += (target_frame_size >> 4);
       target_frame_size -= (target_frame_size >> 4);
 
-      if (frame_index <= middle_frame_idx) {
-        twopass->gf_group.arf_update_idx[frame_index] = 3;
-        twopass->gf_group.arf_ref_idx[frame_index] = 3;
-      } else {
-        twopass->gf_group.arf_update_idx[frame_index] = 2;
-        twopass->gf_group.arf_ref_idx[frame_index] = 2;
-      }
-    } else {
-      twopass->gf_group.arf_update_idx[frame_index] = 2;
-      twopass->gf_group.arf_ref_idx[frame_index] = 2;
+      if (frame_index <= middle_frame_idx)
+        arf_idx = 1;
     }
+    twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[arf_idx];
+    twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[arf_idx];
 
     target_frame_size = clamp(target_frame_size, 0,
                               MIN(max_bits, (int)total_group_bits));
@@ -1400,23 +1412,27 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
     ++frame_index;
   }
 
+  // Note:
+  // We need to configure the frame at the end of the sequence + 1 that will be
+  // the start frame for the next group. Otherwise prior to the call to
+  // vp9_rc_get_second_pass_params() the data will be undefined.
+  twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0];
+  twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
+
   if (rc->source_alt_ref_pending) {
+    twopass->gf_group.update_type[frame_index] = OVERLAY_UPDATE;
+    twopass->gf_group.rf_level[frame_index] = INTER_NORMAL;
+
+    // Final setup for second arf and its overlay.
     if (cpi->multi_arf_enabled) {
       twopass->gf_group.bit_allocation[2] =
         twopass->gf_group.bit_allocation[middle_frame_idx] + mid_boost_bits;
       twopass->gf_group.update_type[middle_frame_idx] = OVERLAY_UPDATE;
       twopass->gf_group.bit_allocation[middle_frame_idx] = 0;
     }
-
-    // Configure the overlay frame at the end of the sequence that will also
-    // be the start frame of the next group. The reason for doing this here
-    // is that on entry to vp9_get_compressed_data() for the overlay
-    // frame, but before the call to vp9_rc_get_second_pass_params() the
-    // data will otherwise be undefined.
-    twopass->gf_group.update_type[frame_index] = OVERLAY_UPDATE;
-    twopass->gf_group.rf_level[frame_index] = INTER_NORMAL;
-    twopass->gf_group.arf_update_idx[frame_index] = 2;
-    twopass->gf_group.arf_ref_idx[frame_index] = 2;
+  } else {
+    twopass->gf_group.update_type[frame_index] = GF_UPDATE;
+    twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
   }
 }
 
index 61268ff57e84950c4bf59cfed239dd80b6b1fc2e..1ee56a3a700fae458cfc2d64bd4c6ab01dfb22c4 100644 (file)
@@ -51,12 +51,12 @@ typedef enum {
 
 typedef struct {
   unsigned char index;
-  RATE_FACTOR_LEVEL rf_level[MAX_LAG_BUFFERS * 2];
-  FRAME_UPDATE_TYPE update_type[MAX_LAG_BUFFERS * 2];
-  unsigned char arf_src_offset[MAX_LAG_BUFFERS * 2];
-  unsigned char arf_update_idx[MAX_LAG_BUFFERS * 2];
-  unsigned char arf_ref_idx[MAX_LAG_BUFFERS * 2];
-  int bit_allocation[MAX_LAG_BUFFERS * 2];
+  RATE_FACTOR_LEVEL rf_level[(MAX_LAG_BUFFERS * 2) + 1];
+  FRAME_UPDATE_TYPE update_type[(MAX_LAG_BUFFERS * 2) + 1];
+  unsigned char arf_src_offset[(MAX_LAG_BUFFERS * 2) + 1];
+  unsigned char arf_update_idx[(MAX_LAG_BUFFERS * 2) + 1];
+  unsigned char arf_ref_idx[(MAX_LAG_BUFFERS * 2) + 1];
+  int bit_allocation[(MAX_LAG_BUFFERS * 2) + 1];
 } GF_GROUP;
 
 typedef struct {
index c39d90b2234eecfc0936cd43352a402b5ad8f6cc..e1109838c7212966c5496ba21649a64715564650 100644 (file)
@@ -1356,6 +1356,8 @@ void vp9_rc_set_gf_max_interval(const VP9EncoderConfig *const oxcf,
 
   // Extended interval for genuinely static scenes
   rc->static_scene_max_gf_interval = oxcf->key_freq >> 1;
+  if (rc->static_scene_max_gf_interval > (MAX_LAG_BUFFERS * 2))
+    rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2;
 
   if (is_altref_enabled(oxcf)) {
     if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1)