Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(928)

Unified Diff: source/libvpx/vp9/encoder/vp9_ratectrl.c

Issue 1302353004: libvpx: Pull from upstream (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libvpx.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_ratectrl.h ('k') | source/libvpx/vp9/encoder/vp9_rd.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
+ }
+}
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_ratectrl.h ('k') | source/libvpx/vp9/encoder/vp9_rd.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698