]> granicus.if.org Git - libvpx/commitdiff
Build arf index stack
authorJingning Han <jingning@google.com>
Sun, 26 Aug 2018 04:39:59 +0000 (21:39 -0700)
committerJingning Han <jingning@google.com>
Sat, 1 Sep 2018 03:48:33 +0000 (20:48 -0700)
Stack the ARF frame indexes. Use the most recent one as the ARF
reference frame for frame coding.

Change-Id: I88a2202fa5deb2587d861b434d27ab8de0642cf7

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

index 79fc160c12cf658eb7413339e196d0258c6b9111..21a68bf398cc396313515fbf6b4d71531cfaf27b 100644 (file)
@@ -909,10 +909,25 @@ int vp9_get_refresh_mask(VP9_COMP *cpi) {
            (cpi->refresh_golden_frame << cpi->alt_fb_idx);
   } else {
     int arf_idx = cpi->alt_fb_idx;
+    GF_GROUP *const gf_group = &cpi->twopass.gf_group;
     if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
       const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
       arf_idx = gf_group->arf_update_idx[gf_group->index];
     }
+
+    if (cpi->multi_layer_arf) {
+      for (arf_idx = 0; arf_idx < REF_FRAMES; ++arf_idx) {
+        if (arf_idx != cpi->alt_fb_idx && arf_idx != cpi->lst_fb_idx &&
+            arf_idx != cpi->gld_fb_idx) {
+          int idx;
+          for (idx = 0; idx < gf_group->stack_size; ++idx)
+            if (arf_idx == gf_group->arf_index_stack[idx]) break;
+          if (idx == gf_group->stack_size) break;
+        }
+      }
+    }
+    cpi->twopass.gf_group.top_arf_idx = arf_idx;
+
     if (cpi->use_svc && cpi->svc.use_set_ref_frame_config &&
         cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS)
       return cpi->svc.update_buffer_slot[cpi->svc.spatial_layer_id];
index c4efd99544588a68182d7729def8a2aa5f73398e..7f9f2c5d55543adc84dcbad7a1dc019feef829f4 100644 (file)
@@ -3169,6 +3169,15 @@ void update_multi_arf_ref_frames(VP9_COMP *cpi) {
 void update_ref_frames(VP9_COMP *cpi) {
   VP9_COMMON *const cm = &cpi->common;
   BufferPool *const pool = cm->buffer_pool;
+  GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+
+  // Pop ARF.
+  if (cm->show_existing_frame) {
+    cpi->lst_fb_idx = cpi->alt_fb_idx;
+    cpi->alt_fb_idx =
+        stack_pop(gf_group->arf_index_stack, gf_group->stack_size);
+    --gf_group->stack_size;
+  }
 
   // At this point the new frame has been encoded.
   // If any buffer copy / swapping is signaled it should be done here.
@@ -3196,16 +3205,25 @@ void update_ref_frames(VP9_COMP *cpi) {
     cpi->gld_fb_idx = tmp;
   } else { /* For non key/golden frames */
     if (cpi->refresh_alt_ref_frame) {
-      int arf_idx = cpi->alt_fb_idx;
+      int arf_idx = gf_group->top_arf_idx;
       if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
         const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
         arf_idx = gf_group->arf_update_idx[gf_group->index];
       }
 
+      // Push new ARF into stack.
+      stack_push(gf_group->arf_index_stack, cpi->alt_fb_idx,
+                 gf_group->stack_size);
+      ++gf_group->stack_size;
+
+      assert(arf_idx < REF_FRAMES);
+
       ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
       memcpy(cpi->interp_filter_selected[ALTREF_FRAME],
              cpi->interp_filter_selected[0],
              sizeof(cpi->interp_filter_selected[0]));
+
+      cpi->alt_fb_idx = arf_idx;
     }
 
     if (cpi->refresh_golden_frame) {
@@ -6091,9 +6109,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
     }
   }
 
+  // Clear arf index stack before group of pictures processing starts.
+  if (cpi->twopass.gf_group.index == 1) {
+    stack_init(cpi->twopass.gf_group.arf_index_stack, MAX_LAG_BUFFERS * 2);
+    cpi->twopass.gf_group.stack_size = 0;
+  }
+
   if (arf_src_index) {
     assert(arf_src_index <= rc->frames_to_key);
-
     if ((source = vp9_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) {
       cpi->alt_ref_source = source;
 
index 9adcb4522a7de262acfd23e4f66c9c53f003188d..446e030ba08d99fb0decccbb5ef969a5a5ce5748 100644 (file)
@@ -834,6 +834,11 @@ static INLINE void stack_push(int *stack, int new_item, int stack_size) {
   stack[0] = new_item;
 }
 
+static INLINE void stack_init(int *stack, int length) {
+  int idx;
+  for (idx = 0; idx < length; ++idx) stack[idx] = -1;
+}
+
 int vp9_get_quantizer(struct VP9_COMP *cpi);
 
 static INLINE int frame_is_kf_gf_arf(const VP9_COMP *cpi) {
index 0a7e1adf7d9ac5d2d4e79c2a5d856b3b8e09d402..e1c882df493cdfbb917595ae48557d33eb732cc0 100644 (file)
@@ -143,6 +143,11 @@ typedef struct {
   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];
+
+  // TODO(jingning): The array size of arf_stack could be reduced.
+  int arf_index_stack[MAX_LAG_BUFFERS * 2];
+  int top_arf_idx;
+  int stack_size;
 } GF_GROUP;
 
 typedef struct {