Index: source/libvpx/vp9/encoder/vp9_ratectrl.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_ratectrl.c (revision 251189) |
+++ source/libvpx/vp9/encoder/vp9_ratectrl.c (working copy) |
@@ -209,51 +209,60 @@ |
: (bpm * mbs) >> BPER_MB_NORMBITS; |
} |
+int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) { |
+ const RATE_CONTROL *rc = &cpi->rc; |
+ const int min_frame_target = MAX(rc->min_frame_bandwidth, |
+ rc->av_per_frame_bandwidth >> 5); |
+ if (target < min_frame_target) |
+ target = min_frame_target; |
+ if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) { |
+ // If there is an active ARF at this location use the minimum |
+ // bits on this frame even if it is a constructed arf. |
+ // The active maximum quantizer insures that an appropriate |
+ // number of bits will be spent if needed for constructed ARFs. |
+ target = min_frame_target; |
+ } |
+ // Clip the frame target to the maximum allowed value. |
+ if (target > rc->max_frame_bandwidth) |
+ target = rc->max_frame_bandwidth; |
+ return target; |
+} |
-static void calc_iframe_target_size(VP9_COMP *cpi) { |
+int vp9_rc_clamp_iframe_target_size(const VP9_COMP *const cpi, int target) { |
+ const RATE_CONTROL *rc = &cpi->rc; |
const VP9_CONFIG *oxcf = &cpi->oxcf; |
- RATE_CONTROL *const rc = &cpi->rc; |
- int target; |
+ if (oxcf->rc_max_intra_bitrate_pct) { |
+ const int max_rate = rc->av_per_frame_bandwidth * |
+ oxcf->rc_max_intra_bitrate_pct / 100; |
+ target = MIN(target, max_rate); |
+ } |
+ if (target > rc->max_frame_bandwidth) |
+ target = rc->max_frame_bandwidth; |
+ return target; |
+} |
- vp9_clear_system_state(); // __asm emms; |
- // For 1-pass. |
- if (cpi->pass == 0) { |
- if (cpi->common.current_video_frame == 0) { |
- target = oxcf->starting_buffer_level / 2; |
- } else { |
- // TODO(marpan): Add in adjustment based on Q. |
- // If this keyframe was forced, use a more recent Q estimate. |
- // int Q = (cpi->common.frame_flags & FRAMEFLAGS_KEY) ? |
- // cpi->rc.avg_frame_qindex : cpi->rc.ni_av_qi; |
- int initial_boost = 32; |
- // Boost depends somewhat on frame rate. |
- int kf_boost = MAX(initial_boost, (int)(2 * cpi->output_framerate - 16)); |
- // Adjustment up based on q: need to fix. |
- // kf_boost = kf_boost * kfboost_qadjust(Q) / 100; |
- // Frame separation adjustment (down). |
- if (rc->frames_since_key < cpi->output_framerate / 2) { |
- kf_boost = (int)(kf_boost * rc->frames_since_key / |
- (cpi->output_framerate / 2)); |
- } |
- kf_boost = (kf_boost < 16) ? 16 : kf_boost; |
- target = ((16 + kf_boost) * rc->per_frame_bandwidth) >> 4; |
- } |
- rc->active_worst_quality = rc->worst_quality; |
- } else { |
- target = rc->per_frame_bandwidth; |
- } |
+// Update the buffer level for higher layers, given the encoded current layer. |
+static void update_layer_buffer_level(VP9_COMP *const cpi, |
+ int encoded_frame_size) { |
+ int temporal_layer = 0; |
+ int current_temporal_layer = cpi->svc.temporal_layer_id; |
+ for (temporal_layer = current_temporal_layer + 1; |
+ temporal_layer < cpi->svc.number_temporal_layers; ++temporal_layer) { |
+ LAYER_CONTEXT *lc = &cpi->svc.layer_context[temporal_layer]; |
+ RATE_CONTROL *lrc = &lc->rc; |
+ int bits_off_for_this_layer = (int)(lc->target_bandwidth / lc->framerate - |
+ encoded_frame_size); |
+ lrc->bits_off_target += bits_off_for_this_layer; |
- if (oxcf->rc_max_intra_bitrate_pct) { |
- const int max_rate = rc->per_frame_bandwidth * |
- oxcf->rc_max_intra_bitrate_pct / 100; |
- target = MIN(target, max_rate); |
+ // Clip buffer level to maximum buffer size for the layer. |
+ lrc->bits_off_target = MIN(lrc->bits_off_target, lc->maximum_buffer_size); |
+ lrc->buffer_level = lrc->bits_off_target; |
} |
- rc->this_frame_target = target; |
} |
// Update the buffer level: leaky bucket model. |
-void vp9_update_buffer_level(VP9_COMP *const cpi, int encoded_frame_size) { |
+static void update_buffer_level(VP9_COMP *cpi, int encoded_frame_size) { |
const VP9_COMMON *const cm = &cpi->common; |
const VP9_CONFIG *oxcf = &cpi->oxcf; |
RATE_CONTROL *const rc = &cpi->rc; |
@@ -266,14 +275,18 @@ |
} |
// Clip the buffer level to the maximum specified buffer size. |
- rc->buffer_level = MIN(rc->bits_off_target, oxcf->maximum_buffer_size); |
+ rc->bits_off_target = MIN(rc->bits_off_target, oxcf->maximum_buffer_size); |
+ rc->buffer_level = rc->bits_off_target; |
+ |
+ if (cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { |
+ update_layer_buffer_level(cpi, encoded_frame_size); |
+ } |
} |
-int vp9_drop_frame(VP9_COMP *const cpi) { |
+int vp9_rc_drop_frame(VP9_COMP *cpi) { |
const VP9_CONFIG *oxcf = &cpi->oxcf; |
RATE_CONTROL *const rc = &cpi->rc; |
- |
if (!oxcf->drop_frames_water_mark) { |
return 0; |
} else { |
@@ -284,7 +297,7 @@ |
// If buffer is below drop_mark, for now just drop every other frame |
// (starting with the next frame) until it increases back over drop_mark. |
int drop_mark = (int)(oxcf->drop_frames_water_mark * |
- oxcf->optimal_buffer_level / 100); |
+ oxcf->optimal_buffer_level / 100); |
if ((rc->buffer_level > drop_mark) && |
(rc->decimation_factor > 0)) { |
--rc->decimation_factor; |
@@ -308,129 +321,12 @@ |
} |
} |
-// Adjust active_worst_quality level based on buffer level. |
-static int adjust_active_worst_quality_from_buffer_level(const VP9_CONFIG *oxcf, |
- const RATE_CONTROL *rc) { |
- // Adjust active_worst_quality: If buffer is above the optimal/target level, |
- // bring active_worst_quality down depending on fullness over buffer. |
- // If buffer is below the optimal level, let the active_worst_quality go from |
- // ambient Q (at buffer = optimal level) to worst_quality level |
- // (at buffer = critical level). |
- |
- int active_worst_quality = rc->active_worst_quality; |
- // Maximum limit for down adjustment, ~20%. |
- int max_adjustment_down = active_worst_quality / 5; |
- // Buffer level below which we push active_worst to worst_quality. |
- int critical_level = oxcf->optimal_buffer_level >> 2; |
- int adjustment = 0; |
- int buff_lvl_step = 0; |
- if (rc->buffer_level > oxcf->optimal_buffer_level) { |
- // Adjust down. |
- if (max_adjustment_down) { |
- buff_lvl_step = (int)((oxcf->maximum_buffer_size - |
- oxcf->optimal_buffer_level) / max_adjustment_down); |
- if (buff_lvl_step) |
- adjustment = (int)((rc->buffer_level - oxcf->optimal_buffer_level) / |
- buff_lvl_step); |
- active_worst_quality -= adjustment; |
- } |
- } else if (rc->buffer_level > critical_level) { |
- // Adjust up from ambient Q. |
- if (critical_level) { |
- buff_lvl_step = (oxcf->optimal_buffer_level - critical_level); |
- if (buff_lvl_step) { |
- adjustment = (rc->worst_quality - rc->avg_frame_qindex[INTER_FRAME]) * |
- (oxcf->optimal_buffer_level - rc->buffer_level) / |
- buff_lvl_step; |
- } |
- active_worst_quality = rc->avg_frame_qindex[INTER_FRAME] + adjustment; |
- } |
- } else { |
- // Set to worst_quality if buffer is below critical level. |
- active_worst_quality = rc->worst_quality; |
- } |
- return active_worst_quality; |
-} |
- |
-// Adjust target frame size with respect to the buffering constraints: |
-static int target_size_from_buffer_level(const VP9_CONFIG *oxcf, |
- const RATE_CONTROL *rc) { |
- int target = rc->this_frame_target; |
- const int64_t diff = oxcf->optimal_buffer_level - rc->buffer_level; |
- const int one_pct_bits = 1 + oxcf->optimal_buffer_level / 100; |
- |
- if (diff > 0) { |
- // Lower the target bandwidth for this frame. |
- const int pct_low = MIN(diff / one_pct_bits, oxcf->under_shoot_pct); |
- target -= (target * pct_low) / 200; |
- } else if (diff < 0) { |
- // Increase the target bandwidth for this frame. |
- const int pct_high = MIN(-diff / one_pct_bits, oxcf->over_shoot_pct); |
- target += (target * pct_high) / 200; |
- } |
- |
- return target; |
-} |
- |
-static void calc_pframe_target_size(VP9_COMP *const cpi) { |
- RATE_CONTROL *const rc = &cpi->rc; |
- const VP9_CONFIG *const oxcf = &cpi->oxcf; |
- int min_frame_target = MAX(rc->min_frame_bandwidth, |
- rc->av_per_frame_bandwidth >> 5); |
- if (cpi->refresh_alt_ref_frame) { |
- // Special alt reference frame case |
- // Per frame bit target for the alt ref frame |
- rc->per_frame_bandwidth = cpi->twopass.gf_bits; |
- rc->this_frame_target = rc->per_frame_bandwidth; |
- } else { |
- // Normal frames (gf and inter). |
- rc->this_frame_target = rc->per_frame_bandwidth; |
- // Set target frame size based on buffer level, for 1 pass CBR. |
- if (cpi->pass == 0 && oxcf->end_usage == USAGE_STREAM_FROM_SERVER) { |
- // Need to decide how low min_frame_target should be for 1-pass CBR. |
- // For now, use: cpi->rc.av_per_frame_bandwidth / 16: |
- min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4, |
- FRAME_OVERHEAD_BITS); |
- rc->this_frame_target = target_size_from_buffer_level(oxcf, rc); |
- // Adjust qp-max based on buffer level. |
- rc->active_worst_quality = |
- adjust_active_worst_quality_from_buffer_level(oxcf, rc); |
- } |
- } |
- |
- // Check that the total sum of adjustments is not above the maximum allowed. |
- // That is, having allowed for the KF and GF penalties, we have not pushed |
- // the current inter-frame target too low. If the adjustment we apply here is |
- // not capable of recovering all the extra bits we have spent in the KF or GF, |
- // then the remainder will have to be recovered over a longer time span via |
- // other buffer / rate control mechanisms. |
- if (rc->this_frame_target < min_frame_target) |
- rc->this_frame_target = min_frame_target; |
- |
- // Adjust target frame size for Golden Frames: |
- if (cpi->refresh_golden_frame) { |
- // If we are using alternate ref instead of gf then do not apply the boost |
- // It will instead be applied to the altref update |
- // Jims modified boost |
- if (!rc->source_alt_ref_active) { |
- // The spend on the GF is defined in the two pass code |
- // for two pass encodes |
- rc->this_frame_target = rc->per_frame_bandwidth; |
- } else { |
- // If there is an active ARF at this location use the minimum |
- // bits on this frame even if it is a constructed arf. |
- // The active maximum quantizer insures that an appropriate |
- // number of bits will be spent if needed for constructed ARFs. |
- rc->this_frame_target = 0; |
- } |
- } |
-} |
- |
static double get_rate_correction_factor(const VP9_COMP *cpi) { |
if (cpi->common.frame_type == KEY_FRAME) { |
return cpi->rc.key_frame_rate_correction_factor; |
} else { |
- if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) |
+ if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) && |
+ !(cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) |
return cpi->rc.gf_rate_correction_factor; |
else |
return cpi->rc.rate_correction_factor; |
@@ -441,7 +337,8 @@ |
if (cpi->common.frame_type == KEY_FRAME) { |
cpi->rc.key_frame_rate_correction_factor = factor; |
} else { |
- if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) |
+ if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) && |
+ !(cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) |
cpi->rc.gf_rate_correction_factor = factor; |
else |
cpi->rc.rate_correction_factor = factor; |
@@ -465,7 +362,6 @@ |
projected_size_based_on_q = estimate_bits_at_q(cpi->common.frame_type, q, |
cpi->common.MBs, |
rate_correction_factor); |
- |
// Work out a size correction factor. |
if (projected_size_based_on_q > 0) |
correction_factor = (100 * cpi->rc.projected_frame_size) / |
@@ -564,13 +460,205 @@ |
} |
} |
-int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi, |
- int *bottom_index, int *top_index) { |
+static int calc_active_worst_quality_one_pass_vbr(const VP9_COMP *cpi) { |
+ int active_worst_quality; |
+ if (cpi->common.frame_type == KEY_FRAME) { |
+ if (cpi->common.current_video_frame == 0) { |
+ active_worst_quality = cpi->rc.worst_quality; |
+ } else { |
+ // Choose active worst quality twice as large as the last q. |
+ active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 2; |
+ } |
+ } else if (!cpi->rc.is_src_frame_alt_ref && |
+ (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
+ if (cpi->common.current_video_frame == 1) { |
+ active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 5 / 4; |
+ } else { |
+ // Choose active worst quality twice as large as the last q. |
+ active_worst_quality = cpi->rc.last_q[INTER_FRAME]; |
+ } |
+ } else { |
+ if (cpi->common.current_video_frame == 1) { |
+ active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 2; |
+ } else { |
+ // Choose active worst quality twice as large as the last q. |
+ active_worst_quality = cpi->rc.last_q[INTER_FRAME] * 2; |
+ } |
+ } |
+ if (active_worst_quality > cpi->rc.worst_quality) |
+ active_worst_quality = cpi->rc.worst_quality; |
+ return active_worst_quality; |
+} |
+ |
+// Adjust active_worst_quality level based on buffer level. |
+static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) { |
+ // Adjust active_worst_quality: If buffer is above the optimal/target level, |
+ // bring active_worst_quality down depending on fullness of buffer. |
+ // If buffer is below the optimal level, let the active_worst_quality go from |
+ // ambient Q (at buffer = optimal level) to worst_quality level |
+ // (at buffer = critical level). |
+ const VP9_CONFIG *oxcf = &cpi->oxcf; |
+ const RATE_CONTROL *rc = &cpi->rc; |
+ // Buffer level below which we push active_worst to worst_quality. |
+ int critical_level = oxcf->optimal_buffer_level >> 2; |
+ int adjustment = 0; |
+ int buff_lvl_step = 0; |
+ int active_worst_quality; |
+ if (cpi->common.frame_type == KEY_FRAME) |
+ return rc->worst_quality; |
+ if (cpi->common.current_video_frame > 1) |
+ active_worst_quality = MIN(rc->worst_quality, |
+ rc->avg_frame_qindex[INTER_FRAME] * 5 / 4); |
+ else |
+ active_worst_quality = MIN(rc->worst_quality, |
+ rc->avg_frame_qindex[KEY_FRAME] * 3 / 2); |
+ if (rc->buffer_level > oxcf->optimal_buffer_level) { |
+ // Adjust down. |
+ // Maximum limit for down adjustment, ~30%. |
+ int max_adjustment_down = active_worst_quality / 3; |
+ if (max_adjustment_down) { |
+ buff_lvl_step = (int)((oxcf->maximum_buffer_size - |
+ oxcf->optimal_buffer_level) / max_adjustment_down); |
+ if (buff_lvl_step) |
+ adjustment = (int)((rc->buffer_level - oxcf->optimal_buffer_level) / |
+ buff_lvl_step); |
+ active_worst_quality -= adjustment; |
+ } |
+ } else if (rc->buffer_level > critical_level) { |
+ // Adjust up from ambient Q. |
+ if (critical_level) { |
+ buff_lvl_step = (oxcf->optimal_buffer_level - critical_level); |
+ if (buff_lvl_step) { |
+ adjustment = (rc->worst_quality - rc->avg_frame_qindex[INTER_FRAME]) * |
+ (oxcf->optimal_buffer_level - rc->buffer_level) / |
+ buff_lvl_step; |
+ } |
+ active_worst_quality = rc->avg_frame_qindex[INTER_FRAME] + adjustment; |
+ } |
+ } else { |
+ // Set to worst_quality if buffer is below critical level. |
+ active_worst_quality = rc->worst_quality; |
+ } |
+ return active_worst_quality; |
+} |
+ |
+static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, |
+ int *bottom_index, |
+ int *top_index) { |
const VP9_COMMON *const cm = &cpi->common; |
const RATE_CONTROL *const rc = &cpi->rc; |
+ int active_best_quality; |
+ int active_worst_quality = calc_active_worst_quality_one_pass_cbr(cpi); |
+ int q; |
+ |
+ if (frame_is_intra_only(cm)) { |
+ active_best_quality = rc->best_quality; |
+ // Handle the special case for key frames forced when we have75 reached |
+ // the maximum key frame interval. Here force the Q to a range |
+ // based on the ambient Q to reduce the risk of popping. |
+ if (rc->this_key_frame_forced) { |
+ int qindex = rc->last_boosted_qindex; |
+ double last_boosted_q = vp9_convert_qindex_to_q(qindex); |
+ int delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q, |
+ (last_boosted_q * 0.75)); |
+ active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); |
+ } else if (cm->current_video_frame > 0) { |
+ // not first frame of one pass and kf_boost is set |
+ double q_adj_factor = 1.0; |
+ double q_val; |
+ |
+ active_best_quality = get_active_quality(rc->avg_frame_qindex[KEY_FRAME], |
+ rc->kf_boost, |
+ kf_low, kf_high, |
+ kf_low_motion_minq, |
+ kf_high_motion_minq); |
+ |
+ // Allow somewhat lower kf minq with small image formats. |
+ if ((cm->width * cm->height) <= (352 * 288)) { |
+ q_adj_factor -= 0.25; |
+ } |
+ |
+ // Convert the adjustment factor to a qindex delta |
+ // on active_best_quality. |
+ q_val = vp9_convert_qindex_to_q(active_best_quality); |
+ active_best_quality += vp9_compute_qdelta(cpi, q_val, q_val * |
+ q_adj_factor); |
+ } |
+ } else if (!rc->is_src_frame_alt_ref && |
+ (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
+ // Use the lower of active_worst_quality and recent |
+ // average Q as basis for GF/ARF best Q limit unless last frame was |
+ // a key frame. |
+ if (rc->frames_since_key > 1 && |
+ rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) { |
+ q = rc->avg_frame_qindex[INTER_FRAME]; |
+ } else { |
+ q = active_worst_quality; |
+ } |
+ active_best_quality = get_active_quality( |
+ q, rc->gfu_boost, gf_low, gf_high, |
+ gf_low_motion_minq, gf_high_motion_minq); |
+ } else { |
+ // Use the lower of active_worst_quality and recent/average Q. |
+ if (cm->current_video_frame > 1) { |
+ if (rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) |
+ active_best_quality = inter_minq[rc->avg_frame_qindex[INTER_FRAME]]; |
+ else |
+ active_best_quality = inter_minq[active_worst_quality]; |
+ } else { |
+ if (rc->avg_frame_qindex[KEY_FRAME] < active_worst_quality) |
+ active_best_quality = inter_minq[rc->avg_frame_qindex[KEY_FRAME]]; |
+ else |
+ active_best_quality = inter_minq[active_worst_quality]; |
+ } |
+ } |
+ |
+ // Clip the active best and worst quality values to limits |
+ active_best_quality = clamp(active_best_quality, |
+ rc->best_quality, rc->worst_quality); |
+ active_worst_quality = clamp(active_worst_quality, |
+ active_best_quality, rc->worst_quality); |
+ |
+ *top_index = active_worst_quality; |
+ *bottom_index = active_best_quality; |
+ |
+#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY |
+ // Limit Q range for the adaptive loop. |
+ if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) { |
+ if (!(cm->current_video_frame == 0)) |
+ *top_index = (active_worst_quality + active_best_quality * 3) / 4; |
+ } |
+#endif |
+ // Special case code to try and match quality with forced key frames |
+ if (cm->frame_type == KEY_FRAME && rc->this_key_frame_forced) { |
+ q = rc->last_boosted_qindex; |
+ } else { |
+ q = vp9_rc_regulate_q(cpi, rc->this_frame_target, |
+ active_best_quality, active_worst_quality); |
+ if (q > *top_index) { |
+ // Special case when we are targeting the max allowed rate |
+ if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth) |
+ *top_index = q; |
+ else |
+ q = *top_index; |
+ } |
+ } |
+ assert(*top_index <= rc->worst_quality && |
+ *top_index >= rc->best_quality); |
+ assert(*bottom_index <= rc->worst_quality && |
+ *bottom_index >= rc->best_quality); |
+ assert(q <= rc->worst_quality && q >= rc->best_quality); |
+ return q; |
+} |
+ |
+static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, |
+ int *bottom_index, |
+ int *top_index) { |
+ const VP9_COMMON *const cm = &cpi->common; |
+ const RATE_CONTROL *const rc = &cpi->rc; |
const VP9_CONFIG *const oxcf = &cpi->oxcf; |
int active_best_quality; |
- int active_worst_quality = rc->active_worst_quality; |
+ int active_worst_quality = calc_active_worst_quality_one_pass_vbr(cpi); |
int q; |
if (frame_is_intra_only(cm)) { |
@@ -585,12 +673,193 @@ |
int delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q, |
(last_boosted_q * 0.75)); |
active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); |
- } else if (!(cpi->pass == 0 && cm->current_video_frame == 0)) { |
+ } else if (cm->current_video_frame > 0) { |
// not first frame of one pass and kf_boost is set |
double q_adj_factor = 1.0; |
double q_val; |
- // Baseline value derived from cpi->active_worst_quality and kf boost |
+ active_best_quality = get_active_quality(rc->avg_frame_qindex[KEY_FRAME], |
+ rc->kf_boost, |
+ kf_low, kf_high, |
+ kf_low_motion_minq, |
+ kf_high_motion_minq); |
+ |
+ // Allow somewhat lower kf minq with small image formats. |
+ if ((cm->width * cm->height) <= (352 * 288)) { |
+ q_adj_factor -= 0.25; |
+ } |
+ |
+ // Convert the adjustment factor to a qindex delta |
+ // on active_best_quality. |
+ q_val = vp9_convert_qindex_to_q(active_best_quality); |
+ active_best_quality += vp9_compute_qdelta(cpi, q_val, q_val * |
+ q_adj_factor); |
+ } |
+#else |
+ double current_q; |
+ // Force the KF quantizer to be 30% of the active_worst_quality. |
+ current_q = vp9_convert_qindex_to_q(active_worst_quality); |
+ active_best_quality = active_worst_quality |
+ + vp9_compute_qdelta(cpi, current_q, current_q * 0.3); |
+#endif |
+ } else if (!rc->is_src_frame_alt_ref && |
+ (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
+ // Use the lower of active_worst_quality and recent |
+ // average Q as basis for GF/ARF best Q limit unless last frame was |
+ // a key frame. |
+ if (rc->frames_since_key > 1 && |
+ rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) { |
+ q = rc->avg_frame_qindex[INTER_FRAME]; |
+ } else { |
+ q = rc->avg_frame_qindex[KEY_FRAME]; |
+ } |
+ // For constrained quality dont allow Q less than the cq level |
+ if (oxcf->end_usage == USAGE_CONSTRAINED_QUALITY) { |
+ if (q < cpi->cq_target_quality) |
+ q = cpi->cq_target_quality; |
+ if (rc->frames_since_key > 1) { |
+ active_best_quality = get_active_quality(q, rc->gfu_boost, |
+ gf_low, gf_high, |
+ afq_low_motion_minq, |
+ afq_high_motion_minq); |
+ } else { |
+ active_best_quality = get_active_quality(q, rc->gfu_boost, |
+ gf_low, gf_high, |
+ gf_low_motion_minq, |
+ gf_high_motion_minq); |
+ } |
+ // Constrained quality use slightly lower active best. |
+ active_best_quality = active_best_quality * 15 / 16; |
+ |
+ } else if (oxcf->end_usage == USAGE_CONSTANT_QUALITY) { |
+ if (!cpi->refresh_alt_ref_frame) { |
+ active_best_quality = cpi->cq_target_quality; |
+ } else { |
+ if (rc->frames_since_key > 1) { |
+ active_best_quality = get_active_quality( |
+ q, rc->gfu_boost, gf_low, gf_high, |
+ afq_low_motion_minq, afq_high_motion_minq); |
+ } else { |
+ active_best_quality = get_active_quality( |
+ q, rc->gfu_boost, gf_low, gf_high, |
+ gf_low_motion_minq, gf_high_motion_minq); |
+ } |
+ } |
+ } else { |
+ active_best_quality = get_active_quality( |
+ q, rc->gfu_boost, gf_low, gf_high, |
+ gf_low_motion_minq, gf_high_motion_minq); |
+ } |
+ } else { |
+ if (oxcf->end_usage == USAGE_CONSTANT_QUALITY) { |
+ active_best_quality = cpi->cq_target_quality; |
+ } else { |
+ // Use the lower of active_worst_quality and recent/average Q. |
+ if (cm->current_video_frame > 1) |
+ active_best_quality = inter_minq[rc->avg_frame_qindex[INTER_FRAME]]; |
+ else |
+ active_best_quality = inter_minq[rc->avg_frame_qindex[KEY_FRAME]]; |
+ // For the constrained quality mode we don't want |
+ // q to fall below the cq level. |
+ if ((oxcf->end_usage == USAGE_CONSTRAINED_QUALITY) && |
+ (active_best_quality < cpi->cq_target_quality)) { |
+ // If we are strongly undershooting the target rate in the last |
+ // frames then use the user passed in cq value not the auto |
+ // cq value. |
+ if (rc->rolling_actual_bits < rc->min_frame_bandwidth) |
+ active_best_quality = oxcf->cq_level; |
+ else |
+ active_best_quality = cpi->cq_target_quality; |
+ } |
+ } |
+ } |
+ |
+ // Clip the active best and worst quality values to limits |
+ active_best_quality = clamp(active_best_quality, |
+ rc->best_quality, rc->worst_quality); |
+ active_worst_quality = clamp(active_worst_quality, |
+ active_best_quality, rc->worst_quality); |
+ |
+ *top_index = active_worst_quality; |
+ *bottom_index = active_best_quality; |
+ |
+#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY |
+ // Limit Q range for the adaptive loop. |
+ if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) { |
+ if (!(cm->current_video_frame == 0)) |
+ *top_index = (active_worst_quality + active_best_quality * 3) / 4; |
+ } else if (!rc->is_src_frame_alt_ref && |
+ (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
+ *top_index = (active_worst_quality + active_best_quality) / 2; |
+ } |
+#endif |
+ if (oxcf->end_usage == USAGE_CONSTANT_QUALITY) { |
+ q = active_best_quality; |
+ // Special case code to try and match quality with forced key frames |
+ } else if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced) { |
+ q = rc->last_boosted_qindex; |
+ } else { |
+ q = vp9_rc_regulate_q(cpi, rc->this_frame_target, |
+ active_best_quality, active_worst_quality); |
+ if (q > *top_index) { |
+ // Special case when we are targeting the max allowed rate |
+ if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth) |
+ *top_index = q; |
+ else |
+ q = *top_index; |
+ } |
+ } |
+#if CONFIG_MULTIPLE_ARF |
+ // Force the quantizer determined by the coding order pattern. |
+ if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) && |
+ cpi->oxcf.end_usage != USAGE_CONSTANT_QUALITY) { |
+ double new_q; |
+ double current_q = vp9_convert_qindex_to_q(active_worst_quality); |
+ int level = cpi->this_frame_weight; |
+ assert(level >= 0); |
+ new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level))); |
+ q = active_worst_quality + |
+ vp9_compute_qdelta(cpi, current_q, new_q); |
+ |
+ *bottom_index = q; |
+ *top_index = q; |
+ printf("frame:%d q:%d\n", cm->current_video_frame, q); |
+ } |
+#endif |
+ assert(*top_index <= rc->worst_quality && |
+ *top_index >= rc->best_quality); |
+ assert(*bottom_index <= rc->worst_quality && |
+ *bottom_index >= rc->best_quality); |
+ assert(q <= rc->worst_quality && q >= rc->best_quality); |
+ return q; |
+} |
+ |
+static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, |
+ int *bottom_index, |
+ int *top_index) { |
+ const VP9_COMMON *const cm = &cpi->common; |
+ const RATE_CONTROL *const rc = &cpi->rc; |
+ const VP9_CONFIG *const oxcf = &cpi->oxcf; |
+ int active_best_quality; |
+ int active_worst_quality = cpi->twopass.active_worst_quality; |
+ int q; |
+ |
+ if (frame_is_intra_only(cm)) { |
+#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 |
+ // based on the ambient Q to reduce the risk of popping. |
+ if (rc->this_key_frame_forced) { |
+ int qindex = rc->last_boosted_qindex; |
+ double last_boosted_q = vp9_convert_qindex_to_q(qindex); |
+ int delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q, |
+ (last_boosted_q * 0.75)); |
+ active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); |
+ } else { |
+ // Not forced keyframe. |
+ double q_adj_factor = 1.0; |
+ double q_val; |
+ // Baseline value derived from cpi->active_worst_quality and kf boost. |
active_best_quality = get_active_quality(active_worst_quality, |
rc->kf_boost, |
kf_low, kf_high, |
@@ -620,7 +889,6 @@ |
#endif |
} else if (!rc->is_src_frame_alt_ref && |
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
- |
// Use the lower of active_worst_quality and recent |
// average Q as basis for GF/ARF best Q limit unless last frame was |
// a key frame. |
@@ -671,13 +939,7 @@ |
if (oxcf->end_usage == USAGE_CONSTANT_QUALITY) { |
active_best_quality = cpi->cq_target_quality; |
} else { |
- if (cpi->pass == 0 && |
- rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) |
- // 1-pass: for now, use the average Q for the active_best, if its lower |
- // than active_worst. |
- active_best_quality = inter_minq[rc->avg_frame_qindex[INTER_FRAME]]; |
- else |
- active_best_quality = inter_minq[active_worst_quality]; |
+ active_best_quality = inter_minq[active_worst_quality]; |
// For the constrained quality mode we don't want |
// q to fall below the cq level. |
@@ -694,7 +956,7 @@ |
} |
} |
- // Clip the active best and worst quality values to limits |
+ // Clip the active best and worst quality values to limits. |
if (active_worst_quality > rc->worst_quality) |
active_worst_quality = rc->worst_quality; |
@@ -713,8 +975,7 @@ |
#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY |
// Limit Q range for the adaptive loop. |
if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) { |
- if (!(cpi->pass == 0 && cm->current_video_frame == 0)) |
- *top_index = (active_worst_quality + active_best_quality * 3) / 4; |
+ *top_index = (active_worst_quality + active_best_quality * 3) / 4; |
} else if (!rc->is_src_frame_alt_ref && |
(oxcf->end_usage != USAGE_STREAM_FROM_SERVER) && |
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
@@ -724,14 +985,14 @@ |
if (oxcf->end_usage == USAGE_CONSTANT_QUALITY) { |
q = active_best_quality; |
- // Special case code to try and match quality with forced key frames |
+ // Special case code to try and match quality with forced key frames. |
} else if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced) { |
q = rc->last_boosted_qindex; |
} else { |
q = vp9_rc_regulate_q(cpi, rc->this_frame_target, |
active_best_quality, active_worst_quality); |
if (q > *top_index) { |
- // Special case when we are targeting the max allowed rate |
+ // Special case when we are targeting the max allowed rate. |
if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth) |
*top_index = q; |
else |
@@ -763,6 +1024,35 @@ |
return q; |
} |
+int vp9_rc_pick_q_and_bounds(const VP9_COMP *cpi, |
+ int *bottom_index, |
+ int *top_index) { |
+ int q; |
+ if (cpi->pass == 0) { |
+ if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) |
+ q = rc_pick_q_and_bounds_one_pass_cbr(cpi, bottom_index, top_index); |
+ else |
+ q = rc_pick_q_and_bounds_one_pass_vbr(cpi, bottom_index, top_index); |
+ } else { |
+ q = rc_pick_q_and_bounds_two_pass(cpi, bottom_index, top_index); |
+ } |
+ |
+ // JBB : This is realtime mode. In real time mode the first frame |
+ // should be larger. Q of 0 is disabled because we force tx size to be |
+ // 16x16... |
+ if (cpi->sf.use_pick_mode) { |
+ if (cpi->common.current_video_frame == 0) |
+ q /= 3; |
+ if (q == 0) |
+ q++; |
+ if (q < *bottom_index) |
+ *bottom_index = q; |
+ else if (q > *top_index) |
+ *top_index = q; |
+ } |
+ return q; |
+} |
+ |
void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, |
int this_frame_target, |
int *frame_under_shoot_limit, |
@@ -806,24 +1096,14 @@ |
} |
} |
-// return of 0 means drop frame |
-int vp9_rc_pick_frame_size_target(VP9_COMP *cpi) { |
+void vp9_rc_set_frame_target(VP9_COMP *cpi, int target) { |
const VP9_COMMON *const cm = &cpi->common; |
RATE_CONTROL *const rc = &cpi->rc; |
- if (cm->frame_type == KEY_FRAME) |
- calc_iframe_target_size(cpi); |
- else |
- calc_pframe_target_size(cpi); |
- |
- // Clip the frame target to the maximum allowed value. |
- if (rc->this_frame_target > rc->max_frame_bandwidth) |
- rc->this_frame_target = rc->max_frame_bandwidth; |
- |
+ rc->this_frame_target = target; |
// Target rate per SB64 (including partial SB64s. |
rc->sb64_target_rate = ((int64_t)rc->this_frame_target * 64 * 64) / |
(cm->width * cm->height); |
- return 1; |
} |
static void update_alt_ref_frame_stats(VP9_COMP *cpi) { |
@@ -867,11 +1147,14 @@ |
void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { |
VP9_COMMON *const cm = &cpi->common; |
RATE_CONTROL *const rc = &cpi->rc; |
+ |
+ cm->last_frame_type = cm->frame_type; |
// Update rate control heuristics |
rc->projected_frame_size = (bytes_used << 3); |
// Post encode loop adjustment of Q prediction. |
- vp9_rc_update_rate_correction_factors(cpi, (cpi->sf.recode_loop || |
+ vp9_rc_update_rate_correction_factors( |
+ cpi, (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF || |
cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) ? 2 : 0); |
// Keep a record of last Q and ambient average Q. |
@@ -880,7 +1163,8 @@ |
rc->avg_frame_qindex[KEY_FRAME] = ROUND_POWER_OF_TWO( |
3 * rc->avg_frame_qindex[KEY_FRAME] + cm->base_qindex, 2); |
} else if (!rc->is_src_frame_alt_ref && |
- (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
+ (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) && |
+ !(cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) { |
rc->last_q[2] = cm->base_qindex; |
rc->avg_frame_qindex[2] = ROUND_POWER_OF_TWO( |
3 * rc->avg_frame_qindex[2] + cm->base_qindex, 2); |
@@ -909,7 +1193,7 @@ |
rc->last_boosted_qindex = cm->base_qindex; |
} |
- vp9_update_buffer_level(cpi, rc->projected_frame_size); |
+ update_buffer_level(cpi, rc->projected_frame_size); |
// Rolling monitors of whether we are over or underspending used to help |
// regulate min and Max Q in two pass. |
@@ -931,22 +1215,6 @@ |
rc->total_target_vs_actual += (rc->this_frame_target - |
rc->projected_frame_size); |
-#ifndef DISABLE_RC_LONG_TERM_MEM |
- // Update bits left to the kf and gf groups to account for overshoot or |
- // undershoot on these frames |
- if (cm->frame_type == KEY_FRAME) { |
- cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - |
- cpi->rc.projected_frame_size; |
- |
- cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0); |
- } else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) { |
- cpi->twopass.gf_group_bits += cpi->rc.this_frame_target - |
- cpi->rc.projected_frame_size; |
- |
- 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. |
@@ -964,6 +1232,169 @@ |
} |
void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) { |
+ // Update buffer level with zero size, update frame counters, and return. |
+ update_buffer_level(cpi, 0); |
+ cpi->common.last_frame_type = cpi->common.frame_type; |
cpi->rc.frames_since_key++; |
cpi->rc.frames_to_key--; |
} |
+ |
+static int test_for_kf_one_pass(VP9_COMP *cpi) { |
+ // Placeholder function for auto key frame |
+ return 0; |
+} |
+// Use this macro to turn on/off use of alt-refs in one-pass mode. |
+#define USE_ALTREF_FOR_ONE_PASS 1 |
+ |
+static int calc_pframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) { |
+ static const int af_ratio = 10; |
+ const RATE_CONTROL *rc = &cpi->rc; |
+ int target; |
+#if USE_ALTREF_FOR_ONE_PASS |
+ target = (!rc->is_src_frame_alt_ref && |
+ (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) ? |
+ (rc->av_per_frame_bandwidth * cpi->rc.baseline_gf_interval * af_ratio) / |
+ (cpi->rc.baseline_gf_interval + af_ratio - 1) : |
+ (rc->av_per_frame_bandwidth * cpi->rc.baseline_gf_interval) / |
+ (cpi->rc.baseline_gf_interval + af_ratio - 1); |
+#else |
+ target = rc->av_per_frame_bandwidth; |
+#endif |
+ return vp9_rc_clamp_pframe_target_size(cpi, target); |
+} |
+ |
+static int calc_iframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) { |
+ static const int kf_ratio = 25; |
+ const RATE_CONTROL *rc = &cpi->rc; |
+ int target = rc->av_per_frame_bandwidth * kf_ratio; |
+ return vp9_rc_clamp_iframe_target_size(cpi, target); |
+} |
+ |
+void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) { |
+ VP9_COMMON *const cm = &cpi->common; |
+ RATE_CONTROL *const rc = &cpi->rc; |
+ int target; |
+ if (!cpi->refresh_alt_ref_frame && |
+ (cm->current_video_frame == 0 || |
+ cm->frame_flags & FRAMEFLAGS_KEY || |
+ rc->frames_to_key == 0 || |
+ (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) { |
+ cm->frame_type = KEY_FRAME; |
+ rc->this_key_frame_forced = cm->current_video_frame != 0 && |
+ rc->frames_to_key == 0; |
+ rc->frames_to_key = cpi->key_frame_frequency; |
+ rc->kf_boost = DEFAULT_KF_BOOST; |
+ rc->source_alt_ref_active = 0; |
+ } else { |
+ cm->frame_type = INTER_FRAME; |
+ } |
+ if (rc->frames_till_gf_update_due == 0) { |
+ rc->baseline_gf_interval = DEFAULT_GF_INTERVAL; |
+ rc->frames_till_gf_update_due = rc->baseline_gf_interval; |
+ // NOTE: frames_till_gf_update_due must be <= frames_to_key. |
+ if (rc->frames_till_gf_update_due > rc->frames_to_key) |
+ rc->frames_till_gf_update_due = rc->frames_to_key; |
+ cpi->refresh_golden_frame = 1; |
+ rc->source_alt_ref_pending = USE_ALTREF_FOR_ONE_PASS; |
+ rc->gfu_boost = DEFAULT_GF_BOOST; |
+ } |
+ if (cm->frame_type == KEY_FRAME) |
+ target = calc_iframe_target_size_one_pass_vbr(cpi); |
+ else |
+ target = calc_pframe_target_size_one_pass_vbr(cpi); |
+ vp9_rc_set_frame_target(cpi, target); |
+} |
+ |
+static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { |
+ const VP9_CONFIG *oxcf = &cpi->oxcf; |
+ const RATE_CONTROL *rc = &cpi->rc; |
+ const int64_t diff = oxcf->optimal_buffer_level - rc->buffer_level; |
+ const int one_pct_bits = 1 + oxcf->optimal_buffer_level / 100; |
+ int min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4, |
+ FRAME_OVERHEAD_BITS); |
+ int target = rc->av_per_frame_bandwidth; |
+ if (cpi->svc.number_temporal_layers > 1 && |
+ cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { |
+ // Note that for layers, av_per_frame_bandwidth is the cumulative |
+ // per-frame-bandwidth. For the target size of this frame, use the |
+ // layer average frame size (i.e., non-cumulative per-frame-bw). |
+ int current_temporal_layer = cpi->svc.temporal_layer_id; |
+ const LAYER_CONTEXT *lc = &cpi->svc.layer_context[current_temporal_layer]; |
+ target = lc->avg_frame_size; |
+ min_frame_target = MAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS); |
+ } |
+ if (diff > 0) { |
+ // Lower the target bandwidth for this frame. |
+ const int pct_low = MIN(diff / one_pct_bits, oxcf->under_shoot_pct); |
+ target -= (target * pct_low) / 200; |
+ } else if (diff < 0) { |
+ // Increase the target bandwidth for this frame. |
+ const int pct_high = MIN(-diff / one_pct_bits, oxcf->over_shoot_pct); |
+ target += (target * pct_high) / 200; |
+ } |
+ return MAX(min_frame_target, target); |
+} |
+ |
+static int calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { |
+ const RATE_CONTROL *rc = &cpi->rc; |
+ |
+ if (cpi->common.current_video_frame == 0) { |
+ return cpi->oxcf.starting_buffer_level / 2; |
+ } else { |
+ const int initial_boost = 32; |
+ int kf_boost = MAX(initial_boost, (int)(2 * cpi->output_framerate - 16)); |
+ if (rc->frames_since_key < cpi->output_framerate / 2) { |
+ kf_boost = (int)(kf_boost * rc->frames_since_key / |
+ (cpi->output_framerate / 2)); |
+ } |
+ return ((16 + kf_boost) * rc->av_per_frame_bandwidth) >> 4; |
+ } |
+} |
+ |
+void vp9_rc_get_svc_params(VP9_COMP *cpi) { |
+ VP9_COMMON *const cm = &cpi->common; |
+ int target = cpi->rc.av_per_frame_bandwidth; |
+ if ((cm->current_video_frame == 0) || |
+ (cm->frame_flags & FRAMEFLAGS_KEY) || |
+ (cpi->oxcf.auto_key && (cpi->rc.frames_since_key % |
+ cpi->key_frame_frequency == 0))) { |
+ cm->frame_type = KEY_FRAME; |
+ cpi->rc.source_alt_ref_active = 0; |
+ if (cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { |
+ target = calc_iframe_target_size_one_pass_cbr(cpi); |
+ } |
+ } else { |
+ cm->frame_type = INTER_FRAME; |
+ if (cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { |
+ target = calc_pframe_target_size_one_pass_cbr(cpi); |
+ } |
+ } |
+ vp9_rc_set_frame_target(cpi, target); |
+ cpi->rc.frames_till_gf_update_due = INT_MAX; |
+ cpi->rc.baseline_gf_interval = INT_MAX; |
+} |
+ |
+void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) { |
+ VP9_COMMON *const cm = &cpi->common; |
+ RATE_CONTROL *const rc = &cpi->rc; |
+ int target; |
+ if ((cm->current_video_frame == 0 || |
+ cm->frame_flags & FRAMEFLAGS_KEY || |
+ rc->frames_to_key == 0 || |
+ (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) { |
+ cm->frame_type = KEY_FRAME; |
+ rc->this_key_frame_forced = cm->current_video_frame != 0 && |
+ rc->frames_to_key == 0; |
+ rc->frames_to_key = cpi->key_frame_frequency; |
+ rc->kf_boost = DEFAULT_KF_BOOST; |
+ rc->source_alt_ref_active = 0; |
+ target = calc_iframe_target_size_one_pass_cbr(cpi); |
+ } else { |
+ cm->frame_type = INTER_FRAME; |
+ target = calc_pframe_target_size_one_pass_cbr(cpi); |
+ } |
+ vp9_rc_set_frame_target(cpi, target); |
+ // Don't use gf_update by default in CBR mode. |
+ rc->frames_till_gf_update_due = INT_MAX; |
+ rc->baseline_gf_interval = INT_MAX; |
+} |