Index: source/libvpx/vp9/encoder/vp9_firstpass.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_firstpass.c (revision 251189) |
+++ source/libvpx/vp9/encoder/vp9_firstpass.c (working copy) |
@@ -49,6 +49,10 @@ |
#define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001) |
+#define MIN_KF_BOOST 300 |
+ |
+#define DISABLE_RC_LONG_TERM_MEM 0 |
+ |
static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) { |
YV12_BUFFER_CONFIG temp = *a; |
*a = *b; |
@@ -129,9 +133,9 @@ |
return 1; |
} |
-static void output_stats(const VP9_COMP *cpi, |
+static void output_stats(const VP9_COMP *cpi, |
struct vpx_codec_pkt_list *pktlist, |
- FIRSTPASS_STATS *stats) { |
+ FIRSTPASS_STATS *stats) { |
struct vpx_codec_cx_pkt pkt; |
pkt.kind = VPX_CODEC_STATS_PKT; |
pkt.data.twopass_stats.buf = stats; |
@@ -262,9 +266,9 @@ |
// Calculate a modified Error used in distributing bits between easier and |
// harder frames. |
-static double calculate_modified_err(VP9_COMP *cpi, |
- FIRSTPASS_STATS *this_frame) { |
- struct twopass_rc *const twopass = &cpi->twopass; |
+static double calculate_modified_err(const VP9_COMP *cpi, |
+ const FIRSTPASS_STATS *this_frame) { |
+ const struct twopass_rc *const twopass = &cpi->twopass; |
const FIRSTPASS_STATS *const stats = &twopass->total_stats; |
const double av_err = stats->ssim_weighted_pred_err / stats->count; |
double modified_error = av_err * pow(this_frame->ssim_weighted_pred_err / |
@@ -333,7 +337,7 @@ |
} |
// This function returns the maximum target rate per frame. |
-static int frame_max_bits(VP9_COMP *cpi) { |
+static int frame_max_bits(const VP9_COMP *cpi) { |
int64_t max_bits = |
((int64_t)cpi->rc.av_per_frame_bandwidth * |
(int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100; |
@@ -465,7 +469,7 @@ |
TileInfo tile; |
struct macroblock_plane *const p = x->plane; |
struct macroblockd_plane *const pd = xd->plane; |
- PICK_MODE_CONTEXT *ctx = &x->sb64_context; |
+ const PICK_MODE_CONTEXT *ctx = &x->sb64_context; |
int i; |
int recon_yoffset, recon_uvoffset; |
@@ -491,11 +495,8 @@ |
int sum_in_vectors = 0; |
uint32_t lastmv_as_int = 0; |
struct twopass_rc *const twopass = &cpi->twopass; |
+ const MV zero_mv = {0, 0}; |
- int_mv zero_ref_mv; |
- |
- zero_ref_mv.as_int = 0; |
- |
vp9_clear_system_state(); // __asm emms; |
vp9_setup_src_planes(x, cpi->Source, 0, 0); |
@@ -503,10 +504,9 @@ |
setup_dst_planes(xd, new_yv12, 0, 0); |
xd->mi_8x8 = cm->mi_grid_visible; |
- // required for vp9_frame_init_quantizer |
- xd->mi_8x8[0] = cm->mi; |
+ xd->mi_8x8[0] = cm->mi; // required for vp9_frame_init_quantizer |
- setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); |
+ vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); |
vp9_frame_init_quantizer(cpi); |
@@ -518,15 +518,9 @@ |
} |
x->skip_recode = 0; |
+ vp9_init_mv_probs(cm); |
+ vp9_initialize_rd_consts(cpi); |
- // Initialise the MV cost table to the defaults |
- // if( cm->current_video_frame == 0) |
- // if ( 0 ) |
- { |
- vp9_init_mv_probs(cm); |
- vp9_initialize_rd_consts(cpi); |
- } |
- |
// tiling is ignored in the first pass |
vp9_tile_init(&tile, cm, 0, 0); |
@@ -550,7 +544,7 @@ |
// for each macroblock col in image |
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { |
int this_error; |
- int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); |
+ 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); |
@@ -568,7 +562,7 @@ |
cm->mi_rows, cm->mi_cols); |
if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
- int energy = vp9_block_energy(cpi, x, bsize); |
+ const int energy = vp9_block_energy(cpi, x, bsize); |
error_weight = vp9_vaq_inv_q_ratio(energy); |
} |
@@ -594,8 +588,7 @@ |
// Set up limit values for motion vectors to prevent them extending |
// outside the UMV borders. |
x->mv_col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16); |
- x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) |
- + BORDER_MV_PIXELS_B16; |
+ x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + BORDER_MV_PIXELS_B16; |
// Other than for the first frame do a motion search |
if (cm->current_video_frame > 0) { |
@@ -620,7 +613,7 @@ |
// based search as well. |
if (best_ref_mv.as_int) { |
tmp_err = INT_MAX; |
- first_pass_motion_search(cpi, x, &zero_ref_mv.as_mv, &tmp_mv.as_mv, |
+ first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv, |
&tmp_err); |
if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
vp9_clear_system_state(); // __asm emms; |
@@ -641,17 +634,15 @@ |
xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset; |
gf_motion_error = zz_motion_search(cpi, x); |
- first_pass_motion_search(cpi, x, &zero_ref_mv.as_mv, &tmp_mv.as_mv, |
+ first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv, |
&gf_motion_error); |
if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
vp9_clear_system_state(); // __asm emms; |
gf_motion_error *= error_weight; |
} |
- if ((gf_motion_error < motion_error) && |
- (gf_motion_error < this_error)) { |
+ if (gf_motion_error < motion_error && gf_motion_error < this_error) |
second_ref_count++; |
- } |
// Reset to last frame as reference buffer |
xd->plane[0].pre[0].buf = lst_yv12->y_buffer + recon_yoffset; |
@@ -779,13 +770,11 @@ |
fps.mvr_abs = (double)sum_mvr_abs / mvcount; |
fps.MVc = (double)sum_mvc / mvcount; |
fps.mvc_abs = (double)sum_mvc_abs / mvcount; |
- fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / mvcount)) / |
- mvcount; |
- fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / mvcount)) / |
- mvcount; |
+ fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / mvcount)) / mvcount; |
+ 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 / cpi->common.MBs; |
+ fps.pcnt_motion = (double)mvcount / cm->MBs; |
} else { |
fps.MVr = 0.0; |
fps.mvr_abs = 0.0; |
@@ -913,13 +902,12 @@ |
return fclamp(pow(error_term, power_term), 0.05, 5.0); |
} |
-static int estimate_max_q(VP9_COMP *cpi, |
- FIRSTPASS_STATS *fpstats, |
- int section_target_bandwitdh) { |
+int vp9_twopass_worst_quality(VP9_COMP *cpi, FIRSTPASS_STATS *fpstats, |
+ int section_target_bandwitdh) { |
int q; |
const int num_mbs = cpi->common.MBs; |
int target_norm_bits_per_mb; |
- RATE_CONTROL *const rc = &cpi->rc; |
+ const RATE_CONTROL *const rc = &cpi->rc; |
const double section_err = fpstats->coded_error / fpstats->count; |
const double err_per_mb = section_err / num_mbs; |
@@ -949,58 +937,6 @@ |
return q; |
} |
-// For cq mode estimate a cq level that matches the observed |
-// complexity and data rate. |
-static int estimate_cq(VP9_COMP *cpi, |
- FIRSTPASS_STATS *fpstats, |
- int section_target_bandwitdh) { |
- int q; |
- int num_mbs = cpi->common.MBs; |
- int target_norm_bits_per_mb; |
- |
- double section_err = (fpstats->coded_error / fpstats->count); |
- double err_per_mb = section_err / num_mbs; |
- double err_correction_factor; |
- double clip_iiratio; |
- double clip_iifactor; |
- |
- target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) |
- ? (512 * section_target_bandwitdh) / num_mbs |
- : 512 * (section_target_bandwitdh / num_mbs); |
- |
- |
- // II ratio correction factor for clip as a whole |
- clip_iiratio = cpi->twopass.total_stats.intra_error / |
- DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats.coded_error); |
- clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025); |
- if (clip_iifactor < 0.80) |
- clip_iifactor = 0.80; |
- |
- // Try and pick a Q that can encode the content at the given rate. |
- for (q = 0; q < MAXQ; q++) { |
- int bits_per_mb_at_this_q; |
- |
- // Error per MB based correction factor |
- err_correction_factor = |
- calc_correction_factor(err_per_mb, 100.0, 0.5, 0.90, q) * clip_iifactor; |
- |
- bits_per_mb_at_this_q = |
- vp9_rc_bits_per_mb(INTER_FRAME, q, err_correction_factor); |
- |
- if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) |
- break; |
- } |
- |
- // Clip value to range "best allowed to (worst allowed - 1)" |
- q = select_cq_level(q); |
- if (q >= cpi->rc.worst_quality) |
- q = cpi->rc.worst_quality - 1; |
- if (q < cpi->rc.best_quality) |
- q = cpi->rc.best_quality; |
- |
- return q; |
-} |
- |
extern void vp9_new_framerate(VP9_COMP *cpi, double framerate); |
void vp9_init_second_pass(VP9_COMP *cpi) { |
@@ -1088,12 +1024,12 @@ |
// This function gives and estimate of how badly we believe |
// the prediction quality is decaying from frame to frame. |
-static double get_prediction_decay_rate(VP9_COMP *cpi, |
- FIRSTPASS_STATS *next_frame) { |
+static double get_prediction_decay_rate(const VP9_COMMON *cm, |
+ const FIRSTPASS_STATS *next_frame) { |
// Look at the observed drop in prediction quality between the last frame |
// and the GF buffer (which contains an older frame). |
const double mb_sr_err_diff = (next_frame->sr_coded_error - |
- next_frame->coded_error) / cpi->common.MBs; |
+ next_frame->coded_error) / cm->MBs; |
const double second_ref_decay = mb_sr_err_diff <= 512.0 |
? fclamp(pow(1.0 - (mb_sr_err_diff / 512.0), 0.5), 0.85, 1.0) |
: 0.85; |
@@ -1104,12 +1040,10 @@ |
// 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( |
- VP9_COMP *cpi, |
- int frame_interval, |
- int still_interval, |
- double loop_decay_rate, |
- double last_decay_rate) { |
+static int detect_transition_to_still(VP9_COMP *cpi, int frame_interval, |
+ int still_interval, |
+ double loop_decay_rate, |
+ double last_decay_rate) { |
int trans_to_still = 0; |
// Break clause to detect very still sections after motion |
@@ -1121,7 +1055,6 @@ |
int j; |
FIRSTPASS_STATS *position = cpi->twopass.stats_in; |
FIRSTPASS_STATS tmp_next_frame; |
- double zz_inter; |
// Look ahead a few frames to see if static condition |
// persists... |
@@ -1129,11 +1062,10 @@ |
if (EOF == input_stats(&cpi->twopass, &tmp_next_frame)) |
break; |
- zz_inter = (tmp_next_frame.pcnt_inter - tmp_next_frame.pcnt_motion); |
- if (zz_inter < 0.999) |
+ if (tmp_next_frame.pcnt_inter - tmp_next_frame.pcnt_motion < 0.999) |
break; |
} |
- // Reset file position |
+ |
reset_fpf_position(&cpi->twopass, position); |
// Only if it does do we signal a transition to still |
@@ -1147,14 +1079,14 @@ |
// This function detects a flash through the high relative pcnt_second_ref |
// score in the frame following a flash frame. The offset passed in should |
// reflect this |
-static int detect_flash(VP9_COMP *cpi, int offset) { |
+static int detect_flash(const struct twopass_rc *twopass, int offset) { |
FIRSTPASS_STATS next_frame; |
int flash_detected = 0; |
// Read the frame data. |
// The return is FALSE (no flash detected) if not a valid frame |
- if (read_frame_stats(&cpi->twopass, &next_frame, offset) != EOF) { |
+ if (read_frame_stats(twopass, &next_frame, offset) != EOF) { |
// What we are looking for here is a situation where there is a |
// brief break in prediction (such as a flash) but subsequent frames |
// are reasonably well predicted by an earlier (pre flash) frame. |
@@ -1183,16 +1115,15 @@ |
// Accumulate Motion In/Out of frame stats |
*this_frame_mv_in_out = this_frame->mv_in_out_count * motion_pct; |
*mv_in_out_accumulator += this_frame->mv_in_out_count * motion_pct; |
- *abs_mv_in_out_accumulator += |
- fabs(this_frame->mv_in_out_count * motion_pct); |
+ *abs_mv_in_out_accumulator += fabs(this_frame->mv_in_out_count * motion_pct); |
// Accumulate a measure of how uniform (or conversely how random) |
// the motion field is. (A ratio of absmv / mv) |
if (motion_pct > 0.05) { |
- double this_frame_mvr_ratio = fabs(this_frame->mvr_abs) / |
+ const double this_frame_mvr_ratio = fabs(this_frame->mvr_abs) / |
DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr)); |
- double this_frame_mvc_ratio = fabs(this_frame->mvc_abs) / |
+ const double this_frame_mvc_ratio = fabs(this_frame->mvc_abs) / |
DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc)); |
*mv_ratio_accumulator += (this_frame_mvr_ratio < this_frame->mvr_abs) |
@@ -1235,7 +1166,7 @@ |
int f_frames, int b_frames, |
int *f_boost, int *b_boost) { |
FIRSTPASS_STATS this_frame; |
- |
+ struct twopass_rc *const twopass = &cpi->twopass; |
int i; |
double boost_score = 0.0; |
double mv_ratio_accumulator = 0.0; |
@@ -1248,7 +1179,7 @@ |
// Search forward from the proposed arf/next gf position |
for (i = 0; i < f_frames; i++) { |
- if (read_frame_stats(&cpi->twopass, &this_frame, (i + offset)) == EOF) |
+ if (read_frame_stats(twopass, &this_frame, (i + offset)) == EOF) |
break; |
// Update the motion related elements to the boost calculation |
@@ -1259,12 +1190,12 @@ |
// We want to discount the flash frame itself and the recovery |
// frame that follows as both will have poor scores. |
- flash_detected = detect_flash(cpi, (i + offset)) || |
- detect_flash(cpi, (i + offset + 1)); |
+ flash_detected = detect_flash(twopass, i + offset) || |
+ detect_flash(twopass, i + offset + 1); |
// Cumulative effect of prediction quality decay |
if (!flash_detected) { |
- decay_accumulator *= get_prediction_decay_rate(cpi, &this_frame); |
+ decay_accumulator *= get_prediction_decay_rate(&cpi->common, &this_frame); |
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR |
? MIN_DECAY_FACTOR : decay_accumulator; |
} |
@@ -1285,7 +1216,7 @@ |
// Search backward towards last gf position |
for (i = -1; i >= -b_frames; i--) { |
- if (read_frame_stats(&cpi->twopass, &this_frame, (i + offset)) == EOF) |
+ if (read_frame_stats(twopass, &this_frame, (i + offset)) == EOF) |
break; |
// Update the motion related elements to the boost calculation |
@@ -1296,12 +1227,12 @@ |
// We want to discount the the flash frame itself and the recovery |
// frame that follows as both will have poor scores. |
- flash_detected = detect_flash(cpi, (i + offset)) || |
- detect_flash(cpi, (i + offset + 1)); |
+ flash_detected = detect_flash(twopass, i + offset) || |
+ detect_flash(twopass, i + offset + 1); |
// Cumulative effect of prediction quality decay |
if (!flash_detected) { |
- decay_accumulator *= get_prediction_decay_rate(cpi, &this_frame); |
+ decay_accumulator *= get_prediction_decay_rate(&cpi->common, &this_frame); |
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR |
? MIN_DECAY_FACTOR : decay_accumulator; |
} |
@@ -1461,6 +1392,7 @@ |
static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { |
FIRSTPASS_STATS next_frame = { 0 }; |
FIRSTPASS_STATS *start_pos; |
+ struct twopass_rc *const twopass = &cpi->twopass; |
int i; |
double boost_score = 0.0; |
double old_boost_score = 0.0; |
@@ -1479,10 +1411,10 @@ |
double mv_in_out_accumulator = 0.0; |
double abs_mv_in_out_accumulator = 0.0; |
double mv_ratio_accumulator_thresh; |
- int max_bits = frame_max_bits(cpi); // Max for a single frame |
+ const int max_bits = frame_max_bits(cpi); // Max for a single frame |
- unsigned int allow_alt_ref = |
- cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames; |
+ unsigned int allow_alt_ref = cpi->oxcf.play_alternate && |
+ cpi->oxcf.lag_in_frames; |
int f_boost = 0; |
int b_boost = 0; |
@@ -1490,11 +1422,11 @@ |
int active_max_gf_interval; |
RATE_CONTROL *const rc = &cpi->rc; |
- cpi->twopass.gf_group_bits = 0; |
+ twopass->gf_group_bits = 0; |
vp9_clear_system_state(); // __asm emms; |
- start_pos = cpi->twopass.stats_in; |
+ start_pos = twopass->stats_in; |
// Load stats for the current frame. |
mod_frame_err = calculate_modified_err(cpi, this_frame); |
@@ -1525,20 +1457,19 @@ |
active_max_gf_interval = rc->max_gf_interval; |
i = 0; |
- while ((i < cpi->twopass.static_scene_max_gf_interval) && |
- (i < rc->frames_to_key)) { |
+ while (i < twopass->static_scene_max_gf_interval && i < rc->frames_to_key) { |
i++; // Increment the loop counter |
// Accumulate error score of frames in this gf group |
mod_frame_err = calculate_modified_err(cpi, this_frame); |
gf_group_err += mod_frame_err; |
- if (EOF == input_stats(&cpi->twopass, &next_frame)) |
+ if (EOF == input_stats(twopass, &next_frame)) |
break; |
// Test for the case where there is a brief flash but the prediction |
// quality back to an earlier frame is then restored. |
- flash_detected = detect_flash(cpi, 0); |
+ flash_detected = detect_flash(twopass, 0); |
// Update the motion related elements to the boost calculation |
accumulate_frame_motion_stats(&next_frame, |
@@ -1549,14 +1480,14 @@ |
// Cumulative effect of prediction quality decay |
if (!flash_detected) { |
last_loop_decay_rate = loop_decay_rate; |
- loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); |
+ loop_decay_rate = get_prediction_decay_rate(&cpi->common, &next_frame); |
decay_accumulator = decay_accumulator * loop_decay_rate; |
// Monitor for static sections. |
if ((next_frame.pcnt_inter - next_frame.pcnt_motion) < |
zero_motion_accumulator) { |
- zero_motion_accumulator = |
- (next_frame.pcnt_inter - next_frame.pcnt_motion); |
+ zero_motion_accumulator = next_frame.pcnt_inter - |
+ next_frame.pcnt_motion; |
} |
// Break clause to detect very still sections after motion |
@@ -1594,14 +1525,14 @@ |
old_boost_score = boost_score; |
} |
- cpi->twopass.gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0); |
+ twopass->gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0); |
// Don't allow a gf too near the next kf |
if ((rc->frames_to_key - i) < MIN_GF_INTERVAL) { |
while (i < (rc->frames_to_key + !rc->next_key_frame_forced)) { |
i++; |
- if (EOF == input_stats(&cpi->twopass, this_frame)) |
+ if (EOF == input_stats(twopass, this_frame)) |
break; |
if (i < rc->frames_to_key) { |
@@ -1635,13 +1566,7 @@ |
(i >= MIN_GF_INTERVAL) && |
// for real scene cuts (not forced kfs) dont allow arf very near kf. |
(rc->next_key_frame_forced || |
- (i <= (rc->frames_to_key - MIN_GF_INTERVAL))) && |
- ((next_frame.pcnt_inter > 0.75) || |
- (next_frame.pcnt_second_ref > 0.5)) && |
- ((mv_in_out_accumulator / (double)i > -0.2) || |
- (mv_in_out_accumulator > -2.0)) && |
- (boost_score > 100)) { |
- |
+ (i <= (rc->frames_to_key - MIN_GF_INTERVAL)))) { |
// Alternative boost calculation for alt ref |
rc->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, |
&b_boost); |
@@ -1705,27 +1630,23 @@ |
#endif |
// Calculate the bits to be allocated to the group as a whole |
- if ((cpi->twopass.kf_group_bits > 0) && |
- (cpi->twopass.kf_group_error_left > 0)) { |
- cpi->twopass.gf_group_bits = |
- (int64_t)(cpi->twopass.kf_group_bits * |
+ if (twopass->kf_group_bits > 0 && twopass->kf_group_error_left > 0) { |
+ twopass->gf_group_bits = (int64_t)(cpi->twopass.kf_group_bits * |
(gf_group_err / cpi->twopass.kf_group_error_left)); |
} else { |
- cpi->twopass.gf_group_bits = 0; |
+ twopass->gf_group_bits = 0; |
} |
- cpi->twopass.gf_group_bits = |
- (cpi->twopass.gf_group_bits < 0) |
- ? 0 |
- : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits) |
- ? cpi->twopass.kf_group_bits : cpi->twopass.gf_group_bits; |
+ twopass->gf_group_bits = (twopass->gf_group_bits < 0) ? |
+ 0 : (twopass->gf_group_bits > twopass->kf_group_bits) ? |
+ twopass->kf_group_bits : twopass->gf_group_bits; |
// Clip cpi->twopass.gf_group_bits based on user supplied data rate |
// variability limit (cpi->oxcf.two_pass_vbrmax_section) |
- if (cpi->twopass.gf_group_bits > (int64_t)max_bits * rc->baseline_gf_interval) |
- cpi->twopass.gf_group_bits = (int64_t)max_bits * rc->baseline_gf_interval; |
+ if (twopass->gf_group_bits > (int64_t)max_bits * rc->baseline_gf_interval) |
+ twopass->gf_group_bits = (int64_t)max_bits * rc->baseline_gf_interval; |
// Reset the file position |
- reset_fpf_position(&cpi->twopass, start_pos); |
+ reset_fpf_position(twopass, start_pos); |
// Assign bits to the arf or gf. |
for (i = 0; i <= (rc->source_alt_ref_pending && |
@@ -1753,17 +1674,17 @@ |
// Calculate the number of bits to be spent on the gf or arf based on |
// the boost number |
- gf_bits = (int)((double)boost * (cpi->twopass.gf_group_bits / |
- (double)allocation_chunks)); |
+ gf_bits = (int)((double)boost * (twopass->gf_group_bits / |
+ (double)allocation_chunks)); |
// If the frame that is to be boosted is simpler than the average for |
// the gf/arf group then use an alternative calculation |
// based on the error score of the frame itself |
if (rc->baseline_gf_interval < 1 || |
mod_frame_err < gf_group_err / (double)rc->baseline_gf_interval) { |
- double alt_gf_grp_bits = (double)cpi->twopass.kf_group_bits * |
+ double alt_gf_grp_bits = (double)twopass->kf_group_bits * |
(mod_frame_err * (double)rc->baseline_gf_interval) / |
- DOUBLE_DIVIDE_CHECK(cpi->twopass.kf_group_error_left); |
+ DOUBLE_DIVIDE_CHECK(twopass->kf_group_error_left); |
int alt_gf_bits = (int)((double)boost * (alt_gf_grp_bits / |
(double)allocation_chunks)); |
@@ -1774,9 +1695,9 @@ |
// If it is harder than other frames in the group make sure it at |
// least receives an allocation in keeping with its relative error |
// score, otherwise it may be worse off than an "un-boosted" frame. |
- int alt_gf_bits = (int)((double)cpi->twopass.kf_group_bits * |
+ int alt_gf_bits = (int)((double)twopass->kf_group_bits * |
mod_frame_err / |
- DOUBLE_DIVIDE_CHECK(cpi->twopass.kf_group_error_left)); |
+ DOUBLE_DIVIDE_CHECK(twopass->kf_group_error_left)); |
if (alt_gf_bits > gf_bits) |
gf_bits = alt_gf_bits; |
@@ -1787,23 +1708,23 @@ |
gf_bits = 0; |
if (i == 0) { |
- cpi->twopass.gf_bits = gf_bits; |
+ twopass->gf_bits = gf_bits; |
} |
if (i == 1 || |
(!rc->source_alt_ref_pending && |
- (cpi->common.frame_type != KEY_FRAME))) { |
+ cpi->common.frame_type != KEY_FRAME)) { |
// Per frame bit target for this frame |
- rc->per_frame_bandwidth = gf_bits; |
+ vp9_rc_set_frame_target(cpi, gf_bits); |
} |
} |
{ |
// Adjust KF group bits and error remaining |
- cpi->twopass.kf_group_error_left -= (int64_t)gf_group_err; |
- cpi->twopass.kf_group_bits -= cpi->twopass.gf_group_bits; |
+ twopass->kf_group_error_left -= (int64_t)gf_group_err; |
+ twopass->kf_group_bits -= twopass->gf_group_bits; |
- if (cpi->twopass.kf_group_bits < 0) |
- cpi->twopass.kf_group_bits = 0; |
+ if (twopass->kf_group_bits < 0) |
+ twopass->kf_group_bits = 0; |
// If this is an arf update we want to remove the score for the |
// overlay frame at the end which will usually be very cheap to code. |
@@ -1812,18 +1733,18 @@ |
// For normal GFs remove the score for the GF itself unless this is |
// also a key frame in which case it has already been accounted for. |
if (rc->source_alt_ref_pending) { |
- cpi->twopass.gf_group_error_left = (int64_t)gf_group_err - mod_frame_err; |
+ twopass->gf_group_error_left = (int64_t)gf_group_err - mod_frame_err; |
} else if (cpi->common.frame_type != KEY_FRAME) { |
- cpi->twopass.gf_group_error_left = (int64_t)(gf_group_err |
+ twopass->gf_group_error_left = (int64_t)(gf_group_err |
- gf_first_frame_err); |
} else { |
- cpi->twopass.gf_group_error_left = (int64_t)gf_group_err; |
+ twopass->gf_group_error_left = (int64_t)gf_group_err; |
} |
- cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits; |
+ twopass->gf_group_bits -= twopass->gf_bits; |
- if (cpi->twopass.gf_group_bits < 0) |
- cpi->twopass.gf_group_bits = 0; |
+ if (twopass->gf_group_bits < 0) |
+ twopass->gf_group_bits = 0; |
// This condition could fail if there are two kfs very close together |
// despite (MIN_GF_INTERVAL) and would cause a divide by 0 in the |
@@ -1832,12 +1753,10 @@ |
const int boost = rc->source_alt_ref_pending ? b_boost : rc->gfu_boost; |
if (boost >= 150) { |
- int alt_extra_bits; |
- int pct_extra = (boost - 100) / 50; |
- pct_extra = (pct_extra > 20) ? 20 : pct_extra; |
- |
- alt_extra_bits = (int)((cpi->twopass.gf_group_bits * pct_extra) / 100); |
- cpi->twopass.gf_group_bits -= alt_extra_bits; |
+ const int pct_extra = MIN(20, (boost - 100) / 50); |
+ const int alt_extra_bits = (int)((twopass->gf_group_bits * pct_extra) / |
+ 100); |
+ twopass->gf_group_bits -= alt_extra_bits; |
} |
} |
} |
@@ -1846,20 +1765,20 @@ |
FIRSTPASS_STATS sectionstats; |
zero_stats(§ionstats); |
- reset_fpf_position(&cpi->twopass, start_pos); |
+ reset_fpf_position(twopass, start_pos); |
for (i = 0; i < rc->baseline_gf_interval; i++) { |
- input_stats(&cpi->twopass, &next_frame); |
+ input_stats(twopass, &next_frame); |
accumulate_stats(§ionstats, &next_frame); |
} |
avg_stats(§ionstats); |
- cpi->twopass.section_intra_rating = (int) |
+ twopass->section_intra_rating = (int) |
(sectionstats.intra_error / |
DOUBLE_DIVIDE_CHECK(sectionstats.coded_error)); |
- reset_fpf_position(&cpi->twopass, start_pos); |
+ reset_fpf_position(twopass, start_pos); |
} |
} |
@@ -1895,18 +1814,13 @@ |
cpi->twopass.gf_group_bits = 0; |
// Per frame bit target for this frame. |
- cpi->rc.per_frame_bandwidth = target_frame_size; |
+ vp9_rc_set_frame_target(cpi, target_frame_size); |
} |
-static int test_for_kf_one_pass(VP9_COMP *cpi) { |
- // Placeholder function for auto key frame |
- return 0; |
-} |
- |
static int test_candidate_kf(VP9_COMP *cpi, |
- FIRSTPASS_STATS *last_frame, |
- FIRSTPASS_STATS *this_frame, |
- FIRSTPASS_STATS *next_frame) { |
+ const FIRSTPASS_STATS *last_frame, |
+ const FIRSTPASS_STATS *this_frame, |
+ const FIRSTPASS_STATS *next_frame) { |
int is_viable_kf = 0; |
// Does the frame satisfy the primary criteria of a key frame |
@@ -2006,8 +1920,6 @@ |
double kf_mod_err = 0.0; |
double kf_group_err = 0.0; |
- double kf_group_intra_err = 0.0; |
- double kf_group_coded_err = 0.0; |
double recent_loop_decay[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; |
RATE_CONTROL *const rc = &cpi->rc; |
@@ -2045,12 +1957,6 @@ |
// Accumulate kf group error |
kf_group_err += calculate_modified_err(cpi, this_frame); |
- // These figures keep intra and coded error counts for all frames including |
- // key frames in the group. The effect of the key frame itself can be |
- // subtracted out using the first_frame data collected above. |
- kf_group_intra_err += this_frame->intra_error; |
- kf_group_coded_err += this_frame->coded_error; |
- |
// load a the next frame's stats |
last_frame = *this_frame; |
input_stats(twopass, this_frame); |
@@ -2064,7 +1970,7 @@ |
// How fast is prediction quality decaying |
- loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); |
+ loop_decay_rate = get_prediction_decay_rate(&cpi->common, &next_frame); |
// We want to know something about the recent past... rather than |
// as used elsewhere where we are concened with decay in prediction |
@@ -2110,17 +2016,13 @@ |
reset_fpf_position(twopass, start_position); |
kf_group_err = 0; |
- kf_group_intra_err = 0; |
- kf_group_coded_err = 0; |
// Rescan to get the correct error data for the forced kf group |
for (i = 0; i < rc->frames_to_key; i++) { |
// Accumulate kf group errors |
kf_group_err += calculate_modified_err(cpi, &tmp_frame); |
- kf_group_intra_err += tmp_frame.intra_error; |
- kf_group_coded_err += tmp_frame.coded_error; |
- // Load a the next frame's stats |
+ // Load the next frame's stats. |
input_stats(twopass, &tmp_frame); |
} |
rc->next_key_frame_forced = 1; |
@@ -2134,12 +2036,6 @@ |
if (twopass->stats_in >= twopass->stats_in_end) { |
// Accumulate kf group error |
kf_group_err += calculate_modified_err(cpi, this_frame); |
- |
- // These figures keep intra and coded error counts for all frames including |
- // key frames in the group. The effect of the key frame itself can be |
- // subtracted out using the first_frame data collected above. |
- kf_group_intra_err += this_frame->intra_error; |
- kf_group_coded_err += this_frame->coded_error; |
} |
// Calculate the number of bits that should be assigned to the kf group. |
@@ -2169,7 +2065,6 @@ |
// frames use inter blocks. |
decay_accumulator = 1.0; |
boost_score = 0.0; |
- loop_decay_rate = 1.00; // Starting decay rate |
// Scan through the kf group collating various stats. |
for (i = 0; i < rc->frames_to_key; i++) { |
@@ -2198,8 +2093,8 @@ |
r = RMAX; |
// How fast is prediction quality decaying |
- if (!detect_flash(cpi, 0)) { |
- loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); |
+ if (!detect_flash(twopass, 0)) { |
+ loop_decay_rate = get_prediction_decay_rate(&cpi->common, &next_frame); |
decay_accumulator *= loop_decay_rate; |
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR |
? MIN_DECAY_FACTOR : decay_accumulator; |
@@ -2238,8 +2133,8 @@ |
if (kf_boost < (rc->frames_to_key * 3)) |
kf_boost = (rc->frames_to_key * 3); |
- if (kf_boost < 300) // Min KF boost |
- kf_boost = 300; |
+ if (kf_boost < MIN_KF_BOOST) |
+ kf_boost = MIN_KF_BOOST; |
// Make a note of baseline boost and the zero motion |
// accumulator value for use elsewhere. |
@@ -2248,7 +2143,7 @@ |
// We do three calculations for kf size. |
// The first is based on the error score for the whole kf group. |
- // The second (optionaly) on the key frames own error if this is |
+ // The second (optionally) on the key frames own error if this is |
// smaller than the average for the group. |
// The final one insures that the frame receives at least the |
// allocation it would have received based on its own error score vs |
@@ -2279,8 +2174,8 @@ |
((double)twopass->kf_group_bits / allocation_chunks)); |
// If the key frame is actually easier than the average for the |
- // kf group (which does sometimes happen... eg a blank intro frame) |
- // Then use an alternate calculation based on the kf error score |
+ // kf group (which does sometimes happen, e.g. a blank intro frame) |
+ // then use an alternate calculation based on the kf error score |
// which should give a smaller key frame. |
if (kf_mod_err < kf_group_err / rc->frames_to_key) { |
double alt_kf_grp_bits = ((double)twopass->bits_left * |
@@ -2303,13 +2198,9 @@ |
twopass->kf_bits = alt_kf_bits; |
} |
} |
- |
twopass->kf_group_bits -= twopass->kf_bits; |
- |
- // Peer frame bit target for this frame |
- rc->per_frame_bandwidth = twopass->kf_bits; |
- // Convert to a per second bitrate |
- cpi->target_bandwidth = (int)(twopass->kf_bits * cpi->output_framerate); |
+ // Per frame bit target for this frame. |
+ vp9_rc_set_frame_target(cpi, twopass->kf_bits); |
} |
// Note the total error score of the kf group minus the key frame itself |
@@ -2321,64 +2212,10 @@ |
twopass->modified_error_left -= kf_group_err; |
} |
-void vp9_get_svc_params(VP9_COMP *cpi) { |
+void vp9_rc_get_first_pass_params(VP9_COMP *cpi) { |
VP9_COMMON *const cm = &cpi->common; |
- if ((cm->current_video_frame == 0) || |
- (cm->frame_flags & FRAMEFLAGS_KEY) || |
- (cpi->oxcf.auto_key && (cpi->rc.frames_since_key % |
- cpi->key_frame_frequency == 0))) { |
- cm->frame_type = KEY_FRAME; |
- } else { |
- cm->frame_type = INTER_FRAME; |
- } |
- cpi->rc.frames_till_gf_update_due = INT_MAX; |
- cpi->rc.baseline_gf_interval = INT_MAX; |
-} |
- |
-void vp9_get_one_pass_params(VP9_COMP *cpi) { |
- VP9_COMMON *const cm = &cpi->common; |
if (!cpi->refresh_alt_ref_frame && |
(cm->current_video_frame == 0 || |
- cm->frame_flags & FRAMEFLAGS_KEY || |
- cpi->rc.frames_to_key == 0 || |
- (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) { |
- cm->frame_type = KEY_FRAME; |
- cpi->rc.this_key_frame_forced = cm->current_video_frame != 0 && |
- cpi->rc.frames_to_key == 0; |
- cpi->rc.frames_to_key = cpi->key_frame_frequency; |
- cpi->rc.kf_boost = 300; |
- } else { |
- cm->frame_type = INTER_FRAME; |
- } |
- if (cpi->rc.frames_till_gf_update_due == 0) { |
- cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval; |
- cpi->refresh_golden_frame = 1; |
- } |
-} |
- |
-void vp9_get_one_pass_cbr_params(VP9_COMP *cpi) { |
- VP9_COMMON *const cm = &cpi->common; |
- if ((cm->current_video_frame == 0 || |
- cm->frame_flags & FRAMEFLAGS_KEY || |
- cpi->rc.frames_to_key == 0 || |
- (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) { |
- cm->frame_type = KEY_FRAME; |
- cpi->rc.this_key_frame_forced = cm->current_video_frame != 0 && |
- cpi->rc.frames_to_key == 0; |
- cpi->rc.frames_to_key = cpi->key_frame_frequency; |
- cpi->rc.kf_boost = 300; |
- } else { |
- cm->frame_type = INTER_FRAME; |
- } |
- // Don't use gf_update by default in CBR mode. |
- cpi->rc.frames_till_gf_update_due = INT_MAX; |
- cpi->rc.baseline_gf_interval = INT_MAX; |
-} |
- |
-void vp9_get_first_pass_params(VP9_COMP *cpi) { |
- VP9_COMMON *const cm = &cpi->common; |
- if (!cpi->refresh_alt_ref_frame && |
- (cm->current_video_frame == 0 || |
cm->frame_flags & FRAMEFLAGS_KEY)) { |
cm->frame_type = KEY_FRAME; |
} else { |
@@ -2388,38 +2225,39 @@ |
cpi->rc.frames_to_key = INT_MAX; |
} |
-void vp9_get_second_pass_params(VP9_COMP *cpi) { |
- int tmp_q; |
- int frames_left = (int)(cpi->twopass.total_stats.count - |
- cpi->common.current_video_frame); |
- |
+void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { |
+ VP9_COMMON *const cm = &cpi->common; |
+ RATE_CONTROL *const rc = &cpi->rc; |
+ struct twopass_rc *const twopass = &cpi->twopass; |
+ const int frames_left = (int)(twopass->total_stats.count - |
+ cm->current_video_frame); |
FIRSTPASS_STATS this_frame; |
FIRSTPASS_STATS this_frame_copy; |
- RATE_CONTROL *rc = &cpi->rc; |
double this_frame_intra_error; |
double this_frame_coded_error; |
+ int target; |
+ if (!twopass->stats_in) |
+ return; |
+ |
if (cpi->refresh_alt_ref_frame) { |
- cpi->common.frame_type = INTER_FRAME; |
+ cm->frame_type = INTER_FRAME; |
+ vp9_rc_set_frame_target(cpi, twopass->gf_bits); |
return; |
} |
- if (!cpi->twopass.stats_in) |
- return; |
vp9_clear_system_state(); |
if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { |
- rc->active_worst_quality = cpi->oxcf.cq_level; |
- } else if (cpi->common.current_video_frame == 0) { |
+ twopass->active_worst_quality = cpi->oxcf.cq_level; |
+ } else if (cm->current_video_frame == 0) { |
// Special case code for first frame. |
- int section_target_bandwidth = |
- (int)(cpi->twopass.bits_left / frames_left); |
- |
- tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats, |
- section_target_bandwidth); |
- |
- rc->active_worst_quality = tmp_q; |
+ const int section_target_bandwidth = (int)(twopass->bits_left / |
+ frames_left); |
+ const int tmp_q = vp9_twopass_worst_quality(cpi, &twopass->total_left_stats, |
+ section_target_bandwidth); |
+ twopass->active_worst_quality = tmp_q; |
rc->ni_av_qi = tmp_q; |
rc->avg_q = vp9_convert_qindex_to_q(tmp_q); |
@@ -2431,7 +2269,7 @@ |
// adjust_maxq_qrange(cpi); |
} |
vp9_zero(this_frame); |
- if (EOF == input_stats(&cpi->twopass, &this_frame)) |
+ if (EOF == input_stats(twopass, &this_frame)) |
return; |
this_frame_intra_error = this_frame.intra_error; |
@@ -2439,12 +2277,12 @@ |
// keyframe and section processing ! |
if (rc->frames_to_key == 0 || |
- (cpi->common.frame_flags & FRAMEFLAGS_KEY)) { |
+ (cm->frame_flags & FRAMEFLAGS_KEY)) { |
// Define next KF group and assign bits to it |
this_frame_copy = this_frame; |
find_next_key_frame(cpi, &this_frame_copy); |
} else { |
- cpi->common.frame_type = INTER_FRAME; |
+ cm->frame_type = INTER_FRAME; |
} |
// Is this a GF / ARF (Note that a KF is always also a GF) |
@@ -2462,13 +2300,13 @@ |
} |
#endif |
- if (cpi->twopass.gf_zeromotion_pct > 995) { |
+ if (twopass->gf_zeromotion_pct > 995) { |
// As long as max_thresh for encode breakout is small enough, it is ok |
- // to enable it for no-show frame, i.e. set enable_encode_breakout to 2. |
- if (!cpi->common.show_frame) |
- cpi->enable_encode_breakout = 0; |
+ // to enable it for show frame, i.e. set allow_encode_breakout to 2. |
+ if (!cm->show_frame) |
+ cpi->allow_encode_breakout = ENCODE_BREAKOUT_DISABLED; |
else |
- cpi->enable_encode_breakout = 2; |
+ cpi->allow_encode_breakout = ENCODE_BREAKOUT_LIMITED; |
} |
rc->frames_till_gf_update_due = rc->baseline_gf_interval; |
@@ -2481,24 +2319,24 @@ |
} |
// Keep a globally available copy of this and the next frame's iiratio. |
- cpi->twopass.this_iiratio = (int)(this_frame_intra_error / |
+ twopass->this_iiratio = (int)(this_frame_intra_error / |
DOUBLE_DIVIDE_CHECK(this_frame_coded_error)); |
{ |
FIRSTPASS_STATS next_frame; |
- if (lookup_next_frame_stats(&cpi->twopass, &next_frame) != EOF) { |
- cpi->twopass.next_iiratio = (int)(next_frame.intra_error / |
- DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); |
+ if (lookup_next_frame_stats(twopass, &next_frame) != EOF) { |
+ twopass->next_iiratio = (int)(next_frame.intra_error / |
+ DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); |
} |
} |
- // Set nominal per second bandwidth for this frame |
- cpi->target_bandwidth = (int)(rc->per_frame_bandwidth * |
- cpi->output_framerate); |
- if (cpi->target_bandwidth < 0) |
- cpi->target_bandwidth = 0; |
+ if (cpi->common.frame_type == KEY_FRAME) |
+ target = vp9_rc_clamp_iframe_target_size(cpi, rc->this_frame_target); |
+ else |
+ target = vp9_rc_clamp_pframe_target_size(cpi, rc->this_frame_target); |
+ vp9_rc_set_frame_target(cpi, target); |
// Update the total stats remaining structure |
- subtract_stats(&cpi->twopass.total_left_stats, &this_frame); |
+ subtract_stats(&twopass->total_left_stats, &this_frame); |
} |
void vp9_twopass_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { |
@@ -2506,5 +2344,18 @@ |
cpi->twopass.bits_left -= cpi->rc.this_frame_target; |
#else |
cpi->twopass.bits_left -= 8 * bytes_used; |
+ // Update bits left to the kf and gf groups to account for overshoot or |
+ // undershoot on these frames |
+ if (cm->frame_type == KEY_FRAME) { |
+ cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - |
+ cpi->rc.projected_frame_size; |
+ |
+ cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0); |
+ } else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) { |
+ cpi->twopass.gf_group_bits += cpi->rc.this_frame_target - |
+ cpi->rc.projected_frame_size; |
+ |
+ cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0); |
+ } |
#endif |
} |