summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2013-03-06 11:33:43 +0000
committerPaul Wilkins <paulwilkins@google.com>2013-03-11 19:25:10 +0000
commit08d2c3829ab47f2ef329f32773cfc2442852ca37 (patch)
treebb682012881e4c01f947977e193734542a69e715 /vp9
parent9b4095c537510c5c6378d08d0f250243da675547 (diff)
downloadlibvpx-08d2c3829ab47f2ef329f32773cfc2442852ca37.tar
libvpx-08d2c3829ab47f2ef329f32773cfc2442852ca37.tar.gz
libvpx-08d2c3829ab47f2ef329f32773cfc2442852ca37.tar.bz2
libvpx-08d2c3829ab47f2ef329f32773cfc2442852ca37.zip
Changes to maximum gf/arf interval.
This patch puts in an adjustment to the maximum gf/arf interval based on the active q range. It sets a fixed baseline maximum of 16 but can drop this down to 12 at lower q. This required some re-ordering in the first pass code to insure we have a Q range estimate before defining the first gf sequence. The main gains seed are int he STD hd set on 50fps clips where previously the interval could rise as high as 25. On the std hd clip the gains are around 2.8% with limit set to 300 frames. When combined with the one shot rate control flags we get combined of: derf 1.55% (limit300), yt 7.25%, hd 5.17% std-hd 5.84% (limit300) Change-Id: Ib380d51354511f2ff0f171a8df4e74291c0421f9
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_firstpass.c133
-rw-r--r--vp9/encoder/vp9_onyx_if.c4
2 files changed, 76 insertions, 61 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 5e2f323a2..5c2067b00 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1509,6 +1509,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
int f_boost = 0;
int b_boost = 0;
int flash_detected;
+ int active_max_gf_interval;
cpi->twopass.gf_group_bits = 0;
@@ -1536,6 +1537,18 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// or ARF that will be coded with the group
i = 0;
+ // Work out a maximum interval for the GF.
+ // If the image appears completely static we can extend beyond this.
+ // The value chosen depends on the active Q range. At low Q we have
+ // bits to spare and are better with a smaller interval and smaller boost.
+ // At high Q when there are few bits to spare we are better with a longer
+ // interval to spread the cost of the GF.
+ active_max_gf_interval =
+ 12 + ((int)vp9_convert_qindex_to_q(cpi->active_worst_quality) >> 5);
+
+ if (active_max_gf_interval > cpi->max_gf_interval)
+ active_max_gf_interval = cpi->max_gf_interval;
+
while (((i < cpi->twopass.static_scene_max_gf_interval) ||
((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)) &&
(i < cpi->twopass.frames_to_key)) {
@@ -1587,7 +1600,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Break out conditions.
if (
// Break at cpi->max_gf_interval unless almost totally static
- (i >= cpi->max_gf_interval && (zero_motion_accumulator < 0.995)) ||
+ (i >= active_max_gf_interval && (zero_motion_accumulator < 0.995)) ||
(
// Dont break out with a very short interval
(i > MIN_GF_INTERVAL) &&
@@ -1914,7 +1927,8 @@ static int adjust_active_maxq(int old_maxqi, int new_maxqi) {
void vp9_second_pass(VP9_COMP *cpi) {
int tmp_q;
- int frames_left = (int)(cpi->twopass.total_stats->count - cpi->common.current_video_frame);
+ int frames_left = (int)(cpi->twopass.total_stats->count -
+ cpi->common.current_video_frame);
FIRSTPASS_STATS this_frame;
FIRSTPASS_STATS this_frame_copy;
@@ -1928,63 +1942,6 @@ void vp9_second_pass(VP9_COMP *cpi) {
vp9_clear_system_state();
- vpx_memset(&this_frame, 0, sizeof(FIRSTPASS_STATS));
-
- if (EOF == input_stats(cpi, &this_frame))
- return;
-
- this_frame_intra_error = this_frame.intra_error;
- this_frame_coded_error = this_frame.coded_error;
-
- // keyframe and section processing !
- if (cpi->twopass.frames_to_key == 0) {
- // Define next KF group and assign bits to it
- vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
- find_next_key_frame(cpi, &this_frame_copy);
- }
-
- // Is this a GF / ARF (Note that a KF is always also a GF)
- if (cpi->frames_till_gf_update_due == 0) {
- // Define next gf group and assign bits to it
- vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
- define_gf_group(cpi, &this_frame_copy);
-
- // If we are going to code an altref frame at the end of the group and the current frame is not a key frame....
- // If the previous group used an arf this frame has already benefited from that arf boost and it should not be given extra bits
- // If the previous group was NOT coded using arf we may want to apply some boost to this GF as well
- if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME)) {
- // Assign a standard frames worth of bits from those allocated to the GF group
- int bak = cpi->per_frame_bandwidth;
- vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
- assign_std_frame_bits(cpi, &this_frame_copy);
- cpi->per_frame_bandwidth = bak;
- }
- }
-
- // Otherwise this is an ordinary frame
- else {
- // Assign bits from those allocated to the GF group
- vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
- assign_std_frame_bits(cpi, &this_frame_copy);
- }
-
- // Keep a globally available copy of this and the next frame's iiratio.
- cpi->twopass.this_iiratio = (int)(this_frame_intra_error /
- DOUBLE_DIVIDE_CHECK(this_frame_coded_error));
- {
- FIRSTPASS_STATS next_frame;
- if (lookup_next_frame_stats(cpi, &next_frame) != EOF) {
- cpi->twopass.next_iiratio = (int)(next_frame.intra_error /
- DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
- }
- }
-
- // Set nominal per second bandwidth for this frame
- cpi->target_bandwidth = (int)(cpi->per_frame_bandwidth
- * cpi->output_frame_rate);
- if (cpi->target_bandwidth < 0)
- cpi->target_bandwidth = 0;
-
// Special case code for first frame.
if (cpi->common.current_video_frame == 0) {
cpi->twopass.est_max_qcorrection_factor = 1.0;
@@ -2049,6 +2006,64 @@ void vp9_second_pass(VP9_COMP *cpi) {
}
#endif
+ vpx_memset(&this_frame, 0, sizeof(FIRSTPASS_STATS));
+ if (EOF == input_stats(cpi, &this_frame))
+ return;
+
+ this_frame_intra_error = this_frame.intra_error;
+ this_frame_coded_error = this_frame.coded_error;
+
+ // keyframe and section processing !
+ if (cpi->twopass.frames_to_key == 0) {
+ // Define next KF group and assign bits to it
+ vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+ find_next_key_frame(cpi, &this_frame_copy);
+ }
+
+ // Is this a GF / ARF (Note that a KF is always also a GF)
+ if (cpi->frames_till_gf_update_due == 0) {
+ // Define next gf group and assign bits to it
+ vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+ define_gf_group(cpi, &this_frame_copy);
+
+ // If we are going to code an altref frame at the end of the group
+ // and the current frame is not a key frame....
+ // If the previous group used an arf this frame has already benefited
+ // from that arf boost and it should not be given extra bits
+ // If the previous group was NOT coded using arf we may want to apply
+ // some boost to this GF as well
+ if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME)) {
+ // Assign a standard frames worth of bits from those allocated
+ // to the GF group
+ int bak = cpi->per_frame_bandwidth;
+ vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+ assign_std_frame_bits(cpi, &this_frame_copy);
+ cpi->per_frame_bandwidth = bak;
+ }
+ } else {
+ // Otherwise this is an ordinary frame
+ // Assign bits from those allocated to the GF group
+ vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+ assign_std_frame_bits(cpi, &this_frame_copy);
+ }
+
+ // Keep a globally available copy of this and the next frame's iiratio.
+ cpi->twopass.this_iiratio = (int)(this_frame_intra_error /
+ DOUBLE_DIVIDE_CHECK(this_frame_coded_error));
+ {
+ FIRSTPASS_STATS next_frame;
+ if (lookup_next_frame_stats(cpi, &next_frame) != EOF) {
+ cpi->twopass.next_iiratio = (int)(next_frame.intra_error /
+ DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
+ }
+ }
+
+ // Set nominal per second bandwidth for this frame
+ cpi->target_bandwidth = (int)(cpi->per_frame_bandwidth
+ * cpi->output_frame_rate);
+ if (cpi->target_bandwidth < 0)
+ cpi->target_bandwidth = 0;
+
cpi->twopass.frames_to_key--;
// Update the total stats remaining sturcture
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 5a565fcab..ce91fb2f5 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -1075,12 +1075,12 @@ void vp9_new_frame_rate(VP9_COMP *cpi, double framerate) {
cpi->min_frame_bandwidth = FRAME_OVERHEAD_BITS;
// Set Maximum gf/arf interval
- cpi->max_gf_interval = 15;
+ cpi->max_gf_interval = 16;
// Extended interval for genuinely static scenes
cpi->twopass.static_scene_max_gf_interval = cpi->key_frame_frequency >> 1;
- // Special conditions when altr ref frame enabled in lagged compress mode
+ // Special conditions when alt ref frame enabled in lagged compress mode
if (cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames) {
if (cpi->max_gf_interval > cpi->oxcf.lag_in_frames - 1)
cpi->max_gf_interval = cpi->oxcf.lag_in_frames - 1;