aboutsummaryrefslogtreecommitdiff
path: root/libvpx/vp9/encoder/vp9_ratectrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvpx/vp9/encoder/vp9_ratectrl.c')
-rw-r--r--libvpx/vp9/encoder/vp9_ratectrl.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/libvpx/vp9/encoder/vp9_ratectrl.c b/libvpx/vp9/encoder/vp9_ratectrl.c
index 1eb8b50f0..27fea5d4e 100644
--- a/libvpx/vp9/encoder/vp9_ratectrl.c
+++ b/libvpx/vp9/encoder/vp9_ratectrl.c
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <string.h>
+#include "./vpx_dsp_rtcd.h"
#include "vpx_dsp/vpx_dsp_common.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
@@ -93,10 +94,17 @@ static int inter_minq_12[QINDEX_RANGE];
static int rtc_minq_12[QINDEX_RANGE];
#endif
+#ifdef AGGRESSIVE_VBR
+static int gf_high = 2400;
+static int gf_low = 400;
+static int kf_high = 4000;
+static int kf_low = 400;
+#else
static int gf_high = 2000;
static int gf_low = 400;
static int kf_high = 5000;
static int kf_low = 400;
+#endif
// Functions to compute the active minq lookup table entries based on a
// formulaic approach to facilitate easier adjustment of the Q tables.
@@ -126,9 +134,14 @@ static void init_minq_luts(int *kf_low_m, int *kf_high_m, int *arfgf_low,
const double maxq = vp9_convert_qindex_to_q(i, bit_depth);
kf_low_m[i] = get_minq_index(maxq, 0.000001, -0.0004, 0.150, bit_depth);
kf_high_m[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth);
+#ifdef AGGRESSIVE_VBR
+ arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.275, bit_depth);
+ inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.80, bit_depth);
+#else
arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.30, bit_depth);
- arfgf_high[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth);
inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth);
+#endif
+ arfgf_high[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth);
rtc[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth);
}
}
@@ -166,6 +179,17 @@ double vp9_convert_qindex_to_q(int qindex, vpx_bit_depth_t bit_depth) {
#endif
}
+int vp9_convert_q_to_qindex(double q_val, vpx_bit_depth_t bit_depth) {
+ int i;
+
+ for (i = 0; i < QINDEX_RANGE; ++i)
+ if (vp9_convert_qindex_to_q(i, bit_depth) >= q_val) break;
+
+ if (i == QINDEX_RANGE) i--;
+
+ return i;
+}
+
int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex,
double correction_factor, vpx_bit_depth_t bit_depth) {
const double q = vp9_convert_qindex_to_q(qindex, bit_depth);
@@ -523,6 +547,7 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi) {
int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
int active_best_quality, int active_worst_quality) {
const VP9_COMMON *const cm = &cpi->common;
+ CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
int q = active_worst_quality;
int last_error = INT_MAX;
int i, target_bits_per_mb, bits_per_mb_at_this_q;
@@ -537,7 +562,8 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
do {
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled &&
- cpi->svc.temporal_layer_id == 0) {
+ cr->apply_cyclic_refresh &&
+ (!cpi->oxcf.gf_cbr_boost_pct || !cpi->refresh_golden_frame)) {
bits_per_mb_at_this_q =
(int)vp9_cyclic_refresh_rc_bits_per_mb(cpi, i, correction_factor);
} else {
@@ -560,6 +586,8 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
// In CBR mode, this makes sure q is between oscillating Qs to prevent
// resonance.
if (cpi->oxcf.rc_mode == VPX_CBR &&
+ (!cpi->oxcf.gf_cbr_boost_pct ||
+ !(cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)) &&
(cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) &&
cpi->rc.q_1_frame != cpi->rc.q_2_frame) {
q = clamp(q, VPXMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame),
@@ -661,6 +689,17 @@ static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) {
? VPXMIN(rc->avg_frame_qindex[INTER_FRAME],
rc->avg_frame_qindex[KEY_FRAME])
: rc->avg_frame_qindex[INTER_FRAME];
+ // For SVC if the current base spatial layer was key frame, use the QP from
+ // that base layer for ambient_qp.
+ if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
+ int layer = LAYER_IDS_TO_IDX(0, cpi->svc.temporal_layer_id,
+ cpi->svc.number_temporal_layers);
+ const LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
+ if (lc->is_key_frame) {
+ const RATE_CONTROL *lrc = &lc->rc;
+ ambient_qp = VPXMIN(ambient_qp, lrc->last_q[KEY_FRAME]);
+ }
+ }
active_worst_quality = VPXMIN(rc->worst_quality, ambient_qp * 5 >> 2);
if (rc->buffer_level > rc->optimal_buffer_level) {
// Adjust down.
@@ -1325,10 +1364,6 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
RATE_CONTROL *const rc = &cpi->rc;
const int qindex = cm->base_qindex;
- if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
- vp9_cyclic_refresh_postencode(cpi);
- }
-
// Update rate control heuristics
rc->projected_frame_size = (int)(bytes_used << 3);
@@ -2135,9 +2170,14 @@ void adjust_gf_boost_lag_one_pass_vbr(VP9_COMP *cpi, uint64_t avg_sad_current) {
// Adjust factors for active_worst setting & af_ratio for next gf interval.
rc->fac_active_worst_inter = 150; // corresponds to 3/2 (= 150 /100).
rc->fac_active_worst_gf = 100;
- if (rate_err < 1.5 && !high_content) {
+ if (rate_err < 2.0 && !high_content) {
rc->fac_active_worst_inter = 120;
rc->fac_active_worst_gf = 90;
+ } else if (rate_err > 8.0 && rc->avg_frame_qindex[INTER_FRAME] < 16) {
+ // Increase active_worst faster at low Q if rate fluctuation is high.
+ rc->fac_active_worst_inter = 200;
+ if (rc->avg_frame_qindex[INTER_FRAME] < 8)
+ rc->fac_active_worst_inter = 400;
}
if (low_content && rc->avg_frame_low_motion > 80) {
rc->af_ratio_onepass_vbr = 15;
@@ -2175,9 +2215,12 @@ void adjust_gf_boost_lag_one_pass_vbr(VP9_COMP *cpi, uint64_t avg_sad_current) {
// in content and allow rate control to react.
// This function also handles special case of lag_in_frames, to measure content
// level in #future frames set by the lag_in_frames.
-void vp9_avg_source_sad(VP9_COMP *cpi) {
+void vp9_scene_detection_onepass(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
+#if CONFIG_VP9_HIGHBITDEPTH
+ if (cm->use_highbitdepth) return;
+#endif
rc->high_source_sad = 0;
if (cpi->Last_Source != NULL &&
cpi->Last_Source->y_width == cpi->Source->y_width &&
@@ -2239,6 +2282,7 @@ void vp9_avg_source_sad(VP9_COMP *cpi) {
const BLOCK_SIZE bsize = BLOCK_64X64;
// Loop over sub-sample of frame, compute average sad over 64x64 blocks.
uint64_t avg_sad = 0;
+ uint64_t tmp_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;
@@ -2251,15 +2295,14 @@ void vp9_avg_source_sad(VP9_COMP *cpi) {
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 the partition copy is on, compute for every superblock.
- if (cpi->sf.copy_partition_flag ||
- ((sbi_row > 0 && sbi_col > 0) &&
+ 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)))) {
+ tmp_sad = cpi->fn_ptr[bsize].sdf(src_y, src_ystride, last_src_y,
+ last_src_ystride);
+ avg_sad += tmp_sad;
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;