From 405499d835a4a01fe09bc5ea01a2e7e77aaef8da Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Mon, 10 Jan 2011 16:02:51 +0000 Subject: [PATCH 1/3] Revert BASE_ERRPERMB Constant value reverted pending more tests on different video formats. Change-Id: I07d11a0e0185e60724698c835416caf2e0774e61 --- vp8/encoder/firstpass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index 0c79adee4..48899162d 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -903,7 +903,7 @@ void vp8_first_pass(VP8_COMP *cpi) } extern const int vp8_bits_per_mb[2][QINDEX_RANGE]; -#define BASE_ERRPERMB 100 +#define BASE_ERRPERMB 150 static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width) { int Q; From cf7c4732e5be5c881a49f778ba011ea5d656f66e Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Mon, 10 Jan 2011 16:41:53 +0000 Subject: [PATCH 2/3] Two Pass VBR change Further experiment with restriction of the Q range. This uses the average non KF/GF/ARF quantizer, instead of just relying on the initial value. It is not such a strong constraint but there may be a reduced risk of rate misses. Change-Id: I424fe782a37a2f4e18c70805e240db55bfaa25ec --- vp8/encoder/firstpass.c | 15 ++++++++++++- vp8/encoder/onyx_if.c | 50 ++++++++++++++++++++++++----------------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index 48899162d..4d259c676 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -989,6 +989,19 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_ //Q = cpi->oxcf.cq_target_quality; } + // Adjust maxq_min_limit and maxq_max_limit limits based on + // averaga q observed in clip for non kf/gf.arf frames + // Give average a chance to settle though. + if ( (cpi->ni_frames > + ((unsigned int)cpi->total_stats->count >> 8)) && + (cpi->ni_frames > 150) ) + { + cpi->maxq_max_limit = ((cpi->ni_av_qi + 32) < cpi->worst_quality) + ? (cpi->ni_av_qi + 32) : cpi->worst_quality; + cpi->maxq_min_limit = ((cpi->ni_av_qi - 32) > cpi->best_quality) + ? (cpi->ni_av_qi - 32) : cpi->best_quality; + } + return Q; } static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width) @@ -2121,7 +2134,7 @@ void vp8_second_pass(VP8_COMP *cpi) cpi->common.Width); // Limit the maxq value returned subsequently. - // This increases the risk of overspend if the initial + // This increases the risk of overspend or underspend if the initial // estimate for the clip is bad, but helps prevent excessive // variation in Q, especially near the end of a clip // where for example a small overspend may cause Q to crash diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index ee461c610..2d9e8011b 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -4442,30 +4442,38 @@ static void encode_frame_to_data_rate { cpi->ni_frames++; - // Calculate the average Q for normal inter frames (not key or GFU frames) - // This is used as a basis for setting active worst quality. - if (cpi->ni_frames > 150) + // Calculate the average Q for normal inter frames (not key or GFU + // frames). + if ( cpi->pass == 2 ) { cpi->ni_tot_qi += Q; cpi->ni_av_qi = (cpi->ni_tot_qi / cpi->ni_frames); } - // Early in the clip ... average the current frame Q value with the default - // entered by the user as a dampening measure else { - cpi->ni_tot_qi += Q; - cpi->ni_av_qi = ((cpi->ni_tot_qi / cpi->ni_frames) + cpi->worst_quality + 1) / 2; + // Damp value for first few frames + if (cpi->ni_frames > 150 ) + { + cpi->ni_tot_qi += Q; + cpi->ni_av_qi = (cpi->ni_tot_qi / cpi->ni_frames); + } + // For one pass, early in the clip ... average the current frame Q + // value with the worstq entered by the user as a dampening measure + else + { + cpi->ni_tot_qi += Q; + cpi->ni_av_qi = ((cpi->ni_tot_qi / cpi->ni_frames) + cpi->worst_quality + 1) / 2; + } + + // If the average Q is higher than what was used in the last frame + // (after going through the recode loop to keep the frame size within range) + // then use the last frame value - 1. + // The -1 is designed to stop Q and hence the data rate, from progressively + // falling away during difficult sections, but at the same time reduce the number of + // itterations around the recode loop. + if (Q > cpi->ni_av_qi) + cpi->ni_av_qi = Q - 1; } - - // If the average Q is higher than what was used in the last frame - // (after going through the recode loop to keep the frame size within range) - // then use the last frame value - 1. - // The -1 is designed to stop Q and hence the data rate, from progressively - // falling away during difficult sections, but at the same time reduce the number of - // itterations around the recode loop. - if (Q > cpi->ni_av_qi) - cpi->ni_av_qi = Q - 1; - } #if 0 @@ -4559,7 +4567,7 @@ static void encode_frame_to_data_rate if (cpi->total_coded_error_left != 0.0) fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %6ld %6ld" - "%6ld %6ld %5ld %5ld %5ld %8ld %8.2f %10d %10.3f" + "%6ld %6ld %6ld %5ld %5ld %5ld %8ld %8.2f %10d %10.3f" "%10.3f %8ld\n", cpi->common.current_video_frame, cpi->this_frame_target, cpi->projected_frame_size, @@ -4568,7 +4576,7 @@ static void encode_frame_to_data_rate (cpi->oxcf.starting_buffer_level-cpi->bits_off_target), (int)cpi->total_actual_bits, cm->base_qindex, cpi->active_best_quality, cpi->active_worst_quality, - cpi->cq_target_quality, cpi->zbin_over_quant, + cpi->ni_av_qi, cpi->cq_target_quality, cpi->zbin_over_quant, //cpi->avg_frame_qindex, cpi->zbin_over_quant, cm->refresh_golden_frame, cm->refresh_alt_ref_frame, cm->frame_type, cpi->gfu_boost, @@ -4578,7 +4586,7 @@ static void encode_frame_to_data_rate cpi->tot_recode_hits); else fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %6ld %6ld" - "%6ld %6ld %5ld %5ld %5ld %8ld %8.2f %10d %10.3f" + "%6ld %6ld %6ld %5ld %5ld %5ld %8ld %8.2f %10d %10.3f" "%8ld\n", cpi->common.current_video_frame, cpi->this_frame_target, cpi->projected_frame_size, @@ -4587,7 +4595,7 @@ static void encode_frame_to_data_rate (cpi->oxcf.starting_buffer_level-cpi->bits_off_target), (int)cpi->total_actual_bits, cm->base_qindex, cpi->active_best_quality, cpi->active_worst_quality, - cpi->cq_target_quality, cpi->zbin_over_quant, + cpi->ni_av_qi, cpi->cq_target_quality, cpi->zbin_over_quant, //cpi->avg_frame_qindex, cpi->zbin_over_quant, cm->refresh_golden_frame, cm->refresh_alt_ref_frame, cm->frame_type, cpi->gfu_boost, From 3675b2291cac15e6bc5a9bde9a0da7e00f919aaa Mon Sep 17 00:00:00 2001 From: Yunqing Wang Date: Mon, 10 Jan 2011 16:16:59 -0500 Subject: [PATCH 3/3] Fix bug in motion search The maximum possible MV in 1/8 pel units is (1<<11), which could cause mvcost out of its range that is 1023. Change maximum possible MV in 1/8 pel units to (1<<11)-8 will fix this problem. Change-Id: I5788ed1de773f66658c14f225fb4ab5b1679b74b --- vp8/encoder/mcomp.h | 1 - vp8/encoder/rdopt.c | 32 ++++++++++++++++---------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/vp8/encoder/mcomp.h b/vp8/encoder/mcomp.h index 122debcae..7600f87fc 100644 --- a/vp8/encoder/mcomp.h +++ b/vp8/encoder/mcomp.h @@ -24,7 +24,6 @@ extern void accum_mv_refs(MB_PREDICTION_MODE, const int near_mv_ref_cts[4]); #define MAX_MVSEARCH_STEPS 8 // The maximum number of steps in a step search given the largest allowed initial step #define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS+3)) - 8) // Max full pel mv specified in 1/8 pel units #define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS-1)) // Maximum size of the first step in full pel units -#define MAX_POSSIBLE_MV (1 << 11) // Maximum MV in 1/8 pel units extern void print_mode_context(void); extern int vp8_mv_bit_cost(MV *mv, MV *ref, int *mvcost[2], int Weight); diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index d694d39fb..366b8759a 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1325,10 +1325,10 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, if (bsi.segment_rd < best_rd) { - int col_min = (best_ref_mv->col - MAX_POSSIBLE_MV) >>3; - int col_max = (best_ref_mv->col + MAX_POSSIBLE_MV) >>3; - int row_min = (best_ref_mv->row - MAX_POSSIBLE_MV) >>3; - int row_max = (best_ref_mv->row + MAX_POSSIBLE_MV) >>3; + int col_min = (best_ref_mv->col - MAX_FULL_PEL_VAL) >>3; + int col_max = (best_ref_mv->col + MAX_FULL_PEL_VAL) >>3; + int row_min = (best_ref_mv->row - MAX_FULL_PEL_VAL) >>3; + int row_max = (best_ref_mv->row + MAX_FULL_PEL_VAL) >>3; int tmp_col_min = x->mv_col_min; int tmp_col_max = x->mv_col_max; @@ -1927,14 +1927,14 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int x->e_mbd.mode_info_context->mbmi.ref_frame, cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]); /* adjust mvp to make sure it is within MV range */ - if(mvp.row > best_ref_mv.row + MAX_POSSIBLE_MV) - mvp.row = best_ref_mv.row + MAX_POSSIBLE_MV; - else if(mvp.row < best_ref_mv.row - MAX_POSSIBLE_MV) - mvp.row = best_ref_mv.row - MAX_POSSIBLE_MV; - if(mvp.col > best_ref_mv.col + MAX_POSSIBLE_MV) - mvp.col = best_ref_mv.col + MAX_POSSIBLE_MV; - else if(mvp.col < best_ref_mv.col - MAX_POSSIBLE_MV) - mvp.col = best_ref_mv.col - MAX_POSSIBLE_MV; + if(mvp.row > best_ref_mv.row + MAX_FULL_PEL_VAL) + mvp.row = best_ref_mv.row + MAX_FULL_PEL_VAL; + else if(mvp.row < best_ref_mv.row - MAX_FULL_PEL_VAL) + mvp.row = best_ref_mv.row - MAX_FULL_PEL_VAL; + if(mvp.col > best_ref_mv.col + MAX_FULL_PEL_VAL) + mvp.col = best_ref_mv.col + MAX_FULL_PEL_VAL; + else if(mvp.col < best_ref_mv.col - MAX_FULL_PEL_VAL) + mvp.col = best_ref_mv.col - MAX_FULL_PEL_VAL; } // Check to see if the testing frequency for this mode is at its max @@ -2066,10 +2066,10 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int int further_steps; int n; - int col_min = (best_ref_mv.col - MAX_POSSIBLE_MV) >>3; - int col_max = (best_ref_mv.col + MAX_POSSIBLE_MV) >>3; - int row_min = (best_ref_mv.row - MAX_POSSIBLE_MV) >>3; - int row_max = (best_ref_mv.row + MAX_POSSIBLE_MV) >>3; + int col_min = (best_ref_mv.col - MAX_FULL_PEL_VAL) >>3; + int col_max = (best_ref_mv.col + MAX_FULL_PEL_VAL) >>3; + int row_min = (best_ref_mv.row - MAX_FULL_PEL_VAL) >>3; + int row_max = (best_ref_mv.row + MAX_FULL_PEL_VAL) >>3; int tmp_col_min = x->mv_col_min; int tmp_col_max = x->mv_col_max;