| 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;
|
| + }
|
| +}
|
|
|