Prepare multi-layer ARF coding structure
authorJingning Han <jingning@google.com>
Thu, 23 Aug 2018 17:18:53 +0000 (10:18 -0700)
committerJingning Han <jingning@google.com>
Fri, 31 Aug 2018 16:26:02 +0000 (09:26 -0700)
Build the frame processing order and type queue for multi-layer
ARF coding structure.

Change-Id: I5e14c60279020dc65a883d2997ca1ca9ce739488

vp9/encoder/vp9_firstpass.c

index 917f0f5..876a2fb 100644 (file)
@@ -2333,30 +2333,40 @@ static void define_gf_multi_arf_structure(VP9_COMP *cpi) {
   gf_group->brf_src_offset[frame_index] = 0;
 }
 
-static void init_arf_order(int *stack, int *layer_depth) {
-  int idx;
-  for (idx = 0; idx < MAX_LAG_BUFFERS; ++idx) {
-    stack[idx] = -1;
-    layer_depth[idx] = 0;
+static void find_arf_order(GF_GROUP *gf_group, int *layer_depth,
+                           int *index_counter, int depth, int start, int end) {
+  const int mid = (start + end + 1) >> 1;
+  const int min_frame_interval = 3;
+
+  // Process regular P frames
+  if (end - start <= min_frame_interval) {
+    int idx;
+    for (idx = start; idx < end; ++idx) {
+      gf_group->update_type[*index_counter] = LF_UPDATE;
+      gf_group->arf_src_offset[*index_counter] = 0;
+      gf_group->rf_level[*index_counter] = INTER_NORMAL;
+      ++(*index_counter);
+    }
+    return;
   }
-}
 
-static void find_arf_order(int *stack, int *layer_depth, int *index_counter,
-                           int *stack_size, int depth, int start, int end) {
-  int mid = (start + end + 1) >> 1;
-  if (end - start < 3) return;
+  assert(abs(mid - start) > 1 && abs(mid - end) > 1);
 
-  if (abs(mid - start) > 1 && abs(mid - end) > 1) {
-    stack_push(stack, mid, *stack_size);
-    ++(*stack_size);
-    layer_depth[*index_counter] = depth;
-    ++(*index_counter);
-  }
+  // Process ARF frame
+  layer_depth[*index_counter] = depth;
+  gf_group->update_type[*index_counter] = ARF_UPDATE;
+  gf_group->arf_src_offset[*index_counter] = mid;
+  gf_group->rf_level[*index_counter] = GF_ARF_LOW;
+  ++(*index_counter);
+
+  find_arf_order(gf_group, layer_depth, index_counter, depth + 1, start, mid);
+
+  gf_group->update_type[*index_counter] = USE_BUF_FRAME;
+  gf_group->arf_src_offset[*index_counter] = 0;
+  gf_group->rf_level[*index_counter] = INTER_NORMAL;
+  ++(*index_counter);
 
-  find_arf_order(stack, layer_depth, index_counter, stack_size, depth + 1,
-                 start, mid);
-  find_arf_order(stack, layer_depth, index_counter, stack_size, depth + 1, mid,
-                 end);
+  find_arf_order(gf_group, layer_depth, index_counter, depth + 1, mid + 1, end);
 }
 
 static void define_gf_group_structure(VP9_COMP *cpi) {
@@ -2369,12 +2379,7 @@ static void define_gf_group_structure(VP9_COMP *cpi) {
   int mid_frame_idx;
   unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
   int normal_frames;
-  int arf_order[MAX_LAG_BUFFERS];
   int layer_depth[MAX_LAG_BUFFERS];
-  int index_counter = 0;
-  int stack_size = 0;
-
-  init_arf_order(arf_order, layer_depth);
 
   key_frame = cpi->common.frame_type == KEY_FRAME;
 
@@ -2421,17 +2426,26 @@ static void define_gf_group_structure(VP9_COMP *cpi) {
       gf_group->arf_ref_idx[frame_index] = arf_buffer_indices[0];
       ++frame_index;
     }
+  }
+
+  if (rc->source_alt_ref_pending && cpi->multi_layer_arf) {
+    layer_depth[frame_index] = 1;
 
-    stack_push(arf_order, gf_group->arf_src_offset[1], stack_size);
-    ++stack_size;
-    layer_depth[index_counter] = 1;
-    ++index_counter;
-    find_arf_order(arf_order, layer_depth, &index_counter, &stack_size, 2, 0,
+    find_arf_order(gf_group, layer_depth, &frame_index, 2, 0,
                    rc->baseline_gf_interval - 1);
-  }
 
-  (void)arf_order;
-  (void)layer_depth;
+    if (rc->source_alt_ref_pending) {
+      gf_group->update_type[frame_index] = OVERLAY_UPDATE;
+      gf_group->rf_level[frame_index] = INTER_NORMAL;
+    } else {
+      gf_group->update_type[frame_index] = GF_UPDATE;
+      gf_group->rf_level[frame_index] = GF_ARF_STD;
+    }
+
+    (void)layer_depth;
+
+    return;
+  }
 
   // Note index of the first normal inter frame int eh group (not gf kf arf)
   gf_group->first_inter_index = frame_index;
@@ -2441,6 +2455,7 @@ static void define_gf_group_structure(VP9_COMP *cpi) {
 
   normal_frames =
       rc->baseline_gf_interval - (key_frame || rc->source_alt_ref_pending);
+
   for (i = 0; i < normal_frames; ++i) {
     int arf_idx = 0;
     if (twopass->stats_in >= twopass->stats_in_end) break;