[svc rc] RC improvement for key frames in upper layers for spatial svc.
authorMinghai Shang <minghai@google.com>
Thu, 24 Apr 2014 20:31:46 +0000 (13:31 -0700)
committerMinghai Shang <minghai@google.com>
Wed, 30 Apr 2014 22:12:55 +0000 (15:12 -0700)
Change-Id: Id6ab59e505be28cd4eb9f1fe114feb47debe0539

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

index 8f32494..563f026 100644 (file)
@@ -592,7 +592,8 @@ static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer(
 // alt ref frames tend to be coded at a higher than ambient quality
 static INLINE int frame_is_boosted(const VP9_COMP *cpi) {
   return frame_is_intra_only(&cpi->common) || cpi->refresh_alt_ref_frame ||
-         (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref);
+         (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref) ||
+         vp9_is_upper_layer_key_frame(cpi);
 }
 
 static INLINE int get_token_alloc(int mb_rows, int mb_cols) {
index 3d4b962..a943023 100644 (file)
@@ -1727,8 +1727,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
       twopass->gf_bits = gf_bits;
     }
     if (i == 1 ||
-        (!rc->source_alt_ref_pending &&
-         cpi->common.frame_type != KEY_FRAME)) {
+        (!rc->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME &&
+         !vp9_is_upper_layer_key_frame(cpi))) {
       // Calculate the per frame bit target for this frame.
       vp9_rc_set_frame_target(cpi, gf_bits);
     }
@@ -2290,11 +2290,16 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
     this_frame_copy = this_frame;
     find_next_key_frame(cpi, &this_frame_copy);
     // Don't place key frame in any enhancement layers in spatial svc
-    if (cpi->use_svc && cpi->svc.number_temporal_layers == 1 &&
-        cpi->svc.spatial_layer_id > 0) {
-      cm->frame_type = INTER_FRAME;
+    if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
+      lc->is_key_frame = 1;
+      if (cpi->svc.spatial_layer_id > 0) {
+        cm->frame_type = INTER_FRAME;
+      }
     }
   } else {
+    if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
+      lc->is_key_frame = 0;
+    }
     cm->frame_type = INTER_FRAME;
   }
 
@@ -2392,9 +2397,11 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) {
   cpi->twopass.bits_left = MAX(cpi->twopass.bits_left, 0);
 
 #ifdef LONG_TERM_VBR_CORRECTION
-  if (cpi->common.frame_type != KEY_FRAME) {
+  if (cpi->common.frame_type != KEY_FRAME &&
+      !vp9_is_upper_layer_key_frame(cpi)) {
 #else
-  if (cpi->common.frame_type == KEY_FRAME) {
+  if (cpi->common.frame_type == KEY_FRAME ||
+      vp9_is_upper_layer_key_frame(cpi)) {
     // For key frames kf_group_bits already had the target bits subtracted out.
     // So now update to the correct value based on the actual bits used.
     cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - bits_used;
index 6ebd9f3..b123bfd 100644 (file)
@@ -807,7 +807,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
   int active_worst_quality = cpi->twopass.active_worst_quality;
   int q;
 
-  if (frame_is_intra_only(cm)) {
+  if (frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi)) {
 #if !CONFIG_MULTIPLE_ARF
     // Handle the special case for key frames forced when we have75 reached
     // the maximum key frame interval. Here force the Q to a range
@@ -928,7 +928,8 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
     vp9_clear_system_state();
 
     // Limit Q range for the adaptive loop.
-    if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) {
+    if ((cm->frame_type == KEY_FRAME || vp9_is_upper_layer_key_frame(cpi)) &&
+        !rc->this_key_frame_forced) {
       qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type,
                                           active_worst_quality, 2.0);
     } else if (!rc->is_src_frame_alt_ref &&
index 2379f35..5342447 100644 (file)
@@ -220,3 +220,16 @@ void vp9_inc_frame_in_layer(SVC *svc) {
       : &svc->layer_context[svc->spatial_layer_id];
   ++lc->current_video_frame_in_layer;
 }
+
+int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi) {
+  int is_upper_layer_key_frame = 0;
+
+  if (cpi->use_svc && cpi->svc.number_temporal_layers == 1 &&
+      cpi->svc.spatial_layer_id > 0) {
+    if (cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame) {
+      is_upper_layer_key_frame = 1;
+    }
+  }
+
+  return is_upper_layer_key_frame;
+}
index 2abed30..74d9c1c 100644 (file)
@@ -30,6 +30,7 @@ typedef struct {
   struct twopass_rc twopass;
   struct vpx_fixed_buf rc_twopass_stats_in;
   unsigned int current_video_frame_in_layer;
+  int is_key_frame;
 } LAYER_CONTEXT;
 
 typedef struct {
@@ -73,6 +74,9 @@ void vp9_init_second_pass_spatial_svc(struct VP9_COMP *cpi);
 // Increment number of video frames in layer
 void vp9_inc_frame_in_layer(SVC *svc);
 
+// Check if current layer is key frame in spatial upper layer
+int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif