shithub: libvpx

Download patch

ref: 0d21d79bbccfb72b06fa48a9507af109a933b5e4
parent: 7d4083a8dafc60aa09beb32afe62cf5a9efdb44a
parent: 730ade414d56b1b9c672c6569e9481af315ed3d1
author: Deb Mukherjee <debargha@google.com>
date: Wed Jan 8 04:20:29 EST 2014

Merge "Further rate control cleanups"

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1987,6 +1987,11 @@
   cpi->rc.per_frame_bandwidth = target_frame_size;
 }
 
+static int test_for_kf_one_pass(VP9_COMP *cpi) {
+  // Placeholder function for auto key frame
+  return 0;
+}
+
 void vp9_get_svc_params(VP9_COMP *cpi) {
   VP9_COMMON *const cm = &cpi->common;
   if ((cm->current_video_frame == 0) ||
@@ -2006,9 +2011,10 @@
   if (!cpi->refresh_alt_ref_frame &&
       (cm->current_video_frame == 0 ||
        cm->frame_flags & FRAMEFLAGS_KEY ||
-       (cpi->oxcf.auto_key && (cpi->rc.frames_since_key %
-                               cpi->key_frame_frequency == 0)))) {
+       cpi->rc.frames_to_key == 0 ||
+       (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) {
     cm->frame_type = KEY_FRAME;
+    cpi->rc.frames_to_key = cpi->key_frame_frequency;
   } else {
     cm->frame_type = INTER_FRAME;
   }
@@ -2027,6 +2033,8 @@
   } else {
     cm->frame_type = INTER_FRAME;
   }
+  cpi->rc.frames_to_key = INT_MAX;
+  // Do not use periodic key frames
 }
 
 void vp9_get_second_pass_params(VP9_COMP *cpi) {
@@ -2150,8 +2158,6 @@
                                 * cpi->output_framerate);
   if (cpi->target_bandwidth < 0)
     cpi->target_bandwidth = 0;
-
-  cpi->rc.frames_to_key--;
 
   // Update the total stats remaining structure
   subtract_stats(&cpi->twopass.total_left_stats, &this_frame);
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -1367,9 +1367,6 @@
       cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
   }
 
-  // At the moment the first order values may not be > MAXQ
-  cpi->oxcf.fixed_q = MIN(cpi->oxcf.fixed_q, MAXQ);
-
   // local file playback mode == really big buffer
   if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK) {
     cpi->oxcf.starting_buffer_level   = 60000;
@@ -1431,13 +1428,6 @@
   }
   update_frame_size(cpi);
 
-  if (cpi->oxcf.fixed_q >= 0) {
-    cpi->rc.last_q[0] = cpi->oxcf.fixed_q;
-    cpi->rc.last_q[1] = cpi->oxcf.fixed_q;
-    cpi->rc.last_q[2] = cpi->oxcf.fixed_q;
-    cpi->rc.last_boosted_qindex = cpi->oxcf.fixed_q;
-  }
-
   cpi->speed = cpi->oxcf.cpu_used;
 
   if (cpi->oxcf.lag_in_frames == 0) {
@@ -1663,7 +1653,6 @@
   init_pick_mode_context(cpi);
 
   cm->current_video_frame   = 0;
-  cpi->rc.frames_till_gf_update_due = 0;
 
   // Set reference frame sign bias for ALTREF frame to 1 (for now)
   cm->ref_frame_sign_bias[ALTREF_FRAME] = 1;
@@ -2445,53 +2434,6 @@
   vp8_yv12_extend_frame_borders(dst_fb);
 }
 
-
-static void update_alt_ref_frame_stats(VP9_COMP *cpi) {
-  // this frame refreshes means next frames don't unless specified by user
-  cpi->rc.frames_since_golden = 0;
-
-#if CONFIG_MULTIPLE_ARF
-  if (!cpi->multi_arf_enabled)
-#endif
-    // Clear the alternate reference update pending flag.
-    cpi->rc.source_alt_ref_pending = 0;
-
-  // Set the alternate reference frame active flag
-  cpi->rc.source_alt_ref_active = 1;
-}
-
-static void update_golden_frame_stats(VP9_COMP *cpi) {
-  // Update the Golden frame usage counts.
-  if (cpi->refresh_golden_frame) {
-    // this frame refreshes means next frames don't unless specified by user
-    cpi->refresh_golden_frame = 0;
-    cpi->rc.frames_since_golden = 0;
-
-    // ******** Fixed Q test code only ************
-    // If we are going to use the ALT reference for the next group of frames
-    // set a flag to say so.
-    if (cpi->oxcf.fixed_q >= 0 &&
-        cpi->oxcf.play_alternate && !cpi->refresh_alt_ref_frame) {
-      cpi->rc.source_alt_ref_pending = 1;
-      cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval;
-    }
-
-    if (!cpi->rc.source_alt_ref_pending)
-      cpi->rc.source_alt_ref_active = 0;
-
-    // Decrement count down till next gf
-    if (cpi->rc.frames_till_gf_update_due > 0)
-      cpi->rc.frames_till_gf_update_due--;
-
-  } else if (!cpi->refresh_alt_ref_frame) {
-    // Decrement count down till next gf
-    if (cpi->rc.frames_till_gf_update_due > 0)
-      cpi->rc.frames_till_gf_update_due--;
-
-    cpi->rc.frames_since_golden++;
-  }
-}
-
 static int find_fp_qindex() {
   int i;
 
@@ -3144,8 +3086,9 @@
     if (vp9_drop_frame(cpi)) {
       // Update buffer level with zero size, update frame counters, and return.
       vp9_update_buffer_level(cpi, 0);
+      cm->last_frame_type = cm->frame_type;
+      vp9_rc_postencode_update_drop_frame(cpi);
       cm->current_video_frame++;
-      cpi->rc.frames_since_key++;
       return;
     }
   }
@@ -3214,7 +3157,7 @@
   // Special case code to reduce pulsing when key frames are forced at a
   // fixed interval. Note the reconstruction error if it is the frame before
   // the force key frame
-  if (cpi->rc.next_key_frame_forced && (cpi->rc.frames_to_key == 0)) {
+  if (cpi->rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) {
     cpi->ambient_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm));
   }
 
@@ -3278,8 +3221,6 @@
    * needed in motion search besides loopfilter */
   cm->last_frame_type = cm->frame_type;
 
-  vp9_rc_postencode_update(cpi, *size);
-
 #if 0
   output_frame_level_debug_stats(cpi);
 #endif
@@ -3295,13 +3236,7 @@
 
   get_ref_frame_flags(cpi);
 
-  if (cpi->oxcf.play_alternate && cpi->refresh_alt_ref_frame
-      && (cm->frame_type != KEY_FRAME))
-    // Update the alternate reference frame stats as appropriate.
-    update_alt_ref_frame_stats(cpi);
-  else
-    // Update the Golden frame stats as appropriate.
-    update_golden_frame_stats(cpi);
+  vp9_rc_postencode_update(cpi, *size);
 
   if (cm->frame_type == KEY_FRAME) {
     // Tell the caller that the frame was coded as a key frame
@@ -3315,10 +3250,6 @@
       cpi->new_frame_coding_order_period = -1;
     }
 #endif
-
-    // As this frame is a key frame the next defaults to an inter frame.
-    vp9_clear_system_state();
-    cpi->rc.frames_since_key = 0;
   } else {
     *frame_flags = cm->frame_flags&~FRAMEFLAGS_KEY;
 
@@ -3368,7 +3299,6 @@
     // Don't increment frame counters if this was an altref buffer
     // update not a real frame
     ++cm->current_video_frame;
-    ++cpi->rc.frames_since_key;
   }
   // restore prev_mi
   cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1;
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -257,16 +257,6 @@
   cpi->rc.this_frame_target = target;
 }
 
-//  Do the best we can to define the parameters for the next GF based
-//  on what information we have available.
-//
-//  In this experimental code only two pass is supported
-//  so we just use the interval determined in the two pass code.
-static void calc_gf_params(VP9_COMP *cpi) {
-  // Set the gf interval
-  cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval;
-}
-
 // Update the buffer level: leaky bucket model.
 void vp9_update_buffer_level(VP9_COMP *const cpi, int encoded_frame_size) {
   VP9_COMMON *const cm = &cpi->common;
@@ -847,6 +837,43 @@
   return 1;
 }
 
+static void update_alt_ref_frame_stats(VP9_COMP *cpi) {
+  // this frame refreshes means next frames don't unless specified by user
+  cpi->rc.frames_since_golden = 0;
+
+#if CONFIG_MULTIPLE_ARF
+  if (!cpi->multi_arf_enabled)
+#endif
+    // Clear the alternate reference update pending flag.
+    cpi->rc.source_alt_ref_pending = 0;
+
+  // Set the alternate reference frame active flag
+  cpi->rc.source_alt_ref_active = 1;
+}
+
+static void update_golden_frame_stats(VP9_COMP *cpi) {
+  // Update the Golden frame usage counts.
+  if (cpi->refresh_golden_frame) {
+    // this frame refreshes means next frames don't unless specified by user
+    cpi->refresh_golden_frame = 0;
+    cpi->rc.frames_since_golden = 0;
+
+    if (!cpi->rc.source_alt_ref_pending)
+      cpi->rc.source_alt_ref_active = 0;
+
+    // Decrement count down till next gf
+    if (cpi->rc.frames_till_gf_update_due > 0)
+      cpi->rc.frames_till_gf_update_due--;
+
+  } else if (!cpi->refresh_alt_ref_frame) {
+    // Decrement count down till next gf
+    if (cpi->rc.frames_till_gf_update_due > 0)
+      cpi->rc.frames_till_gf_update_due--;
+
+    cpi->rc.frames_since_golden++;
+  }
+}
+
 void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
   VP9_COMMON *const cm = &cpi->common;
   // Update rate control heuristics
@@ -934,4 +961,24 @@
     cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0);
   }
 #endif
+
+  if (cpi->oxcf.play_alternate && cpi->refresh_alt_ref_frame
+      && (cm->frame_type != KEY_FRAME))
+    // Update the alternate reference frame stats as appropriate.
+    update_alt_ref_frame_stats(cpi);
+  else
+    // Update the Golden frame stats as appropriate.
+    update_golden_frame_stats(cpi);
+
+  if (cm->frame_type == KEY_FRAME)
+    cpi->rc.frames_since_key = 0;
+  if (cm->show_frame) {
+    cpi->rc.frames_since_key++;
+    cpi->rc.frames_to_key--;
+  }
+}
+
+void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) {
+  cpi->rc.frames_since_key++;
+  // cpi->rc.frames_to_key--;
 }
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -52,6 +52,8 @@
 // on bytes used
 void vp9_rc_postencode_update(VP9_COMP *cpi,
                               uint64_t bytes_used);
+// for dropped frames
+void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi);
 
 // estimates bits per mb for a given qindex and correction factor
 int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex,