Index: source/libvpx/vp9/encoder/vp9_firstpass.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_firstpass.c (revision 293081) |
+++ source/libvpx/vp9/encoder/vp9_firstpass.c (working copy) |
@@ -53,6 +53,7 @@ |
#define MIN_KF_BOOST 300 |
#define NEW_MV_MODE_PENALTY 32 |
#define SVC_FACTOR_PT_LOW 0.45 |
+#define DARK_THRESH 64 |
#define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001) |
@@ -106,10 +107,11 @@ |
FILE *fpfile; |
fpfile = fopen("firstpass.stt", "a"); |
- fprintf(fpfile, "%12.0f %12.0f %12.0f %12.0f %12.4f %12.4f" |
+ fprintf(fpfile, "%12.0f %12.4f %12.0f %12.0f %12.0f %12.4f %12.4f" |
"%12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f" |
"%12.0f %12.0f %12.4f %12.0f %12.0f %12.4f\n", |
stats->frame, |
+ stats->weight, |
stats->intra_error, |
stats->coded_error, |
stats->sr_coded_error, |
@@ -138,13 +140,14 @@ |
struct vpx_codec_cx_pkt pkt; |
pkt.kind = VPX_CODEC_FPMB_STATS_PKT; |
pkt.data.firstpass_mb_stats.buf = this_frame_mb_stats; |
- pkt.data.firstpass_mb_stats.sz = cm->MBs * sizeof(uint8_t); |
+ pkt.data.firstpass_mb_stats.sz = cm->initial_mbs * sizeof(uint8_t); |
vpx_codec_pkt_list_add(pktlist, &pkt); |
} |
#endif |
static void zero_stats(FIRSTPASS_STATS *section) { |
- section->frame = 0.0; |
+ section->frame = 0.0; |
+ section->weight = 0.0; |
section->intra_error = 0.0; |
section->coded_error = 0.0; |
section->sr_coded_error = 0.0; |
@@ -168,6 +171,7 @@ |
static void accumulate_stats(FIRSTPASS_STATS *section, |
const FIRSTPASS_STATS *frame) { |
section->frame += frame->frame; |
+ section->weight += frame->weight; |
section->spatial_layer_id = frame->spatial_layer_id; |
section->intra_error += frame->intra_error; |
section->coded_error += frame->coded_error; |
@@ -191,6 +195,7 @@ |
static void subtract_stats(FIRSTPASS_STATS *section, |
const FIRSTPASS_STATS *frame) { |
section->frame -= frame->frame; |
+ section->weight -= frame->weight; |
section->intra_error -= frame->intra_error; |
section->coded_error -= frame->coded_error; |
section->sr_coded_error -= frame->sr_coded_error; |
@@ -217,10 +222,11 @@ |
const VP9EncoderConfig *oxcf, |
const FIRSTPASS_STATS *this_frame) { |
const FIRSTPASS_STATS *const stats = &twopass->total_stats; |
- const double av_err = stats->coded_error / stats->count; |
- const double modified_error = av_err * |
- pow(this_frame->coded_error / DOUBLE_DIVIDE_CHECK(av_err), |
- oxcf->two_pass_vbrbias / 100.0); |
+ const double av_weight = stats->weight / stats->count; |
+ const double av_err = (stats->coded_error * av_weight) / stats->count; |
+ const double modified_error = |
+ av_err * pow(this_frame->coded_error * this_frame->weight / |
+ DOUBLE_DIVIDE_CHECK(av_err), oxcf->two_pass_vbrbias / 100.0); |
return fclamp(modified_error, |
twopass->modified_error_min, twopass->modified_error_max); |
} |
@@ -332,9 +338,9 @@ |
// Refine the motion search range according to the frame dimension |
// for first pass test. |
-static int get_search_range(const VP9_COMMON *cm) { |
+static int get_search_range(const VP9_COMP *cpi) { |
int sr = 0; |
- const int dim = MIN(cm->width, cm->height); |
+ const int dim = MIN(cpi->initial_width, cpi->initial_height); |
while ((dim << sr) < MAX_FULL_PEL_VAL) |
++sr; |
@@ -354,7 +360,7 @@ |
int step_param = 3; |
int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; |
- const int sr = get_search_range(&cpi->common); |
+ const int sr = get_search_range(cpi); |
step_param += sr; |
further_steps -= sr; |
@@ -480,15 +486,20 @@ |
const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12; |
LAYER_CONTEXT *const lc = is_two_pass_svc(cpi) ? |
&cpi->svc.layer_context[cpi->svc.spatial_layer_id] : NULL; |
+ double intra_factor; |
+ double brightness_factor; |
#if CONFIG_FP_MB_STATS |
if (cpi->use_fp_mb_stats) { |
- vp9_zero_array(cpi->twopass.frame_mb_stats_buf, cm->MBs); |
+ vp9_zero_array(cpi->twopass.frame_mb_stats_buf, cm->initial_mbs); |
} |
#endif |
vp9_clear_system_state(); |
+ intra_factor = 0.0; |
+ brightness_factor = 0.0; |
+ |
set_first_pass_params(cpi); |
vp9_set_quantizer(cm, find_fp_qindex(cm->bit_depth)); |
@@ -585,8 +596,10 @@ |
for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { |
int this_error; |
const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); |
- double error_weight = 1.0; |
const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col); |
+ double log_intra; |
+ int level_sample; |
+ |
#if CONFIG_FP_MB_STATS |
const int mb_index = mb_row * cm->mb_cols + mb_col; |
#endif |
@@ -604,11 +617,6 @@ |
mb_col << 1, num_8x8_blocks_wide_lookup[bsize], |
cm->mi_rows, cm->mi_cols); |
- if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
- const int energy = vp9_block_energy(cpi, x, bsize); |
- error_weight = vp9_vaq_inv_q_ratio(energy); |
- } |
- |
// Do intra 16x16 prediction. |
x->skip_encode = 0; |
xd->mi[0].src_mi->mbmi.mode = DC_PRED; |
@@ -635,11 +643,26 @@ |
} |
#endif // CONFIG_VP9_HIGHBITDEPTH |
- if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
- vp9_clear_system_state(); |
- this_error = (int)(this_error * error_weight); |
- } |
+ vp9_clear_system_state(); |
+ log_intra = log(this_error + 1.0); |
+ if (log_intra < 10.0) |
+ intra_factor += 1.0 + ((10.0 - log_intra) * 0.05); |
+ else |
+ intra_factor += 1.0; |
+#if CONFIG_VP9_HIGHBITDEPTH |
+ if (cm->use_highbitdepth) |
+ level_sample = CONVERT_TO_SHORTPTR(x->plane[0].src.buf)[0]; |
+ else |
+ level_sample = x->plane[0].src.buf[0]; |
+#else |
+ level_sample = x->plane[0].src.buf[0]; |
+#endif |
+ if ((level_sample < DARK_THRESH) && (log_intra < 9.0)) |
+ brightness_factor += 1.0 + (0.01 * (DARK_THRESH - level_sample)); |
+ else |
+ brightness_factor += 1.0; |
+ |
// Intrapenalty below deals with situations where the intra and inter |
// error scores are very low (e.g. a plain black frame). |
// We do not have special cases in first pass for 0,0 and nearest etc so |
@@ -711,10 +734,6 @@ |
// Test last reference frame using the previous best mv as the |
// starting point (best reference) for the search. |
first_pass_motion_search(cpi, x, &best_ref_mv, &mv, &motion_error); |
- if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
- vp9_clear_system_state(); |
- motion_error = (int)(motion_error * error_weight); |
- } |
// If the current best reference mv is not centered on 0,0 then do a |
// 0,0 based search as well. |
@@ -721,10 +740,6 @@ |
if (!is_zero_mv(&best_ref_mv)) { |
tmp_err = INT_MAX; |
first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &tmp_err); |
- if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
- vp9_clear_system_state(); |
- tmp_err = (int)(tmp_err * error_weight); |
- } |
if (tmp_err < motion_error) { |
motion_error = tmp_err; |
@@ -755,10 +770,6 @@ |
first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, |
&gf_motion_error); |
- if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
- vp9_clear_system_state(); |
- gf_motion_error = (int)(gf_motion_error * error_weight); |
- } |
if (gf_motion_error < motion_error && gf_motion_error < this_error) |
++second_ref_count; |
@@ -931,16 +942,21 @@ |
vp9_clear_system_state(); |
} |
- vp9_clear_system_state(); |
{ |
FIRSTPASS_STATS fps; |
- // The minimum error here insures some bit alocation to frames even |
+ // The minimum error here insures some bit allocation to frames even |
// in static regions. The allocation per MB declines for larger formats |
// where the typical "real" energy per MB also falls. |
// Initial estimate here uses sqrt(mbs) to define the min_err, where the |
- // number of mbs is propotional to image area. |
- const double min_err = 200 * sqrt(cm->MBs); |
+ // number of mbs is proportional to the image area. |
+ const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) |
+ ? cpi->initial_mbs : cpi->common.MBs; |
+ const double min_err = 200 * sqrt(num_mbs); |
+ intra_factor = intra_factor / (double)num_mbs; |
+ brightness_factor = brightness_factor / (double)num_mbs; |
+ fps.weight = intra_factor * brightness_factor; |
+ |
fps.frame = cm->current_video_frame; |
fps.spatial_layer_id = cpi->svc.spatial_layer_id; |
fps.coded_error = (double)(coded_error >> 8) + min_err; |
@@ -947,9 +963,9 @@ |
fps.sr_coded_error = (double)(sr_coded_error >> 8) + min_err; |
fps.intra_error = (double)(intra_error >> 8) + min_err; |
fps.count = 1.0; |
- fps.pcnt_inter = (double)intercount / cm->MBs; |
- fps.pcnt_second_ref = (double)second_ref_count / cm->MBs; |
- fps.pcnt_neutral = (double)neutral_count / cm->MBs; |
+ fps.pcnt_inter = (double)intercount / num_mbs; |
+ fps.pcnt_second_ref = (double)second_ref_count / num_mbs; |
+ fps.pcnt_neutral = (double)neutral_count / num_mbs; |
if (mvcount > 0) { |
fps.MVr = (double)sum_mvr / mvcount; |
@@ -960,7 +976,7 @@ |
fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / mvcount)) / mvcount; |
fps.mv_in_out_count = (double)sum_in_vectors / (mvcount * 2); |
fps.new_mv_count = new_mv_count; |
- fps.pcnt_motion = (double)mvcount / cm->MBs; |
+ fps.pcnt_motion = (double)mvcount / num_mbs; |
} else { |
fps.MVr = 0.0; |
fps.mvr_abs = 0.0; |
@@ -1074,7 +1090,8 @@ |
if (section_target_bandwidth <= 0) { |
return rc->worst_quality; // Highest value allowed |
} else { |
- const int num_mbs = cpi->common.MBs; |
+ const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) |
+ ? cpi->initial_mbs : cpi->common.MBs; |
const double section_err = stats->coded_error / stats->count; |
const double err_per_mb = section_err / num_mbs; |
const double speed_term = 1.0 + 0.04 * oxcf->speed; |
@@ -1091,7 +1108,8 @@ |
// content at the given rate. |
for (q = rc->best_quality; q < rc->worst_quality; ++q) { |
const double factor = |
- calc_correction_factor(err_per_mb, ERR_DIVISOR - ediv_size_correction, |
+ calc_correction_factor(err_per_mb, |
+ ERR_DIVISOR - ediv_size_correction, |
is_svc_upper_layer ? SVC_FACTOR_PT_LOW : |
FACTOR_PT_LOW, FACTOR_PT_HIGH, q, |
cpi->common.bit_depth); |
@@ -1188,9 +1206,12 @@ |
#define LOW_SR_DIFF_TRHESH 0.1 |
#define SR_DIFF_MAX 128.0 |
-static double get_sr_decay_rate(const VP9_COMMON *cm, |
+static double get_sr_decay_rate(const VP9_COMP *cpi, |
const FIRSTPASS_STATS *frame) { |
- double sr_diff = (frame->sr_coded_error - frame->coded_error) / cm->MBs; |
+ const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) |
+ ? cpi->initial_mbs : cpi->common.MBs; |
+ double sr_diff = |
+ (frame->sr_coded_error - frame->coded_error) / num_mbs; |
double sr_decay = 1.0; |
const double motion_amplitude_factor = |
frame->pcnt_motion * ((frame->mvc_abs + frame->mvr_abs) / 2); |
@@ -1207,19 +1228,19 @@ |
// This function gives an estimate of how badly we believe the prediction |
// quality is decaying from frame to frame. |
-static double get_zero_motion_factor(const VP9_COMMON *cm, |
+static double get_zero_motion_factor(const VP9_COMP *cpi, |
const FIRSTPASS_STATS *frame) { |
const double zero_motion_pct = frame->pcnt_inter - |
frame->pcnt_motion; |
- double sr_decay = get_sr_decay_rate(cm, frame); |
+ double sr_decay = get_sr_decay_rate(cpi, frame); |
return MIN(sr_decay, zero_motion_pct); |
} |
#define ZM_POWER_FACTOR 0.75 |
-static double get_prediction_decay_rate(const VP9_COMMON *cm, |
+static double get_prediction_decay_rate(const VP9_COMP *cpi, |
const FIRSTPASS_STATS *next_frame) { |
- const double sr_decay_rate = get_sr_decay_rate(cm, next_frame); |
+ const double sr_decay_rate = get_sr_decay_rate(cpi, next_frame); |
const double zero_motion_factor = |
(0.95 * pow((next_frame->pcnt_inter - next_frame->pcnt_motion), |
ZM_POWER_FACTOR)); |
@@ -1313,12 +1334,14 @@ |
const double lq = |
vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[INTER_FRAME], |
cpi->common.bit_depth); |
- const double boost_correction = MIN((0.5 + (lq * 0.015)), 1.5); |
+ const double boost_q_correction = MIN((0.5 + (lq * 0.015)), 1.5); |
+ const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) |
+ ? cpi->initial_mbs : cpi->common.MBs; |
// Underlying boost factor is based on inter error ratio. |
- frame_boost = (BASELINE_ERR_PER_MB * cpi->common.MBs) / |
+ frame_boost = (BASELINE_ERR_PER_MB * num_mbs) / |
DOUBLE_DIVIDE_CHECK(this_frame->coded_error); |
- frame_boost = frame_boost * BOOST_FACTOR * boost_correction; |
+ frame_boost = frame_boost * BOOST_FACTOR * boost_q_correction; |
// Increase boost for frames where new data coming into frame (e.g. zoom out). |
// Slightly reduce boost if there is a net balance of motion out of the frame |
@@ -1329,7 +1352,7 @@ |
else |
frame_boost += frame_boost * (this_frame_mv_in_out / 2.0); |
- return MIN(frame_boost, max_boost * boost_correction); |
+ return MIN(frame_boost, max_boost * boost_q_correction); |
} |
static int calc_arf_boost(VP9_COMP *cpi, int offset, |
@@ -1365,7 +1388,7 @@ |
// Accumulate the effect of prediction quality decay. |
if (!flash_detected) { |
- decay_accumulator *= get_prediction_decay_rate(&cpi->common, this_frame); |
+ decay_accumulator *= get_prediction_decay_rate(cpi, this_frame); |
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR |
? MIN_DECAY_FACTOR : decay_accumulator; |
} |
@@ -1404,7 +1427,7 @@ |
// Cumulative effect of prediction quality decay. |
if (!flash_detected) { |
- decay_accumulator *= get_prediction_decay_rate(&cpi->common, this_frame); |
+ decay_accumulator *= get_prediction_decay_rate(cpi, this_frame); |
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR |
? MIN_DECAY_FACTOR : decay_accumulator; |
} |
@@ -1723,7 +1746,8 @@ |
gf_group_err -= gf_first_frame_err; |
// Motion breakout threshold for loop below depends on image size. |
- mv_ratio_accumulator_thresh = (cpi->common.width + cpi->common.height) / 4.0; |
+ mv_ratio_accumulator_thresh = |
+ (cpi->initial_height + cpi->initial_width) / 4.0; |
// Set a maximum and minimum interval for the GF group. |
// If the image appears almost completely static we can extend beyond this. |
@@ -1775,14 +1799,13 @@ |
// Accumulate the effect of prediction quality decay. |
if (!flash_detected) { |
last_loop_decay_rate = loop_decay_rate; |
- loop_decay_rate = get_prediction_decay_rate(&cpi->common, &next_frame); |
+ loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); |
decay_accumulator = decay_accumulator * loop_decay_rate; |
// Monitor for static sections. |
zero_motion_accumulator = |
- MIN(zero_motion_accumulator, |
- get_zero_motion_factor(&cpi->common, &next_frame)); |
+ MIN(zero_motion_accumulator, get_zero_motion_factor(cpi, &next_frame)); |
// Break clause to detect very still sections after motion. For example, |
// a static image after a fade or other transition. |
@@ -2048,8 +2071,7 @@ |
break; |
// How fast is the prediction quality decaying? |
- loop_decay_rate = get_prediction_decay_rate(&cpi->common, |
- twopass->stats_in); |
+ loop_decay_rate = get_prediction_decay_rate(cpi, twopass->stats_in); |
// We want to know something about the recent past... rather than |
// as used elsewhere where we are concerned with decay in prediction |
@@ -2160,7 +2182,7 @@ |
// Monitor for static sections. |
zero_motion_accumulator = |
MIN(zero_motion_accumulator, |
- get_zero_motion_factor(&cpi->common, &next_frame)); |
+ get_zero_motion_factor(cpi, &next_frame)); |
// Not all frames in the group are necessarily used in calculating boost. |
if ((i <= rc->max_gf_interval) || |
@@ -2171,7 +2193,7 @@ |
// How fast is prediction quality decaying. |
if (!detect_flash(twopass, 0)) { |
const double loop_decay_rate = |
- get_prediction_decay_rate(&cpi->common, &next_frame); |
+ get_prediction_decay_rate(cpi, &next_frame); |
decay_accumulator *= loop_decay_rate; |
decay_accumulator = MAX(decay_accumulator, MIN_DECAY_FACTOR); |
av_decay_accumulator += decay_accumulator; |
@@ -2217,36 +2239,6 @@ |
twopass->modified_error_left -= kf_group_err; |
} |
-#define VBR_PCT_ADJUSTMENT_LIMIT 50 |
-// For VBR...adjustment to the frame target based on error from previous frames |
-void vbr_rate_correction(VP9_COMP *cpi, |
- int * this_frame_target, |
- const int64_t vbr_bits_off_target) { |
- int max_delta; |
- double position_factor = 1.0; |
- |
- // How far through the clip are we. |
- // This number is used to damp the per frame rate correction. |
- // Range 0 - 1.0 |
- if (cpi->twopass.total_stats.count) { |
- position_factor = sqrt((double)cpi->common.current_video_frame / |
- cpi->twopass.total_stats.count); |
- } |
- max_delta = (int)(position_factor * |
- ((*this_frame_target * VBR_PCT_ADJUSTMENT_LIMIT) / 100)); |
- |
- // vbr_bits_off_target > 0 means we have extra bits to spend |
- if (vbr_bits_off_target > 0) { |
- *this_frame_target += |
- (vbr_bits_off_target > max_delta) ? max_delta |
- : (int)vbr_bits_off_target; |
- } else { |
- *this_frame_target -= |
- (vbr_bits_off_target < -max_delta) ? max_delta |
- : (int)-vbr_bits_off_target; |
- } |
-} |
- |
// Define the reference buffers that will be updated post encode. |
void configure_buffer_updates(VP9_COMP *cpi) { |
TWO_PASS *const twopass = &cpi->twopass; |
@@ -2295,7 +2287,25 @@ |
} |
} |
+int is_skippable_frame(const VP9_COMP *cpi) { |
+ // If the current frame does not have non-zero motion vector detected in the |
+ // first pass, and so do its previous and forward frames, then this frame |
+ // can be skipped for partition check, and the partition size is assigned |
+ // according to the variance |
+ const SVC *const svc = &cpi->svc; |
+ const TWO_PASS *const twopass = is_two_pass_svc(cpi) ? |
+ &svc->layer_context[svc->spatial_layer_id].twopass : &cpi->twopass; |
+ return (!frame_is_intra_only(&cpi->common) && |
+ twopass->stats_in - 2 > twopass->stats_in_start && |
+ twopass->stats_in < twopass->stats_in_end && |
+ (twopass->stats_in - 1)->pcnt_inter - (twopass->stats_in - 1)->pcnt_motion |
+ == 1 && |
+ (twopass->stats_in - 2)->pcnt_inter - (twopass->stats_in - 2)->pcnt_motion |
+ == 1 && |
+ twopass->stats_in->pcnt_inter - twopass->stats_in->pcnt_motion == 1); |
+} |
+ |
void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { |
VP9_COMMON *const cm = &cpi->common; |
RATE_CONTROL *const rc = &cpi->rc; |
@@ -2329,11 +2339,6 @@ |
target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate); |
rc->base_frame_target = target_rate; |
- // Correction to rate target based on prior over or under shoot. |
- if (cpi->oxcf.rc_mode == VPX_VBR) |
- vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target); |
- |
- vp9_rc_set_frame_target(cpi, target_rate); |
cm->frame_type = INTER_FRAME; |
if (lc != NULL) { |
@@ -2347,6 +2352,13 @@ |
} |
} |
+ // Do the firstpass stats indicate that this frame is skippable for the |
+ // partition search? |
+ if (cpi->sf.allow_partition_search_skip && |
+ cpi->oxcf.pass == 2 && (!cpi->use_svc || is_two_pass_svc(cpi))) { |
+ cpi->partition_search_skippable_frame = is_skippable_frame(cpi); |
+ } |
+ |
return; |
} |
@@ -2377,8 +2389,7 @@ |
this_frame_copy = this_frame; |
// Keyframe and section processing. |
- if (rc->frames_to_key == 0 || |
- (cpi->frame_flags & FRAMEFLAGS_KEY)) { |
+ if (rc->frames_to_key == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY)) { |
// Define next KF group and assign bits to it. |
find_next_key_frame(cpi, &this_frame_copy); |
} else { |
@@ -2431,6 +2442,13 @@ |
configure_buffer_updates(cpi); |
+ // Do the firstpass stats indicate that this frame is skippable for the |
+ // partition search? |
+ if (cpi->sf.allow_partition_search_skip && cpi->oxcf.pass == 2 && |
+ (!cpi->use_svc || is_two_pass_svc(cpi))) { |
+ cpi->partition_search_skippable_frame = is_skippable_frame(cpi); |
+ } |
+ |
target_rate = gf_group->bit_allocation[gf_group->index]; |
if (cpi->common.frame_type == KEY_FRAME) |
target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate); |
@@ -2439,18 +2457,20 @@ |
rc->base_frame_target = target_rate; |
- // Correction to rate target based on prior over or under shoot. |
- if (cpi->oxcf.rc_mode == VPX_VBR) |
- vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target); |
+ { |
+ const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) |
+ ? cpi->initial_mbs : cpi->common.MBs; |
+ // The multiplication by 256 reverses a scaling factor of (>> 8) |
+ // applied when combining MB error values for the frame. |
+ twopass->mb_av_energy = |
+ log(((this_frame.intra_error * 256.0) / num_mbs) + 1.0); |
+ } |
- vp9_rc_set_frame_target(cpi, target_rate); |
- |
// Update the total stats remaining structure. |
subtract_stats(&twopass->total_left_stats, &this_frame); |
} |
#define MINQ_ADJ_LIMIT 32 |
-#define Q_LIMIT_STEP 1 |
void vp9_twopass_postencode_update(VP9_COMP *cpi) { |
TWO_PASS *const twopass = &cpi->twopass; |
RATE_CONTROL *const rc = &cpi->rc; |
@@ -2495,16 +2515,22 @@ |
if (rc->rate_error_estimate > cpi->oxcf.under_shoot_pct) { |
--twopass->extend_maxq; |
if (rc->rolling_target_bits >= rc->rolling_actual_bits) |
- twopass->extend_minq += Q_LIMIT_STEP; |
+ ++twopass->extend_minq; |
// Overshoot. |
} else if (rc->rate_error_estimate < -cpi->oxcf.over_shoot_pct) { |
--twopass->extend_minq; |
if (rc->rolling_target_bits < rc->rolling_actual_bits) |
- twopass->extend_maxq += Q_LIMIT_STEP; |
+ ++twopass->extend_maxq; |
} else { |
+ // Adjustment for extreme local overshoot. |
+ if (rc->projected_frame_size > (2 * rc->base_frame_target) && |
+ rc->projected_frame_size > (2 * rc->avg_frame_bandwidth)) |
+ ++twopass->extend_maxq; |
+ |
+ // Unwind undershoot or overshoot adjustment. |
if (rc->rolling_target_bits < rc->rolling_actual_bits) |
--twopass->extend_minq; |
- if (rc->rolling_target_bits > rc->rolling_actual_bits) |
+ else if (rc->rolling_target_bits > rc->rolling_actual_bits) |
--twopass->extend_maxq; |
} |
twopass->extend_minq = clamp(twopass->extend_minq, 0, MINQ_ADJ_LIMIT); |