diff options
Diffstat (limited to 'vp9/encoder')
-rw-r--r-- | vp9/encoder/vp9_bitstream.c | 27 | ||||
-rw-r--r-- | vp9/encoder/vp9_block.h | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 15 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 173 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_int.h | 4 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 204 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.h | 20 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 12 |
8 files changed, 204 insertions, 253 deletions
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 97717fb9c..276bb13c7 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -553,7 +553,7 @@ static void write_modes(VP9_COMP *cpi, const TileInfo *const tile, static void build_tree_distribution(VP9_COMP *cpi, TX_SIZE tx_size) { vp9_coeff_probs_model *coef_probs = cpi->frame_coef_probs[tx_size]; vp9_coeff_count *coef_counts = cpi->coef_counts[tx_size]; - unsigned int (*eob_branch_ct)[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] = + unsigned int (*eob_branch_ct)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] = cpi->common.counts.eob_branch[tx_size]; vp9_coeff_stats *coef_branch_ct = cpi->frame_branch_ct[tx_size]; int i, j, k, l, m; @@ -561,9 +561,7 @@ static void build_tree_distribution(VP9_COMP *cpi, TX_SIZE tx_size) { for (i = 0; i < BLOCK_TYPES; ++i) { for (j = 0; j < REF_TYPES; ++j) { for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < PREV_COEF_CONTEXTS; ++l) { - if (l >= 3 && k == 0) - continue; + for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { vp9_tree_probs_from_distribution(vp9_coef_tree, coef_branch_ct[i][j][k][l], coef_counts[i][j][k][l]); @@ -606,15 +604,12 @@ static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi, for (i = 0; i < BLOCK_TYPES; ++i) { for (j = 0; j < REF_TYPES; ++j) { for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < PREV_COEF_CONTEXTS; ++l) { + for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { for (t = 0; t < entropy_nodes_update; ++t) { vp9_prob newp = new_frame_coef_probs[i][j][k][l][t]; const vp9_prob oldp = old_frame_coef_probs[i][j][k][l][t]; int s; int u = 0; - - if (l >= 3 && k == 0) - continue; if (t == PIVOT_NODE) s = vp9_prob_diff_update_savings_search_model( frame_branch_ct[i][j][k][l][0], @@ -645,7 +640,7 @@ static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi, for (i = 0; i < BLOCK_TYPES; ++i) { for (j = 0; j < REF_TYPES; ++j) { for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < PREV_COEF_CONTEXTS; ++l) { + for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { // calc probs and branch cts for this frame only for (t = 0; t < entropy_nodes_update; ++t) { vp9_prob newp = new_frame_coef_probs[i][j][k][l][t]; @@ -653,8 +648,6 @@ static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi, const vp9_prob upd = DIFF_UPDATE_PROB; int s; int u = 0; - if (l >= 3 && k == 0) - continue; if (t == PIVOT_NODE) s = vp9_prob_diff_update_savings_search_model( frame_branch_ct[i][j][k][l][0], @@ -686,25 +679,23 @@ static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi, case 1: case 2: { const int prev_coef_contexts_to_update = - (cpi->sf.use_fast_coef_updates == 2 ? - PREV_COEF_CONTEXTS >> 1 : PREV_COEF_CONTEXTS); + cpi->sf.use_fast_coef_updates == 2 ? COEFF_CONTEXTS >> 1 + : COEFF_CONTEXTS; const int coef_band_to_update = - (cpi->sf.use_fast_coef_updates == 2 ? - COEF_BANDS >> 1 : COEF_BANDS); + cpi->sf.use_fast_coef_updates == 2 ? COEF_BANDS >> 1 + : COEF_BANDS; int updates = 0; int noupdates_before_first = 0; for (i = 0; i < BLOCK_TYPES; ++i) { for (j = 0; j < REF_TYPES; ++j) { for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < PREV_COEF_CONTEXTS; ++l) { + for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { // calc probs and branch cts for this frame only for (t = 0; t < entropy_nodes_update; ++t) { vp9_prob newp = new_frame_coef_probs[i][j][k][l][t]; vp9_prob *oldp = old_frame_coef_probs[i][j][k][l] + t; int s; int u = 0; - if (l >= 3 && k == 0) - continue; if (l >= prev_coef_contexts_to_update || k >= coef_band_to_update) { u = 0; diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index a34a92917..f9a0226d8 100644 --- a/vp9/encoder/vp9_block.h +++ b/vp9/encoder/vp9_block.h @@ -87,7 +87,7 @@ struct macroblock_plane { /* The [2] dimension is for whether we skip the EOB node (i.e. if previous * coefficient in this block was zero) or not. */ typedef unsigned int vp9_coeff_cost[BLOCK_TYPES][REF_TYPES][COEF_BANDS][2] - [PREV_COEF_CONTEXTS][ENTROPY_TOKENS]; + [COEFF_CONTEXTS][ENTROPY_TOKENS]; typedef struct macroblock MACROBLOCK; struct macroblock { diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 30e18a37f..60830d00c 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -2170,21 +2170,6 @@ void vp9_second_pass(VP9_COMP *cpi) { (int)(cpi->twopass.bits_left / frames_left); cpi->twopass.est_max_qcorrection_factor = 1.0; - // Set a cq_level in constrained quality mode. - // Commenting this code out for now since it does not seem to be - // working well. - /* - if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { - int est_cq = estimate_cq(cpi, &cpi->twopass.total_left_stats, - section_target_bandwidth); - - if (est_cq > cpi->cq_target_quality) - cpi->cq_target_quality = est_cq; - else - cpi->cq_target_quality = cpi->oxcf.cq_level; - } - */ - // guess at maxq needed in 2nd pass cpi->twopass.maxq_max_limit = cpi->rc.worst_quality; cpi->twopass.maxq_min_limit = cpi->rc.best_quality; diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 7c36637a0..d40fc6673 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -143,8 +143,9 @@ static INLINE void Scale2Ratio(int mode, int *hr, int *hs) { } } -static void set_mvcost(VP9_COMP *cpi) { +static void set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) { MACROBLOCK *const mb = &cpi->mb; + cpi->common.allow_high_precision_mv = allow_high_precision_mv; if (cpi->common.allow_high_precision_mv) { mb->mvcost = mb->nmvcost_hp; mb->mvsadcost = mb->nmvsadcost_hp; @@ -234,7 +235,7 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { // Computes a q delta (in "q index" terms) to get from a starting q value // to a target value // target q value -int vp9_compute_qdelta(VP9_COMP *cpi, double qstart, double qtarget) { +int vp9_compute_qdelta(const VP9_COMP *cpi, double qstart, double qtarget) { int i; int start_index = cpi->rc.worst_quality; int target_index = cpi->rc.worst_quality; @@ -1115,8 +1116,8 @@ static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { vp9_change_config(ptr, oxcf); // Initialize active best and worst q and average q values. - cpi->rc.active_worst_quality = cpi->oxcf.worst_allowed_q; - cpi->rc.active_best_quality = cpi->oxcf.best_allowed_q; + cpi->rc.active_worst_quality = cpi->oxcf.worst_allowed_q; + cpi->rc.avg_frame_qindex = cpi->oxcf.worst_allowed_q; // Initialise the starting buffer levels @@ -1205,8 +1206,7 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { cm->reset_frame_context = 0; setup_features(cm); - cpi->common.allow_high_precision_mv = 0; // Default mv precision - set_mvcost(cpi); + set_high_precision_mv(cpi, 0); { int i; @@ -1253,12 +1253,8 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { // active values should only be modified if out of new range cpi->rc.active_worst_quality = clamp(cpi->rc.active_worst_quality, - cpi->oxcf.best_allowed_q, - cpi->oxcf.worst_allowed_q); - - cpi->rc.active_best_quality = clamp(cpi->rc.active_best_quality, - cpi->oxcf.best_allowed_q, - cpi->oxcf.worst_allowed_q); + cpi->rc.best_quality, + cpi->rc.worst_quality); cpi->cq_target_quality = cpi->oxcf.cq_level; @@ -2369,16 +2365,6 @@ static int find_fp_qindex() { return i; } -static void Pass1Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest, - unsigned int *frame_flags) { - (void) size; - (void) dest; - (void) frame_flags; - - vp9_set_quantizer(cpi, find_fp_qindex()); - vp9_first_pass(cpi); -} - #define WRITE_RECON_BUFFER 0 #if WRITE_RECON_BUFFER void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) { @@ -2470,16 +2456,9 @@ static int recode_loop_test(VP9_COMP *cpi, cpi->rc.projected_frame_size < ((cpi->rc.this_frame_target * 7) >> 3)) { force_recode = 1; - } else if (q > cpi->oxcf.cq_level && - cpi->rc.projected_frame_size < cpi->rc.min_frame_bandwidth && - cpi->rc.active_best_quality > cpi->oxcf.cq_level) { - // Severe undershoot and between auto and user cq level - force_recode = 1; - cpi->rc.active_best_quality = cpi->oxcf.cq_level; } } } - return force_recode; } @@ -2614,17 +2593,15 @@ static void full_to_model_count(unsigned int *model_count, model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN]; } -static void full_to_model_counts( - vp9_coeff_count_model *model_count, vp9_coeff_count *full_count) { +static void full_to_model_counts(vp9_coeff_count_model *model_count, + vp9_coeff_count *full_count) { int i, j, k, l; + for (i = 0; i < BLOCK_TYPES; ++i) for (j = 0; j < REF_TYPES; ++j) for (k = 0; k < COEF_BANDS; ++k) - for (l = 0; l < PREV_COEF_CONTEXTS; ++l) { - if (l >= 3 && k == 0) - continue; + for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) full_to_model_count(model_count[i][j][k][l], full_count[i][j][k][l]); - } } #if 0 && CONFIG_INTERNAL_STATS @@ -2639,7 +2616,7 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) { if (cpi->twopass.total_left_stats.coded_error != 0.0) fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %10d" - "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f" + "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f" "%6d %6d %5d %5d %5d %8.2f %10d %10.3f" "%10.3f %8d %10d %10d %10d\n", cpi->common.current_video_frame, cpi->rc.this_frame_target, @@ -2650,7 +2627,6 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) { (int)cpi->rc.total_actual_bits, cm->base_qindex, vp9_convert_qindex_to_q(cm->base_qindex), (double)vp9_dc_quant(cm->base_qindex, 0) / 4.0, - vp9_convert_qindex_to_q(cpi->rc.active_best_quality), vp9_convert_qindex_to_q(cpi->rc.active_worst_quality), cpi->rc.avg_q, vp9_convert_qindex_to_q(cpi->rc.ni_av_qi), vp9_convert_qindex_to_q(cpi->cq_target_quality), @@ -2699,6 +2675,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, int overshoot_seen = 0; int undershoot_seen = 0; int q_low = bottom_index, q_high = top_index; + do { vp9_clear_system_state(); // __asm emms; @@ -2816,11 +2793,13 @@ static void encode_with_recode_loop(VP9_COMP *cpi, // Update rate_correction_factor unless vp9_rc_update_rate_correction_factors(cpi, 0); - *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target); + *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, + bottom_index, top_index); while (*q < q_low && retries < 10) { vp9_rc_update_rate_correction_factors(cpi, 0); - *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target); + *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, + bottom_index, top_index); retries++; } } @@ -2831,18 +2810,12 @@ static void encode_with_recode_loop(VP9_COMP *cpi, q_high = *q > q_low ? *q - 1 : q_low; if (overshoot_seen || loop_count > 1) { - // Update rate_correction_factor unless - // cpi->rc.active_worst_quality has changed. vp9_rc_update_rate_correction_factors(cpi, 1); - *q = (q_high + q_low) / 2; } else { - // Update rate_correction_factor unless - // cpi->rc.active_worst_quality has changed. vp9_rc_update_rate_correction_factors(cpi, 0); - - *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target); - + *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, + bottom_index, top_index); // Special case reset for qlow for constrained quality. // This should only trigger where there is very substantial // undershoot on a frame and the auto cq level is above @@ -2854,7 +2827,8 @@ static void encode_with_recode_loop(VP9_COMP *cpi, while (*q > q_high && retries < 10) { vp9_rc_update_rate_correction_factors(cpi, 0); - *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target); + *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, + bottom_index, top_index); retries++; } } @@ -2893,8 +2867,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, int q; int frame_over_shoot_limit; int frame_under_shoot_limit; - int top_index; + int top_index_prop; int bottom_index; SPEED_FEATURES *const sf = &cpi->sf; @@ -3008,45 +2982,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, vp9_clear_system_state(); - // Decide how big to make the frame. - vp9_rc_pick_frame_size_and_bounds(cpi, - &frame_under_shoot_limit, - &frame_over_shoot_limit); - - q = vp9_rc_pick_q_and_adjust_q_bounds(cpi, - &bottom_index, - &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(cpi->rc.active_worst_quality); - int level = cpi->this_frame_weight; - assert(level >= 0); - - // Set quantizer steps at 10% increments. - new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level))); - q = cpi->rc.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 - vp9_zero(cpi->rd_tx_select_threshes); - if (!frame_is_intra_only(cm)) { - cm->mcomp_filter_type = DEFAULT_INTERP_FILTER; - /* TODO: Decide this more intelligently */ - cm->allow_high_precision_mv = q < HIGH_PRECISION_MV_QTHRESH; - set_mvcost(cpi); - } - #if CONFIG_VP9_POSTPROC if (cpi->oxcf.noise_sensitivity > 0) { int l = 0; @@ -3076,6 +3013,26 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, vp9_write_yuv_frame(cpi->Source); #endif + // Decide how big to make the frame. + vp9_rc_pick_frame_size_target(cpi); + + // Decide frame size bounds + vp9_rc_compute_frame_size_bounds(cpi, cpi->rc.this_frame_target, + &frame_under_shoot_limit, + &frame_over_shoot_limit); + + // Decide q and q bounds + q = vp9_rc_pick_q_and_adjust_q_bounds(cpi, + &bottom_index, + &top_index, + &top_index_prop); + + if (!frame_is_intra_only(cm)) { + cm->mcomp_filter_type = DEFAULT_INTERP_FILTER; + /* TODO: Decide this more intelligently */ + set_high_precision_mv(cpi, (q < HIGH_PRECISION_MV_QTHRESH)); + } + encode_with_recode_loop(cpi, size, dest, @@ -3161,7 +3118,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, * needed in motion search besides loopfilter */ cm->last_frame_type = cm->frame_type; - vp9_rc_postencode_update(cpi, *size, q); + vp9_rc_postencode_update(cpi, *size, top_index_prop); #if 0 output_frame_level_debug_stats(cpi); @@ -3282,6 +3239,21 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; } +static void Pass0Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest, + unsigned int *frame_flags) { + encode_frame_to_data_rate(cpi, size, dest, frame_flags); +} + +static void Pass1Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest, + unsigned int *frame_flags) { + (void) size; + (void) dest; + (void) frame_flags; + + vp9_set_quantizer(cpi, find_fp_qindex()); + vp9_first_pass(cpi); +} + static void Pass2Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags) { cpi->enable_encode_breakout = 1; @@ -3293,27 +3265,6 @@ static void Pass2Encode(VP9_COMP *cpi, unsigned long *size, // vp9_print_modes_and_motion_vectors(&cpi->common, "encode.stt"); vp9_twopass_postencode_update(cpi, *size); - - /* -#ifdef DISABLE_RC_LONG_TERM_MEM - cpi->twopass.bits_left -= cpi->rc.this_frame_target; -#else - cpi->twopass.bits_left -= 8 * *size; -#endif - - if (!cpi->refresh_alt_ref_frame) { - double lower_bounds_min_rate = FRAME_OVERHEAD_BITS * cpi->oxcf.framerate; - double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth - * cpi->oxcf.two_pass_vbrmin_section - / 100); - - if (two_pass_min_rate < lower_bounds_min_rate) - two_pass_min_rate = lower_bounds_min_rate; - - cpi->twopass.bits_left += (int64_t)(two_pass_min_rate - / cpi->oxcf.framerate); - } - */ } static void check_initial_width(VP9_COMP *cpi, YV12_BUFFER_CONFIG *sd) { @@ -3385,8 +3336,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, cpi->source = NULL; - cpi->common.allow_high_precision_mv = ALTREF_HIGH_PRECISION_MV; - set_mvcost(cpi); + set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV); // Should we code an alternate reference frame. if (cpi->oxcf.play_alternate && cpi->source_alt_ref_pending) { @@ -3626,7 +3576,8 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, } else if (cpi->pass == 2) { Pass2Encode(cpi, size, dest, frame_flags); } else { - encode_frame_to_data_rate(cpi, size, dest, frame_flags); + // One pass encode + Pass0Encode(cpi, size, dest, frame_flags); } if (cm->refresh_frame_context) diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index b8602e094..c6315653e 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -338,7 +338,7 @@ typedef struct { int worst_quality; int active_worst_quality; int best_quality; - int active_best_quality; + // int active_best_quality; } RATE_CONTROL; typedef struct VP9_COMP { @@ -695,7 +695,7 @@ int vp9_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest); void vp9_alloc_compressor_data(VP9_COMP *cpi); -int vp9_compute_qdelta(VP9_COMP *cpi, double qstart, double qtarget); +int vp9_compute_qdelta(const VP9_COMP *cpi, double qstart, double qtarget); static int get_token_alloc(int mb_rows, int mb_cols) { return mb_rows * mb_cols * (48 * 16 + 4); diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index bf1fc4f31..d631b3145 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -45,6 +45,10 @@ static int gf_high_motion_minq[QINDEX_RANGE]; static int inter_minq[QINDEX_RANGE]; static int afq_low_motion_minq[QINDEX_RANGE]; static int afq_high_motion_minq[QINDEX_RANGE]; +static int gf_high = 2000; +static int gf_low = 400; +static int kf_high = 5000; +static int kf_low = 400; // Functions to compute the active minq lookup table entries based on a // formulaic approach to facilitate easier adjustment of the Q tables. @@ -84,7 +88,7 @@ void vp9_rc_init_minq_luts(void) { kf_high_motion_minq[i] = calculate_minq_index(maxq, 0.000002, -0.0012, - 0.5, + 0.50, 0.0); gf_low_motion_minq[i] = calculate_minq_index(maxq, @@ -97,11 +101,6 @@ void vp9_rc_init_minq_luts(void) { -0.00125, 0.50, 0.0); - inter_minq[i] = calculate_minq_index(maxq, - 0.00000271, - -0.00113, - 0.75, - 0.0); afq_low_motion_minq[i] = calculate_minq_index(maxq, 0.0000015, -0.0009, @@ -112,6 +111,11 @@ void vp9_rc_init_minq_luts(void) { -0.00125, 0.55, 0.0); + inter_minq[i] = calculate_minq_index(maxq, + 0.00000271, + -0.00113, + 0.75, + 0.0); } } @@ -285,7 +289,6 @@ static void calc_pframe_target_size(VP9_COMP *cpi) { } } - void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) { const int q = cpi->common.base_qindex; int correction_factor = 100; @@ -333,7 +336,6 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) { break; } - // if ( (correction_factor > 102) && (Q < cpi->rc.active_worst_quality) ) if (correction_factor > 102) { // We are not already at the worst allowable quality correction_factor = @@ -367,8 +369,9 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) { } -int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame) { - int q = cpi->rc.active_worst_quality; +int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame, + int active_best_quality, int active_worst_quality) { + int q = active_worst_quality; int i; int last_error = INT_MAX; @@ -396,7 +399,7 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame) { target_bits_per_mb = (target_bits_per_frame << BPER_MB_NORMBITS) / cpi->common.MBs; - i = cpi->rc.active_best_quality; + i = active_best_quality; do { bits_per_mb_at_this_q = (int)vp9_rc_bits_per_mb(cpi->common.frame_type, i, @@ -412,7 +415,7 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame) { } else { last_error = bits_per_mb_at_this_q - target_bits_per_mb; } - } while (++i <= cpi->rc.active_worst_quality); + } while (++i <= active_worst_quality); return q; } @@ -438,14 +441,17 @@ static int get_active_quality(int q, return active_best_quality; } -int vp9_rc_pick_q_and_adjust_q_bounds(VP9_COMP *cpi, +int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi, int *bottom_index, - int *top_index) { - // Set an active best quality and if necessary active worst quality - int q = cpi->rc.active_worst_quality; - VP9_COMMON *const cm = &cpi->common; + int *top_index, + int *top_index_prop) { + const VP9_COMMON *const cm = &cpi->common; + int active_best_quality; + int active_worst_quality = cpi->rc.active_worst_quality; + int q; if (frame_is_intra_only(cm)) { + active_best_quality = cpi->rc.best_quality; #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 @@ -457,25 +463,19 @@ int vp9_rc_pick_q_and_adjust_q_bounds(VP9_COMP *cpi, delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q, (last_boosted_q * 0.75)); - - cpi->rc.active_best_quality = MAX(qindex + delta_qindex, - cpi->rc.best_quality); - } else if (cpi->pass == 0 && cpi->common.current_video_frame == 0) { - // If this is the first (key) frame in 1-pass, active best/worst is - // the user best/worst-allowed, and leave the top_index to active_worst. - cpi->rc.active_best_quality = cpi->oxcf.best_allowed_q; - cpi->rc.active_worst_quality = cpi->oxcf.worst_allowed_q; - } else { - int high = 5000; - int low = 400; + active_best_quality = MAX(qindex + delta_qindex, + cpi->rc.best_quality); + } else if (!(cpi->pass == 0 && cpi->common.current_video_frame == 0)) { + // not first frame of one pass double q_adj_factor = 1.0; double q_val; // Baseline value derived from cpi->active_worst_quality and kf boost - cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.kf_boost, - low, high, - kf_low_motion_minq, - kf_high_motion_minq); + active_best_quality = get_active_quality(active_worst_quality, + cpi->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)) { @@ -487,124 +487,128 @@ int vp9_rc_pick_q_and_adjust_q_bounds(VP9_COMP *cpi, // Convert the adjustment factor to a qindex delta // on active_best_quality. - q_val = vp9_convert_qindex_to_q(cpi->rc.active_best_quality); - cpi->rc.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(cpi->rc.active_worst_quality); - cpi->rc.active_best_quality = cpi->rc.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 (!cpi->is_src_frame_alt_ref && (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - int high = 2000; - int low = 400; - // Use the lower of cpi->rc.active_worst_quality and recent + // 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 (cpi->frames_since_key > 1 && - cpi->rc.avg_frame_qindex < cpi->rc.active_worst_quality) { + cpi->rc.avg_frame_qindex < active_worst_quality) { q = cpi->rc.avg_frame_qindex; + } else { + q = active_worst_quality; } // For constrained quality dont allow Q less than the cq level if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { if (q < cpi->cq_target_quality) q = cpi->cq_target_quality; if (cpi->frames_since_key > 1) { - cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, - low, high, - afq_low_motion_minq, - afq_high_motion_minq); + active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, + gf_low, gf_high, + afq_low_motion_minq, + afq_high_motion_minq); } else { - cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, - low, high, - gf_low_motion_minq, - gf_high_motion_minq); + active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, + gf_low, gf_high, + gf_low_motion_minq, + gf_high_motion_minq); } // Constrained quality use slightly lower active best. - cpi->rc.active_best_quality = cpi->rc.active_best_quality * 15 / 16; + active_best_quality = active_best_quality * 15 / 16; } else if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { if (!cpi->refresh_alt_ref_frame) { - cpi->rc.active_best_quality = cpi->cq_target_quality; + active_best_quality = cpi->cq_target_quality; } else { if (cpi->frames_since_key > 1) { - cpi->rc.active_best_quality = get_active_quality( - q, cpi->rc.gfu_boost, low, high, + active_best_quality = get_active_quality( + q, cpi->rc.gfu_boost, gf_low, gf_high, afq_low_motion_minq, afq_high_motion_minq); } else { - cpi->rc.active_best_quality = get_active_quality( - q, cpi->rc.gfu_boost, low, high, + active_best_quality = get_active_quality( + q, cpi->rc.gfu_boost, gf_low, gf_high, gf_low_motion_minq, gf_high_motion_minq); } } } else { - cpi->rc.active_best_quality = get_active_quality( - q, cpi->rc.gfu_boost, low, high, - gf_low_motion_minq, gf_high_motion_minq); + active_best_quality = get_active_quality( + q, cpi->rc.gfu_boost, gf_low, gf_high, + gf_low_motion_minq, gf_high_motion_minq); } } else { if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { - cpi->rc.active_best_quality = cpi->cq_target_quality; + active_best_quality = cpi->cq_target_quality; } else { - cpi->rc.active_best_quality = inter_minq[q]; - // 1-pass: for now, use the average Q for the active_best, if its lower - // than active_worst. - if (cpi->pass == 0 && (cpi->rc.avg_frame_qindex < q)) - cpi->rc.active_best_quality = inter_minq[cpi->rc.avg_frame_qindex]; + if (cpi->pass == 0 && + cpi->rc.avg_frame_qindex < 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[cpi->rc.avg_frame_qindex]; + else + active_best_quality = inter_minq[active_worst_quality]; // For the constrained quality mode we don't want // q to fall below the cq level. if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (cpi->rc.active_best_quality < cpi->cq_target_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 (cpi->rc.rolling_actual_bits < cpi->rc.min_frame_bandwidth) - cpi->rc.active_best_quality = cpi->oxcf.cq_level; + active_best_quality = cpi->oxcf.cq_level; else - cpi->rc.active_best_quality = cpi->cq_target_quality; + active_best_quality = cpi->cq_target_quality; } } } // Clip the active best and worst quality values to limits - if (cpi->rc.active_worst_quality > cpi->rc.worst_quality) - cpi->rc.active_worst_quality = cpi->rc.worst_quality; + if (active_worst_quality > cpi->rc.worst_quality) + active_worst_quality = cpi->rc.worst_quality; - if (cpi->rc.active_best_quality < cpi->rc.best_quality) - cpi->rc.active_best_quality = cpi->rc.best_quality; + if (active_best_quality < cpi->rc.best_quality) + active_best_quality = cpi->rc.best_quality; - if (cpi->rc.active_best_quality > cpi->rc.worst_quality) - cpi->rc.active_best_quality = cpi->rc.worst_quality; + if (active_best_quality > cpi->rc.worst_quality) + active_best_quality = cpi->rc.worst_quality; - if (cpi->rc.active_worst_quality < cpi->rc.active_best_quality) - cpi->rc.active_worst_quality = cpi->rc.active_best_quality; + if (active_worst_quality < active_best_quality) + active_worst_quality = active_best_quality; - *top_index = cpi->rc.active_worst_quality; - *bottom_index = cpi->rc.active_best_quality; + *top_index_prop = active_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 && !cpi->this_key_frame_forced) { if (!(cpi->pass == 0 && cpi->common.current_video_frame == 0)) { + *top_index = active_worst_quality; *top_index = - (cpi->rc.active_worst_quality + cpi->rc.active_best_quality * 3) / 4; + (active_worst_quality + active_best_quality * 3) / 4; } } else if (!cpi->is_src_frame_alt_ref && (cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER) && (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { *top_index = - (cpi->rc.active_worst_quality + cpi->rc.active_best_quality) / 2; + (active_worst_quality + active_best_quality) / 2; } #endif if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { - q = cpi->rc.active_best_quality; + q = active_best_quality; // Special case code to try and match quality with forced key frames } else if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { q = cpi->rc.last_boosted_qindex; @@ -614,17 +618,35 @@ int vp9_rc_pick_q_and_adjust_q_bounds(VP9_COMP *cpi, // 1-pass: for now, use per-frame-bw for target size of frame, scaled // by |x| for key frame. int scale = (cm->frame_type == KEY_FRAME) ? 5 : 1; - q = vp9_rc_regulate_q(cpi, scale * cpi->rc.av_per_frame_bandwidth); + q = vp9_rc_regulate_q(cpi, scale * cpi->rc.av_per_frame_bandwidth, + active_best_quality, active_worst_quality); } else { - q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target); + q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, + active_best_quality, active_worst_quality); } if (q > *top_index) 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 return q; } - static int estimate_keyframe_frequency(VP9_COMP *cpi) { int i; @@ -680,8 +702,7 @@ static void adjust_key_frame_context(VP9_COMP *cpi) { cpi->rc.key_frame_count++; } - -static void compute_frame_size_bounds(const VP9_COMP *cpi, +void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, int this_frame_target, int *frame_under_shoot_limit, int *frame_over_shoot_limit) { @@ -720,9 +741,7 @@ static void compute_frame_size_bounds(const VP9_COMP *cpi, } // return of 0 means drop frame -int vp9_rc_pick_frame_size_and_bounds(VP9_COMP *cpi, - int *frame_under_shoot_limit, - int *frame_over_shoot_limit) { +int vp9_rc_pick_frame_size_target(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; if (cm->frame_type == KEY_FRAME) @@ -733,13 +752,11 @@ int vp9_rc_pick_frame_size_and_bounds(VP9_COMP *cpi, // Target rate per SB64 (including partial SB64s. cpi->rc.sb64_target_rate = ((int64_t)cpi->rc.this_frame_target * 64 * 64) / (cpi->common.width * cpi->common.height); - compute_frame_size_bounds(cpi, cpi->rc.this_frame_target, - frame_under_shoot_limit, frame_over_shoot_limit); - return 1; } -void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used, int q) { +void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used, + int worst_q) { VP9_COMMON *const cm = &cpi->common; // Update rate control heuristics cpi->rc.projected_frame_size = (bytes_used << 3); @@ -750,6 +767,7 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used, int q) { cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) ? 2 : 0); cpi->rc.last_q[cm->frame_type] = cm->base_qindex; + cpi->rc.active_worst_quality = worst_q; // Keep record of last boosted (KF/KF/ARF) Q value. // If the current frame is coded at a lower Q then we also update it. @@ -777,11 +795,11 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used, int q) { if (cm->frame_type != KEY_FRAME && !cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) { cpi->rc.ni_frames++; - cpi->rc.tot_q += vp9_convert_qindex_to_q(q); + cpi->rc.tot_q += vp9_convert_qindex_to_q(cm->base_qindex); cpi->rc.avg_q = cpi->rc.tot_q / (double)cpi->rc.ni_frames; // Calculate the average Q for normal inter frames (not key or GFU frames). - cpi->rc.ni_tot_qi += q; + cpi->rc.ni_tot_qi += cm->base_qindex; cpi->rc.ni_av_qi = cpi->rc.ni_tot_qi / cpi->rc.ni_frames; } diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index f01d18672..063ac8f6a 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -31,23 +31,29 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var); void vp9_rc_init_minq_luts(void); // return of 0 means drop frame -// Changes rc.this_frame_target and rc.sb64_rate_target -int vp9_rc_pick_frame_size_and_bounds(VP9_COMP *cpi, +// Changes only rc.this_frame_target and rc.sb64_rate_target +int vp9_rc_pick_frame_size_target(VP9_COMP *cpi); + +void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, + int this_frame_target, int *frame_under_shoot_limit, int *frame_over_shoot_limit); + // Picks q and q bounds given the target for bits -int vp9_rc_pick_q_and_adjust_q_bounds(VP9_COMP *cpi, - int * bottom_index, - int * top_index); +int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi, + int *bottom_index, + int *top_index, + int *top_index_prop); // Estimates q to achieve a target bits per frame -int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame); +int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame, + int active_best_quality, int active_worst_quality); // Post encode update of the rate control parameters based // on bytes used and q used for the frame void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used, - int q_used); + int worst_q); // estimates bits per mb for a given qindex and correction factor int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex, diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 71a3650fe..399c534ec 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -154,11 +154,11 @@ static void fill_token_costs(vp9_coeff_cost *c, vp9_coeff_probs_model (*p)[BLOCK_TYPES]) { int i, j, k, l; TX_SIZE t; - for (t = TX_4X4; t <= TX_32X32; t++) - for (i = 0; i < BLOCK_TYPES; i++) - for (j = 0; j < REF_TYPES; j++) - for (k = 0; k < COEF_BANDS; k++) - for (l = 0; l < PREV_COEF_CONTEXTS; l++) { + for (t = TX_4X4; t <= TX_32X32; ++t) + for (i = 0; i < BLOCK_TYPES; ++i) + for (j = 0; j < REF_TYPES; ++j) + for (k = 0; k < COEF_BANDS; ++k) + for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { vp9_prob probs[ENTROPY_NODES]; vp9_model_to_full_probs(p[t][i][j][k][l], probs); vp9_cost_tokens((int *)c[t][i][j][k][0][l], probs, @@ -528,7 +528,7 @@ static INLINE int cost_coeffs(MACROBLOCK *x, const int eob = p->eobs[block]; const int16_t *const qcoeff_ptr = BLOCK_OFFSET(p->qcoeff, block); const int ref = mbmi->ref_frame[0] != INTRA_FRAME; - unsigned int (*token_costs)[2][PREV_COEF_CONTEXTS][ENTROPY_TOKENS] = + unsigned int (*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] = x->token_costs[tx_size][type][ref]; const ENTROPY_CONTEXT above_ec = !!*A, left_ec = !!*L; uint8_t *p_tok = x->token_cache; |