Index: source/libvpx/vp9/encoder/vp9_ratectrl.c |
diff --git a/source/libvpx/vp9/encoder/vp9_ratectrl.c b/source/libvpx/vp9/encoder/vp9_ratectrl.c |
index 7427ccfb9d4b1d76ca18de901f979c89d36e60f5..fdc55f78b79b538a6945f3477ef71400b5f30ddc 100644 |
--- a/source/libvpx/vp9/encoder/vp9_ratectrl.c |
+++ b/source/libvpx/vp9/encoder/vp9_ratectrl.c |
@@ -17,6 +17,7 @@ |
#include "vpx_mem/vpx_mem.h" |
#include "vpx_ports/mem.h" |
+#include "vpx_ports/system_state.h" |
#include "vp9/common/vp9_alloccommon.h" |
#include "vp9/encoder/vp9_aq_cyclicrefresh.h" |
@@ -24,7 +25,6 @@ |
#include "vp9/common/vp9_entropymode.h" |
#include "vp9/common/vp9_quant_common.h" |
#include "vp9/common/vp9_seg_common.h" |
-#include "vp9/common/vp9_systemdependent.h" |
#include "vp9/encoder/vp9_encodemv.h" |
#include "vp9/encoder/vp9_ratectrl.h" |
@@ -106,8 +106,8 @@ static int kf_low = 400; |
static int get_minq_index(double maxq, double x3, double x2, double x1, |
vpx_bit_depth_t bit_depth) { |
int i; |
- const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq, |
- maxq); |
+ const double minqtarget = VPXMIN(((x3 * maxq + x2) * maxq + x1) * maxq, |
+ maxq); |
// Special case handling to deal with the step from q2.0 |
// down to lossless mode represented by q 1.0. |
@@ -192,15 +192,15 @@ int vp9_estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs, |
vpx_bit_depth_t bit_depth) { |
const int bpm = (int)(vp9_rc_bits_per_mb(frame_type, q, correction_factor, |
bit_depth)); |
- return MAX(FRAME_OVERHEAD_BITS, |
- (int)((uint64_t)bpm * mbs) >> BPER_MB_NORMBITS); |
+ return VPXMAX(FRAME_OVERHEAD_BITS, |
+ (int)((uint64_t)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 VP9EncoderConfig *oxcf = &cpi->oxcf; |
- const int min_frame_target = MAX(rc->min_frame_bandwidth, |
- rc->avg_frame_bandwidth >> 5); |
+ const int min_frame_target = VPXMAX(rc->min_frame_bandwidth, |
+ rc->avg_frame_bandwidth >> 5); |
if (target < min_frame_target) |
target = min_frame_target; |
if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) { |
@@ -216,7 +216,7 @@ int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) { |
if (oxcf->rc_max_inter_bitrate_pct) { |
const int max_rate = rc->avg_frame_bandwidth * |
oxcf->rc_max_inter_bitrate_pct / 100; |
- target = MIN(target, max_rate); |
+ target = VPXMIN(target, max_rate); |
} |
return target; |
} |
@@ -227,7 +227,7 @@ int vp9_rc_clamp_iframe_target_size(const VP9_COMP *const cpi, int target) { |
if (oxcf->rc_max_intra_bitrate_pct) { |
const int max_rate = rc->avg_frame_bandwidth * |
oxcf->rc_max_intra_bitrate_pct / 100; |
- target = MIN(target, max_rate); |
+ target = VPXMIN(target, max_rate); |
} |
if (target > rc->max_frame_bandwidth) |
target = rc->max_frame_bandwidth; |
@@ -250,7 +250,8 @@ static void update_layer_buffer_level(SVC *svc, int encoded_frame_size) { |
lrc->bits_off_target += bits_off_for_this_layer; |
// Clip buffer level to maximum buffer size for the layer. |
- lrc->bits_off_target = MIN(lrc->bits_off_target, lrc->maximum_buffer_size); |
+ lrc->bits_off_target = |
+ VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size); |
lrc->buffer_level = lrc->bits_off_target; |
} |
} |
@@ -268,7 +269,7 @@ static void update_buffer_level(VP9_COMP *cpi, int encoded_frame_size) { |
} |
// Clip the buffer level to the maximum specified buffer size. |
- rc->bits_off_target = MIN(rc->bits_off_target, rc->maximum_buffer_size); |
+ rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size); |
rc->buffer_level = rc->bits_off_target; |
if (is_one_pass_cbr_svc(cpi)) { |
@@ -287,8 +288,8 @@ int vp9_rc_get_default_min_gf_interval( |
if (factor <= factor_safe) |
return default_interval; |
else |
- return MAX(default_interval, |
- (int)(MIN_GF_INTERVAL * factor / factor_safe + 0.5)); |
+ return VPXMAX(default_interval, |
+ (int)(MIN_GF_INTERVAL * factor / factor_safe + 0.5)); |
// Note this logic makes: |
// 4K24: 5 |
// 4K30: 6 |
@@ -296,9 +297,9 @@ int vp9_rc_get_default_min_gf_interval( |
} |
int vp9_rc_get_default_max_gf_interval(double framerate, int min_gf_interval) { |
- int interval = MIN(MAX_GF_INTERVAL, (int)(framerate * 0.75)); |
+ int interval = VPXMIN(MAX_GF_INTERVAL, (int)(framerate * 0.75)); |
interval += (interval & 0x01); // Round to even value |
- return MAX(interval, min_gf_interval); |
+ return VPXMAX(interval, min_gf_interval); |
} |
void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { |
@@ -455,7 +456,7 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi) { |
return; |
// Clear down mmx registers to allow floating point in what follows |
- vp9_clear_system_state(); |
+ vpx_clear_system_state(); |
// Work out how big we would have expected the frame to be at this Q given |
// the current correction factor. |
@@ -478,7 +479,7 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi) { |
// More heavily damped adjustment used if we have been oscillating either side |
// of target. |
adjustment_limit = 0.25 + |
- 0.5 * MIN(1, fabs(log10(0.01 * correction_factor))); |
+ 0.5 * VPXMIN(1, fabs(log10(0.01 * correction_factor))); |
cpi->rc.q_2_frame = cpi->rc.q_1_frame; |
cpi->rc.q_1_frame = cm->base_qindex; |
@@ -558,8 +559,8 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame, |
if (cpi->oxcf.rc_mode == VPX_CBR && |
(cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) && |
cpi->rc.q_1_frame != cpi->rc.q_2_frame) { |
- q = clamp(q, MIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame), |
- MAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame)); |
+ q = clamp(q, VPXMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame), |
+ VPXMAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame)); |
} |
return q; |
} |
@@ -617,7 +618,7 @@ static int calc_active_worst_quality_one_pass_vbr(const VP9_COMP *cpi) { |
: rc->last_q[INTER_FRAME] * 2; |
} |
} |
- return MIN(active_worst_quality, rc->worst_quality); |
+ return VPXMIN(active_worst_quality, rc->worst_quality); |
} |
// Adjust active_worst_quality level based on buffer level. |
@@ -635,6 +636,7 @@ static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) { |
int adjustment = 0; |
int active_worst_quality; |
int ambient_qp; |
+ unsigned int num_frames_weight_key = 5 * cpi->svc.number_temporal_layers; |
if (cm->frame_type == KEY_FRAME) |
return rc->worst_quality; |
// For ambient_qp we use minimum of avg_frame_qindex[KEY_FRAME/INTER_FRAME] |
@@ -642,11 +644,11 @@ static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) { |
// to worst_quality and updated with (3/4, 1/4) average in postencode_update. |
// So for first few frames following key, the qp of that key frame is weighted |
// into the active_worst_quality setting. |
- ambient_qp = (cm->current_video_frame < 5) ? |
- MIN(rc->avg_frame_qindex[INTER_FRAME], rc->avg_frame_qindex[KEY_FRAME]) : |
- rc->avg_frame_qindex[INTER_FRAME]; |
- active_worst_quality = MIN(rc->worst_quality, |
- ambient_qp * 5 / 4); |
+ ambient_qp = (cm->current_video_frame < num_frames_weight_key) ? |
+ VPXMIN(rc->avg_frame_qindex[INTER_FRAME], |
+ rc->avg_frame_qindex[KEY_FRAME]) : |
+ rc->avg_frame_qindex[INTER_FRAME]; |
+ active_worst_quality = VPXMIN(rc->worst_quality, ambient_qp * 5 / 4); |
if (rc->buffer_level > rc->optimal_buffer_level) { |
// Adjust down. |
// Maximum limit for down adjustment, ~30%. |
@@ -699,7 +701,7 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, |
int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, |
(last_boosted_q * 0.75), |
cm->bit_depth); |
- active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); |
+ active_best_quality = VPXMAX(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; |
@@ -764,7 +766,7 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, |
!rc->this_key_frame_forced && |
!(cm->current_video_frame == 0)) { |
int qdelta = 0; |
- vp9_clear_system_state(); |
+ vpx_clear_system_state(); |
qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, |
active_worst_quality, 2.0, |
cm->bit_depth); |
@@ -823,7 +825,6 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, |
ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); |
if (frame_is_intra_only(cm)) { |
- |
// Handle the special case for key frames forced when we have reached |
// the maximum key frame interval. Here force the Q to a range |
// based on the ambient Q to reduce the risk of popping. |
@@ -833,7 +834,7 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, |
int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, |
last_boosted_q * 0.75, |
cm->bit_depth); |
- active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); |
+ active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); |
} else { |
// not first frame of one pass and kf_boost is set |
double q_adj_factor = 1.0; |
@@ -915,7 +916,7 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, |
#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY |
{ |
int qdelta = 0; |
- vp9_clear_system_state(); |
+ vpx_clear_system_state(); |
// Limit Q range for the adaptive loop. |
if (cm->frame_type == KEY_FRAME && |
@@ -1002,21 +1003,21 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, |
int qindex; |
if (cpi->twopass.last_kfgroup_zeromotion_pct >= STATIC_MOTION_THRESH) { |
- qindex = MIN(rc->last_kf_qindex, rc->last_boosted_qindex); |
+ qindex = VPXMIN(rc->last_kf_qindex, rc->last_boosted_qindex); |
active_best_quality = qindex; |
last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); |
delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, |
last_boosted_q * 1.25, |
cm->bit_depth); |
- active_worst_quality = MIN(qindex + delta_qindex, active_worst_quality); |
- |
+ active_worst_quality = |
+ VPXMIN(qindex + delta_qindex, active_worst_quality); |
} else { |
qindex = rc->last_boosted_qindex; |
last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); |
delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, |
last_boosted_q * 0.75, |
cm->bit_depth); |
- active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); |
+ active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); |
} |
} else { |
// Not forced keyframe. |
@@ -1109,15 +1110,15 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, |
} |
#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY |
- vp9_clear_system_state(); |
+ vpx_clear_system_state(); |
// Static forced key frames Q restrictions dealt with elsewhere. |
if (!((frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi))) || |
!rc->this_key_frame_forced || |
(cpi->twopass.last_kfgroup_zeromotion_pct < STATIC_MOTION_THRESH)) { |
int qdelta = vp9_frame_type_qdelta(cpi, gf_group->rf_level[gf_group->index], |
active_worst_quality); |
- active_worst_quality = MAX(active_worst_quality + qdelta, |
- active_best_quality); |
+ active_worst_quality = VPXMAX(active_worst_quality + qdelta, |
+ active_best_quality); |
} |
#endif |
@@ -1126,7 +1127,8 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, |
int qdelta = vp9_compute_qdelta_by_rate(rc, cm->frame_type, |
active_best_quality, 2.0, |
cm->bit_depth); |
- active_best_quality = MAX(active_best_quality + qdelta, rc->best_quality); |
+ active_best_quality = |
+ VPXMAX(active_best_quality + qdelta, rc->best_quality); |
} |
active_best_quality = clamp(active_best_quality, |
@@ -1141,7 +1143,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, |
rc->this_key_frame_forced) { |
// If static since last kf use better of last boosted and last kf q. |
if (cpi->twopass.last_kfgroup_zeromotion_pct >= STATIC_MOTION_THRESH) { |
- q = MIN(rc->last_kf_qindex, rc->last_boosted_qindex); |
+ q = VPXMIN(rc->last_kf_qindex, rc->last_boosted_qindex); |
} else { |
q = rc->last_boosted_qindex; |
} |
@@ -1203,9 +1205,9 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, |
// For very small rate targets where the fractional adjustment |
// may be tiny make sure there is at least a minimum range. |
const int tolerance = (cpi->sf.recode_tolerance * frame_target) / 100; |
- *frame_under_shoot_limit = MAX(frame_target - tolerance - 200, 0); |
- *frame_over_shoot_limit = MIN(frame_target + tolerance + 200, |
- cpi->rc.max_frame_bandwidth); |
+ *frame_under_shoot_limit = VPXMAX(frame_target - tolerance - 200, 0); |
+ *frame_over_shoot_limit = VPXMIN(frame_target + tolerance + 200, |
+ cpi->rc.max_frame_bandwidth); |
} |
} |
@@ -1286,6 +1288,18 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { |
rc->last_q[KEY_FRAME] = qindex; |
rc->avg_frame_qindex[KEY_FRAME] = |
ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2); |
+ if (cpi->use_svc) { |
+ int i = 0; |
+ SVC *svc = &cpi->svc; |
+ for (i = 0; i < svc->number_temporal_layers; ++i) { |
+ const int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, i, |
+ svc->number_temporal_layers); |
+ LAYER_CONTEXT *lc = &svc->layer_context[layer]; |
+ RATE_CONTROL *lrc = &lc->rc; |
+ lrc->last_q[KEY_FRAME] = rc->last_q[KEY_FRAME]; |
+ lrc->avg_frame_qindex[KEY_FRAME] = rc->avg_frame_qindex[KEY_FRAME]; |
+ } |
+ } |
} else { |
if (rc->is_src_frame_alt_ref || |
!(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) || |
@@ -1339,13 +1353,15 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { |
rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits; |
- if (is_altref_enabled(cpi) && 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 (!cpi->use_svc) { |
+ if (is_altref_enabled(cpi) && 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) |
rc->frames_since_key = 0; |
@@ -1444,7 +1460,8 @@ static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { |
const SVC *const svc = &cpi->svc; |
const int64_t diff = rc->optimal_buffer_level - rc->buffer_level; |
const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100; |
- int min_frame_target = MAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS); |
+ int min_frame_target = |
+ VPXMAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS); |
int target; |
if (oxcf->gf_cbr_boost_pct) { |
@@ -1466,23 +1483,24 @@ static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { |
svc->temporal_layer_id, svc->number_temporal_layers); |
const LAYER_CONTEXT *lc = &svc->layer_context[layer]; |
target = lc->avg_frame_size; |
- min_frame_target = MAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS); |
+ min_frame_target = VPXMAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS); |
} |
if (diff > 0) { |
// Lower the target bandwidth for this frame. |
- const int pct_low = (int)MIN(diff / one_pct_bits, oxcf->under_shoot_pct); |
+ const int pct_low = (int)VPXMIN(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 = (int)MIN(-diff / one_pct_bits, oxcf->over_shoot_pct); |
+ const int pct_high = |
+ (int)VPXMIN(-diff / one_pct_bits, oxcf->over_shoot_pct); |
target += (target * pct_high) / 200; |
} |
if (oxcf->rc_max_inter_bitrate_pct) { |
const int max_rate = rc->avg_frame_bandwidth * |
oxcf->rc_max_inter_bitrate_pct / 100; |
- target = MIN(target, max_rate); |
+ target = VPXMIN(target, max_rate); |
} |
- return MAX(min_frame_target, target); |
+ return VPXMAX(min_frame_target, target); |
} |
static int calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { |
@@ -1504,7 +1522,7 @@ static int calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { |
const LAYER_CONTEXT *lc = &svc->layer_context[layer]; |
framerate = lc->framerate; |
} |
- kf_boost = MAX(kf_boost, (int)(2 * framerate - 16)); |
+ kf_boost = VPXMAX(kf_boost, (int)(2 * framerate - 16)); |
if (rc->frames_since_key < framerate / 2) { |
kf_boost = (int)(kf_boost * rc->frames_since_key / |
(framerate / 2)); |
@@ -1712,7 +1730,7 @@ void vp9_rc_set_gf_interval_range(const VP9_COMP *const cpi, |
rc->max_gf_interval = rc->static_scene_max_gf_interval; |
// Clamp min to max |
- rc->min_gf_interval = MIN(rc->min_gf_interval, rc->max_gf_interval); |
+ rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval); |
} |
void vp9_rc_update_framerate(VP9_COMP *cpi) { |
@@ -1725,7 +1743,8 @@ void vp9_rc_update_framerate(VP9_COMP *cpi) { |
rc->min_frame_bandwidth = (int)(rc->avg_frame_bandwidth * |
oxcf->two_pass_vbrmin_section / 100); |
- rc->min_frame_bandwidth = MAX(rc->min_frame_bandwidth, FRAME_OVERHEAD_BITS); |
+ rc->min_frame_bandwidth = |
+ VPXMAX(rc->min_frame_bandwidth, FRAME_OVERHEAD_BITS); |
// A maximum bitrate for a frame is defined. |
// The baseline for this aligns with HW implementations that |
@@ -1736,8 +1755,8 @@ void vp9_rc_update_framerate(VP9_COMP *cpi) { |
// specifies lossless encode. |
vbr_max_bits = (int)(((int64_t)rc->avg_frame_bandwidth * |
oxcf->two_pass_vbrmax_section) / 100); |
- rc->max_frame_bandwidth = MAX(MAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P), |
- vbr_max_bits); |
+ rc->max_frame_bandwidth = |
+ VPXMAX(VPXMAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P), vbr_max_bits); |
vp9_rc_set_gf_interval_range(cpi, rc); |
} |
@@ -1775,12 +1794,12 @@ static void vbr_rate_correction(VP9_COMP *cpi, int *this_frame_target) { |
// Dont do it for kf,arf,gf or overlay frames. |
if (!frame_is_kf_gf_arf(cpi) && !rc->is_src_frame_alt_ref && |
rc->vbr_bits_off_target_fast) { |
- int one_frame_bits = MAX(rc->avg_frame_bandwidth, *this_frame_target); |
+ int one_frame_bits = VPXMAX(rc->avg_frame_bandwidth, *this_frame_target); |
int fast_extra_bits; |
- fast_extra_bits = |
- (int)MIN(rc->vbr_bits_off_target_fast, one_frame_bits); |
- fast_extra_bits = (int)MIN(fast_extra_bits, |
- MAX(one_frame_bits / 8, rc->vbr_bits_off_target_fast / 8)); |
+ fast_extra_bits = (int)VPXMIN(rc->vbr_bits_off_target_fast, one_frame_bits); |
+ fast_extra_bits = (int)VPXMIN( |
+ fast_extra_bits, |
+ VPXMAX(one_frame_bits / 8, rc->vbr_bits_off_target_fast / 8)); |
*this_frame_target += (int)fast_extra_bits; |
rc->vbr_bits_off_target_fast -= fast_extra_bits; |
} |
@@ -1886,3 +1905,86 @@ int vp9_resize_one_pass_cbr(VP9_COMP *cpi) { |
} |
return resize_now; |
} |
+ |
+// Compute average source sad (temporal sad: between current source and |
+// previous source) over a subset of superblocks. Use this is detect big changes |
+// in content and allow rate control to react. |
+// TODO(marpan): Superblock sad is computed again in variance partition for |
+// non-rd mode (but based on last reconstructed frame). Should try to reuse |
+// these computations. |
+void vp9_avg_source_sad(VP9_COMP *cpi) { |
+ VP9_COMMON * const cm = &cpi->common; |
+ RATE_CONTROL *const rc = &cpi->rc; |
+ rc->high_source_sad = 0; |
+ if (cpi->Last_Source != NULL) { |
+ const uint8_t *src_y = cpi->Source->y_buffer; |
+ const int src_ystride = cpi->Source->y_stride; |
+ const uint8_t *last_src_y = cpi->Last_Source->y_buffer; |
+ const int last_src_ystride = cpi->Last_Source->y_stride; |
+ int sbi_row, sbi_col; |
+ const BLOCK_SIZE bsize = BLOCK_64X64; |
+ // Loop over sub-sample of frame, and compute average sad over 64x64 blocks. |
+ uint64_t avg_sad = 0; |
+ int num_samples = 0; |
+ int sb_cols = (cm->mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; |
+ int sb_rows = (cm->mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; |
+ for (sbi_row = 0; sbi_row < sb_rows; sbi_row ++) { |
+ for (sbi_col = 0; sbi_col < sb_cols; sbi_col ++) { |
+ // Checker-board pattern, ignore boundary. |
+ if ((sbi_row > 0 && sbi_col > 0) && |
+ (sbi_row < sb_rows - 1 && sbi_col < sb_cols - 1) && |
+ ((sbi_row % 2 == 0 && sbi_col % 2 == 0) || |
+ (sbi_row % 2 != 0 && sbi_col % 2 != 0))) { |
+ num_samples++; |
+ avg_sad += cpi->fn_ptr[bsize].sdf(src_y, |
+ src_ystride, |
+ last_src_y, |
+ last_src_ystride); |
+ } |
+ src_y += 64; |
+ last_src_y += 64; |
+ } |
+ src_y += (src_ystride << 6) - (sb_cols << 6); |
+ last_src_y += (last_src_ystride << 6) - (sb_cols << 6); |
+ } |
+ if (num_samples > 0) |
+ avg_sad = avg_sad / num_samples; |
+ // Set high_source_sad flag if we detect very high increase in avg_sad |
+ // between current and the previous frame value(s). Use a minimum threshold |
+ // for cases where there is small change from content that is completely |
+ // static. |
+ if (avg_sad > VPXMAX(4000, (rc->avg_source_sad << 3)) && |
+ rc->frames_since_key > 1) |
+ rc->high_source_sad = 1; |
+ else |
+ rc->high_source_sad = 0; |
+ rc->avg_source_sad = (rc->avg_source_sad + avg_sad) >> 1; |
+ } |
+} |
+ |
+// Test if encoded frame will significantly overshoot the target bitrate, and |
+// if so, set the QP, reset/adjust some rate control parameters, and return 1. |
+int vp9_encodedframe_overshoot(VP9_COMP *cpi, |
+ int frame_size, |
+ int *q) { |
+ VP9_COMMON * const cm = &cpi->common; |
+ RATE_CONTROL *const rc = &cpi->rc; |
+ int thresh_qp = 3 * (rc->worst_quality >> 2); |
+ int thresh_rate = rc->avg_frame_bandwidth * 10; |
+ if (cm->base_qindex < thresh_qp && |
+ frame_size > thresh_rate) { |
+ // Force a re-encode, and for now use max-QP. |
+ *q = cpi->rc.worst_quality; |
+ // Adjust avg_frame_qindex and buffer_level, as these parameters will affect |
+ // QP selection for subsequent frames. If they have settled down to a very |
+ // different (low QP) state, then not re-adjusting them may cause next |
+ // frame to select low QP and overshoot again. |
+ // TODO(marpan): Check if rate correction factor should also be adjusted. |
+ cpi->rc.avg_frame_qindex[INTER_FRAME] = *q; |
+ rc->buffer_level = rc->optimal_buffer_level; |
+ rc->bits_off_target = rc->optimal_buffer_level; |
+ return 1; |
+ } else { |
+ return 0; |
+ } |
+} |