| Index: source/libvpx/vp9/encoder/vp9_firstpass.c
|
| diff --git a/source/libvpx/vp9/encoder/vp9_firstpass.c b/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| index 3f28e0ff346b5728e91e1457274b9a2cd535d232..9752668b15df0bba9cb9c6b08b524dcef71a1ec4 100644
|
| --- a/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| +++ b/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| @@ -38,7 +38,7 @@
|
| #define OUTPUT_FPF 0
|
| #define ARF_STATS_OUTPUT 0
|
|
|
| -#define GROUP_ADAPTIVE_MAXQ 0
|
| +#define GROUP_ADAPTIVE_MAXQ 1
|
|
|
| #define BOOST_BREAKOUT 12.5
|
| #define BOOST_FACTOR 12.5
|
| @@ -51,7 +51,6 @@
|
| #define KF_MAX_BOOST 128.0
|
| #define MIN_ARF_GF_BOOST 240
|
| #define MIN_DECAY_FACTOR 0.01
|
| -#define MIN_GF_INTERVAL 4
|
| #define MIN_KF_BOOST 300
|
| #define NEW_MV_MODE_PENALTY 32
|
| #define SVC_FACTOR_PT_LOW 0.45
|
| @@ -61,12 +60,9 @@
|
| #define RC_FACTOR_MAX 1.75
|
|
|
|
|
| -#define INTRA_WEIGHT_EXPERIMENT 0
|
| -#if INTRA_WEIGHT_EXPERIMENT
|
| #define NCOUNT_INTRA_THRESH 8192
|
| #define NCOUNT_INTRA_FACTOR 3
|
| #define NCOUNT_FRAME_II_THRESH 5.0
|
| -#endif
|
|
|
| #define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001)
|
|
|
| @@ -361,7 +357,7 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
|
| MV tmp_mv = {0, 0};
|
| MV ref_mv_full = {ref_mv->row >> 3, ref_mv->col >> 3};
|
| int num00, tmp_err, n;
|
| - const BLOCK_SIZE bsize = xd->mi[0].src_mi->mbmi.sb_type;
|
| + const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
|
| vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
|
| const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY;
|
|
|
| @@ -570,8 +566,8 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
|
| }
|
|
|
| - xd->mi = cm->mi;
|
| - xd->mi[0].src_mi = &xd->mi[0];
|
| + xd->mi = cm->mi_grid_visible;
|
| + xd->mi[0] = cm->mi;
|
|
|
| vp9_frame_init_quantizer(cpi);
|
|
|
| @@ -624,8 +620,8 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset;
|
| xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset;
|
| xd->left_available = (mb_col != 0);
|
| - xd->mi[0].src_mi->mbmi.sb_type = bsize;
|
| - xd->mi[0].src_mi->mbmi.ref_frame[0] = INTRA_FRAME;
|
| + xd->mi[0]->mbmi.sb_type = bsize;
|
| + xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
|
| set_mi_row_col(xd, &tile,
|
| mb_row << 1, num_8x8_blocks_high_lookup[bsize],
|
| mb_col << 1, num_8x8_blocks_wide_lookup[bsize],
|
| @@ -633,8 +629,8 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
|
|
| // Do intra 16x16 prediction.
|
| x->skip_encode = 0;
|
| - xd->mi[0].src_mi->mbmi.mode = DC_PRED;
|
| - xd->mi[0].src_mi->mbmi.tx_size = use_dc_pred ?
|
| + xd->mi[0]->mbmi.mode = DC_PRED;
|
| + xd->mi[0]->mbmi.tx_size = use_dc_pred ?
|
| (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
|
| vp9_encode_intra_block_plane(x, bsize, 0);
|
| this_error = vp9_get_mb_ss(x->plane[0].src_diff);
|
| @@ -832,7 +828,6 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| // Keep a count of cases where the inter and intra were very close
|
| // and very low. This helps with scene cut detection for example in
|
| // cropped clips with black bars at the sides or top and bottom.
|
| -#if INTRA_WEIGHT_EXPERIMENT
|
| if (((this_error - intrapenalty) * 9 <= motion_error * 10) &&
|
| (this_error < (2 * intrapenalty))) {
|
| neutral_count += 1.0;
|
| @@ -843,21 +838,15 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| neutral_count += (double)motion_error /
|
| DOUBLE_DIVIDE_CHECK((double)this_error);
|
| }
|
| -#else
|
| - if (((this_error - intrapenalty) * 9 <= motion_error * 10) &&
|
| - (this_error < (2 * intrapenalty))) {
|
| - neutral_count += 1.0;
|
| - }
|
| -#endif
|
|
|
| mv.row *= 8;
|
| mv.col *= 8;
|
| this_error = motion_error;
|
| - xd->mi[0].src_mi->mbmi.mode = NEWMV;
|
| - xd->mi[0].src_mi->mbmi.mv[0].as_mv = mv;
|
| - xd->mi[0].src_mi->mbmi.tx_size = TX_4X4;
|
| - xd->mi[0].src_mi->mbmi.ref_frame[0] = LAST_FRAME;
|
| - xd->mi[0].src_mi->mbmi.ref_frame[1] = NONE;
|
| + xd->mi[0]->mbmi.mode = NEWMV;
|
| + xd->mi[0]->mbmi.mv[0].as_mv = mv;
|
| + xd->mi[0]->mbmi.tx_size = TX_4X4;
|
| + xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME;
|
| + xd->mi[0]->mbmi.ref_frame[1] = NONE;
|
| vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize);
|
| vp9_encode_sby_pass1(x, bsize);
|
| sum_mvr += mv.row;
|
| @@ -1291,11 +1280,10 @@ static double get_sr_decay_rate(const VP9_COMP *cpi,
|
| frame->pcnt_motion * ((frame->mvc_abs + frame->mvr_abs) / 2);
|
|
|
| modified_pct_inter = frame->pcnt_inter;
|
| -#if INTRA_WEIGHT_EXPERIMENT
|
| if ((frame->intra_error / DOUBLE_DIVIDE_CHECK(frame->coded_error)) <
|
| - (double)NCOUNT_FRAME_II_THRESH)
|
| + (double)NCOUNT_FRAME_II_THRESH) {
|
| modified_pct_inter = frame->pcnt_inter - frame->pcnt_neutral;
|
| -#endif
|
| + }
|
| modified_pcnt_intra = 100 * (1.0 - modified_pct_inter);
|
|
|
|
|
| @@ -1334,14 +1322,17 @@ static double get_prediction_decay_rate(const VP9_COMP *cpi,
|
| // Function to test for a condition where a complex transition is followed
|
| // by a static section. For example in slide shows where there is a fade
|
| // between slides. This is to help with more optimal kf and gf positioning.
|
| -static int detect_transition_to_still(const TWO_PASS *twopass,
|
| +static int detect_transition_to_still(VP9_COMP *cpi,
|
| int frame_interval, int still_interval,
|
| double loop_decay_rate,
|
| double last_decay_rate) {
|
| + TWO_PASS *const twopass = &cpi->twopass;
|
| + RATE_CONTROL *const rc = &cpi->rc;
|
| +
|
| // Break clause to detect very still sections after motion
|
| // For example a static image after a fade or other transition
|
| // instead of a clean scene cut.
|
| - if (frame_interval > MIN_GF_INTERVAL &&
|
| + if (frame_interval > rc->min_gf_interval &&
|
| loop_decay_rate >= 0.999 &&
|
| last_decay_rate < 0.9) {
|
| int j;
|
| @@ -1849,7 +1840,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
| int int_lbq =
|
| (int)(vp9_convert_qindex_to_q(rc->last_boosted_qindex,
|
| cpi->common.bit_depth));
|
| - active_min_gf_interval = MIN_GF_INTERVAL + MIN(2, int_max_q / 200);
|
| + active_min_gf_interval = rc->min_gf_interval + MIN(2, int_max_q / 200);
|
| if (active_min_gf_interval > rc->max_gf_interval)
|
| active_min_gf_interval = rc->max_gf_interval;
|
|
|
| @@ -1863,6 +1854,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
| active_max_gf_interval = 12 + MIN(4, (int_lbq / 6));
|
| if (active_max_gf_interval > rc->max_gf_interval)
|
| active_max_gf_interval = rc->max_gf_interval;
|
| + if (active_max_gf_interval < active_min_gf_interval)
|
| + active_max_gf_interval = active_min_gf_interval;
|
| }
|
| }
|
|
|
| @@ -1903,7 +1896,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|
|
| // Break clause to detect very still sections after motion. For example,
|
| // a static image after a fade or other transition.
|
| - if (detect_transition_to_still(twopass, i, 5, loop_decay_rate,
|
| + if (detect_transition_to_still(cpi, i, 5, loop_decay_rate,
|
| last_loop_decay_rate)) {
|
| allow_alt_ref = 0;
|
| break;
|
| @@ -1969,7 +1962,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
| // Should we use the alternate reference frame.
|
| if (allow_alt_ref &&
|
| (i < cpi->oxcf.lag_in_frames) &&
|
| - (i >= MIN_GF_INTERVAL)) {
|
| + (i >= rc->min_gf_interval)) {
|
| // Calculate the boost for alt ref.
|
| rc->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost,
|
| &b_boost);
|
| @@ -2058,29 +2051,61 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
| }
|
| }
|
|
|
| -// TODO(PGW) Re-examine the use of II ration in this code in the light of#
|
| -// changes elsewhere
|
| +// Threshold for use of the lagging second reference frame. High second ref
|
| +// usage may point to a transient event like a flash or occlusion rather than
|
| +// a real scene cut.
|
| +#define SECOND_REF_USEAGE_THRESH 0.1
|
| +// Minimum % intra coding observed in first pass (1.0 = 100%)
|
| +#define MIN_INTRA_LEVEL 0.25
|
| +// Minimum ratio between the % of intra coding and inter coding in the first
|
| +// pass after discounting neutral blocks (discounting neutral blocks in this
|
| +// way helps catch scene cuts in clips with very flat areas or letter box
|
| +// format clips with image padding.
|
| +#define INTRA_VS_INTER_THRESH 2.0
|
| +// Hard threshold where the first pass chooses intra for almost all blocks.
|
| +// In such a case even if the frame is not a scene cut coding a key frame
|
| +// may be a good option.
|
| +#define VERY_LOW_INTER_THRESH 0.05
|
| +// Maximum threshold for the relative ratio of intra error score vs best
|
| +// inter error score.
|
| +#define KF_II_ERR_THRESHOLD 2.5
|
| +// In real scene cuts there is almost always a sharp change in the intra
|
| +// or inter error score.
|
| +#define ERR_CHANGE_THRESHOLD 0.4
|
| +// For real scene cuts we expect an improvment in the intra inter error
|
| +// ratio in the next frame.
|
| +#define II_IMPROVEMENT_THRESHOLD 3.5
|
| #define KF_II_MAX 128.0
|
| +
|
| static int test_candidate_kf(TWO_PASS *twopass,
|
| const FIRSTPASS_STATS *last_frame,
|
| const FIRSTPASS_STATS *this_frame,
|
| const FIRSTPASS_STATS *next_frame) {
|
| int is_viable_kf = 0;
|
| + double pcnt_intra = 1.0 - this_frame->pcnt_inter;
|
| + double modified_pcnt_inter =
|
| + this_frame->pcnt_inter - this_frame->pcnt_neutral;
|
|
|
| // Does the frame satisfy the primary criteria of a key frame?
|
| + // See above for an explanation of the test criteria.
|
| // If so, then examine how well it predicts subsequent frames.
|
| - if ((this_frame->pcnt_second_ref < 0.10) &&
|
| - (next_frame->pcnt_second_ref < 0.10) &&
|
| - ((this_frame->pcnt_inter < 0.05) ||
|
| - (((this_frame->pcnt_inter - this_frame->pcnt_neutral) < 0.35) &&
|
| + if ((this_frame->pcnt_second_ref < SECOND_REF_USEAGE_THRESH) &&
|
| + (next_frame->pcnt_second_ref < SECOND_REF_USEAGE_THRESH) &&
|
| + ((this_frame->pcnt_inter < VERY_LOW_INTER_THRESH) ||
|
| + ((pcnt_intra > MIN_INTRA_LEVEL) &&
|
| + (pcnt_intra > (INTRA_VS_INTER_THRESH * modified_pcnt_inter)) &&
|
| ((this_frame->intra_error /
|
| - DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) &&
|
| + DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) <
|
| + KF_II_ERR_THRESHOLD) &&
|
| ((fabs(last_frame->coded_error - this_frame->coded_error) /
|
| - DOUBLE_DIVIDE_CHECK(this_frame->coded_error) > 0.40) ||
|
| + DOUBLE_DIVIDE_CHECK(this_frame->coded_error) >
|
| + ERR_CHANGE_THRESHOLD) ||
|
| (fabs(last_frame->intra_error - this_frame->intra_error) /
|
| - DOUBLE_DIVIDE_CHECK(this_frame->intra_error) > 0.40) ||
|
| + DOUBLE_DIVIDE_CHECK(this_frame->intra_error) >
|
| + ERR_CHANGE_THRESHOLD) ||
|
| ((next_frame->intra_error /
|
| - DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5))))) {
|
| + DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) >
|
| + II_IMPROVEMENT_THRESHOLD))))) {
|
| int i;
|
| const FIRSTPASS_STATS *start_pos = twopass->stats_in;
|
| FIRSTPASS_STATS local_next_frame = *next_frame;
|
| @@ -2216,7 +2241,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|
|
| // Special check for transition or high motion followed by a
|
| // static scene.
|
| - if (detect_transition_to_still(twopass, i, cpi->oxcf.key_freq - i,
|
| + if (detect_transition_to_still(cpi, i, cpi->oxcf.key_freq - i,
|
| loop_decay_rate, decay_accumulator))
|
| break;
|
|
|
| @@ -2623,6 +2648,7 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
| }
|
|
|
| #define MINQ_ADJ_LIMIT 48
|
| +#define MINQ_ADJ_LIMIT_CQ 20
|
| void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
| TWO_PASS *const twopass = &cpi->twopass;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| @@ -2662,7 +2688,7 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
| const int maxq_adj_limit =
|
| rc->worst_quality - twopass->active_worst_quality;
|
| const int minq_adj_limit =
|
| - (cpi->oxcf.rc_mode == VPX_CQ) ? 0 : MINQ_ADJ_LIMIT;
|
| + (cpi->oxcf.rc_mode == VPX_CQ ? MINQ_ADJ_LIMIT_CQ : MINQ_ADJ_LIMIT);
|
|
|
| // Undershoot.
|
| if (rc->rate_error_estimate > cpi->oxcf.under_shoot_pct) {
|
|
|