Parameter fixes for one-pass non-cbr mode

Fixes some of the parameters for 1-pass non-cbr mode.
Also includes some cleanups, inlcuding refactoring of the
recode_loop options.

Results on derfraw300 improve by about 5-6%, so that the one-pass
mode is now 13% below the 2-pass mode in speed 0.

Change-Id: I844cc2638694c7574f3be00d41d60b23dc1016f0
This commit is contained in:
Deb Mukherjee 2014-02-05 16:19:11 -08:00
Родитель 005fc6970b
Коммит b2209c3346
3 изменённых файлов: 114 добавлений и 54 удалений

Просмотреть файл

@ -572,7 +572,7 @@ static void set_good_speed_feature(VP9_COMMON *cm,
int speed) {
int i;
sf->adaptive_rd_thresh = 1;
sf->recode_loop = (speed < 1);
sf->recode_loop = ((speed < 1) ? ALLOW_RECODE : ALLOW_RECODE_KFMAXBW);
if (speed == 1) {
sf->use_square_partition_only = !frame_is_intra_only(cm);
sf->less_rectangular_check = 1;
@ -590,7 +590,7 @@ static void set_good_speed_feature(VP9_COMMON *cm,
sf->adaptive_pred_interp_filter = 1;
sf->auto_mv_step_size = 1;
sf->adaptive_rd_thresh = 2;
sf->recode_loop = 2;
sf->recode_loop = ALLOW_RECODE_KFARFGF;
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
@ -626,7 +626,7 @@ static void set_good_speed_feature(VP9_COMMON *cm,
sf->last_partitioning_redo_frequency = 3;
sf->adaptive_rd_thresh = 2;
sf->recode_loop = 2;
sf->recode_loop = ALLOW_RECODE_KFARFGF;
sf->use_lp32x32fdct = 1;
sf->mode_skip_start = 11;
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
@ -743,7 +743,7 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
int speed) {
sf->static_segmentation = 0;
sf->adaptive_rd_thresh = 1;
sf->recode_loop = (speed < 1);
sf->recode_loop = ((speed < 1) ? ALLOW_RECODE : ALLOW_RECODE_KFMAXBW);
if (speed == 1) {
sf->use_square_partition_only = !frame_is_intra_only(cm);
sf->less_rectangular_check = 1;
@ -761,7 +761,7 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
sf->adaptive_pred_interp_filter = 1;
sf->auto_mv_step_size = 1;
sf->adaptive_rd_thresh = 2;
sf->recode_loop = 2;
sf->recode_loop = ALLOW_RECODE_KFARFGF;
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
@ -797,7 +797,7 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
sf->last_partitioning_redo_frequency = 3;
sf->adaptive_rd_thresh = 2;
sf->recode_loop = 2;
sf->recode_loop = ALLOW_RECODE_KFARFGF;
sf->use_lp32x32fdct = 1;
sf->mode_skip_start = 11;
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
@ -865,7 +865,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
// best quality defaults
sf->RD = 1;
sf->search_method = NSTEP;
sf->recode_loop = 1;
sf->recode_loop = ALLOW_RECODE;
sf->subpel_search_method = SUBPEL_TREE;
sf->subpel_iters_per_step = 2;
sf->subpel_force_stop = 0;
@ -933,7 +933,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
// No recode for 1 pass.
if (cpi->pass == 0) {
sf->recode_loop = 0;
sf->recode_loop = DISALLOW_RECODE;
sf->optimize_coefficients = 0;
}
@ -2544,8 +2544,8 @@ static int recode_loop_test(const VP9_COMP *cpi,
// Is frame recode allowed.
// Yes if either recode mode 1 is selected or mode 2 is selected
// and the frame is a key frame, golden frame or alt_ref_frame
} else if ((cpi->sf.recode_loop == 1) ||
((cpi->sf.recode_loop == 2) &&
} else if ((cpi->sf.recode_loop == ALLOW_RECODE) ||
((cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF) &&
(cm->frame_type == KEY_FRAME ||
cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) {
// General over and under shoot tests
@ -2764,20 +2764,62 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
}
#endif
static void encode_without_recode_loop(VP9_COMP *cpi,
size_t *size,
uint8_t *dest,
int *q) {
VP9_COMMON *const cm = &cpi->common;
vp9_clear_system_state(); // __asm emms;
vp9_set_quantizer(cpi, *q);
// Set up entropy context depending on frame type. The decoder mandates
// the use of the default context, index 0, for keyframes and inter
// frames where the error_resilient_mode or intra_only flag is set. For
// other inter-frames the encoder currently uses only two contexts;
// context 1 for ALTREF frames and context 0 for the others.
if (cm->frame_type == KEY_FRAME) {
vp9_setup_key_frame(cpi);
} else {
if (!cm->intra_only && !cm->error_resilient_mode) {
cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
}
vp9_setup_inter_frame(cpi);
}
// Variance adaptive and in frame q adjustment experiments are mutually
// exclusive.
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_vaq_frame_setup(cpi);
} else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
setup_in_frame_q_adj(cpi);
}
// transform / motion compensation build reconstruction frame
vp9_encode_frame(cpi);
// Update the skip mb flag probabilities based on the distribution
// seen in the last encoder iteration.
// update_base_skip_probs(cpi);
vp9_clear_system_state(); // __asm emms;
}
static void encode_with_recode_loop(VP9_COMP *cpi,
size_t *size,
uint8_t *dest,
int *q,
int bottom_index,
int top_index,
int frame_over_shoot_limit,
int frame_under_shoot_limit) {
int top_index) {
VP9_COMMON *const cm = &cpi->common;
int loop_count = 0;
int loop = 0;
int overshoot_seen = 0;
int undershoot_seen = 0;
int q_low = bottom_index, q_high = top_index;
int frame_over_shoot_limit;
int frame_under_shoot_limit;
// Decide frame size bounds
vp9_rc_compute_frame_size_bounds(cpi, cpi->rc.this_frame_target,
&frame_under_shoot_limit,
&frame_over_shoot_limit);
do {
vp9_clear_system_state(); // __asm emms;
@ -2809,7 +2851,6 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
}
// transform / motion compensation build reconstruction frame
vp9_encode_frame(cpi);
// Update the skip mb flag probabilities based on the distribution
@ -2821,7 +2862,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
// Dummy pack of the bitstream using up to date stats to get an
// accurate estimate of output frame size to determine if we need
// to recode.
if (cpi->sf.recode_loop != 0) {
if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
vp9_save_coding_context(cpi);
cpi->dummy_packing = 1;
if (!cpi->sf.super_fast_rtc)
@ -3024,8 +3065,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
VP9_COMMON *const cm = &cpi->common;
TX_SIZE t;
int q;
int frame_over_shoot_limit;
int frame_under_shoot_limit;
int top_index;
int bottom_index;
@ -3121,7 +3160,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cm->frame_type != KEY_FRAME) {
if (vp9_rc_drop_frame(cpi)) {
vp9_rc_postencode_update_drop_frame(cpi);
cm->current_video_frame++;
++cm->current_video_frame;
return;
}
}
@ -3159,35 +3198,22 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_write_yuv_frame(cpi->Source);
#endif
// 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);
// JBB : This is realtime mode. In real time mode the first frame
// should be larger. Q of 0 is disabled because we force tx size to be
// 16x16...
if (cpi->sf.super_fast_rtc) {
if (cm->current_video_frame == 0)
q /= 3;
if (q == 0)
q++;
}
if (!frame_is_intra_only(cm)) {
cm->interp_filter = 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, &q, bottom_index, top_index,
frame_over_shoot_limit, frame_under_shoot_limit);
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
encode_without_recode_loop(cpi, size, dest, &q);
} else {
encode_with_recode_loop(cpi, size, dest, &q, bottom_index, top_index);
}
// Special case code to reduce pulsing when key frames are forced at a
// fixed interval. Note the reconstruction error if it is the frame before

Просмотреть файл

@ -44,8 +44,9 @@ extern "C" {
#else
#define MIN_GF_INTERVAL 4
#endif
#define DEFAULT_GF_INTERVAL 7
#define DEFAULT_GF_INTERVAL 11
#define DEFAULT_KF_BOOST 2000
#define DEFAULT_GF_BOOST 2000
#define KEY_FRAME_CONTEXT 5
@ -217,6 +218,17 @@ typedef enum {
LAST_FRAME_PARTITION_ALL = 2
} LAST_FRAME_PARTITION_METHOD;
typedef enum {
// No recode.
DISALLOW_RECODE = 0,
// Allow recode for KF and exceeding maximum frame bandwidth.
ALLOW_RECODE_KFMAXBW = 1,
// Allow recode only for KF/ARF/GF frames.
ALLOW_RECODE_KFARFGF = 2,
// Allow recode for all frames based on bitrate constraints.
ALLOW_RECODE = 3,
} RECODE_LOOP_TYPE;
typedef struct {
// This flag refers to whether or not to perform rd optimization.
int RD;
@ -224,11 +236,7 @@ typedef struct {
// Motion search method (Diamond, NSTEP, Hex, Big Diamond, Square, etc).
SEARCH_METHODS search_method;
// Recode_loop can be:
// 0 means we only encode a frame once
// 1 means we can re-encode based on bitrate constraints on any frame
// 2 means we can only recode gold, alt, and key frames.
int recode_loop;
RECODE_LOOP_TYPE recode_loop;
// Subpel_search_method can only be subpel_tree which does a subpixel
// logarithmic search that keeps stepping at 1/2 pixel units until

Просмотреть файл

@ -220,7 +220,7 @@ int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) {
// bits on this frame even if it is a constructed arf.
// The active maximum quantizer insures that an appropriate
// number of bits will be spent if needed for constructed ARFs.
target = 0;
target = min_frame_target;
}
// Clip the frame target to the maximum allowed value.
if (target > rc->max_frame_bandwidth)
@ -569,7 +569,6 @@ static int rc_pick_q_and_adjust_q_bounds_one_pass(const VP9_COMP *cpi,
active_best_quality = inter_minq[rc->avg_frame_qindex[INTER_FRAME]];
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 ((oxcf->end_usage == USAGE_CONSTRAINED_QUALITY) &&
@ -840,12 +839,28 @@ static int rc_pick_q_and_adjust_q_bounds_two_pass(const VP9_COMP *cpi,
int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
int *bottom_index,
int *top_index) {
int q;
if (cpi->pass == 0)
return rc_pick_q_and_adjust_q_bounds_one_pass(
q = rc_pick_q_and_adjust_q_bounds_one_pass(
cpi, bottom_index, top_index);
else
return rc_pick_q_and_adjust_q_bounds_two_pass(
q = rc_pick_q_and_adjust_q_bounds_two_pass(
cpi, bottom_index, top_index);
// JBB : This is realtime mode. In real time mode the first frame
// should be larger. Q of 0 is disabled because we force tx size to be
// 16x16...
if (cpi->sf.super_fast_rtc) {
if (cpi->common.current_video_frame == 0)
q /= 3;
if (q == 0)
q++;
if (q < *bottom_index)
*bottom_index = q;
else if (q > *top_index)
*top_index = q;
}
return q;
}
void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi,
@ -948,7 +963,8 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
rc->projected_frame_size = (bytes_used << 3);
// Post encode loop adjustment of Q prediction.
vp9_rc_update_rate_correction_factors(cpi, (cpi->sf.recode_loop ||
vp9_rc_update_rate_correction_factors(
cpi, (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF ||
cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) ? 2 : 0);
// Keep a record of last Q and ambient average Q.
@ -1040,17 +1056,27 @@ static int test_for_kf_one_pass(VP9_COMP *cpi) {
#define USE_ALTREF_FOR_ONE_PASS 1
static int calc_pframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) {
static const int af_ratio = 5;
const RATE_CONTROL *rc = &cpi->rc;
int target = rc->av_per_frame_bandwidth;
target = vp9_rc_clamp_pframe_target_size(cpi, target);
return target;
int target;
#if USE_ALTREF_FOR_ONE_PASS
target = (!rc->is_src_frame_alt_ref &&
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) ?
(rc->av_per_frame_bandwidth * cpi->rc.baseline_gf_interval * af_ratio) /
(cpi->rc.baseline_gf_interval + af_ratio - 1) :
(rc->av_per_frame_bandwidth * cpi->rc.baseline_gf_interval) /
(cpi->rc.baseline_gf_interval + af_ratio - 1);
#else
target = rc->av_per_frame_bandwidth;
#endif
return vp9_rc_clamp_pframe_target_size(cpi, target);
}
static int calc_iframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) {
static const int kf_ratio = 12;
const RATE_CONTROL *rc = &cpi->rc;
int target = rc->av_per_frame_bandwidth * 8;
target = vp9_rc_clamp_iframe_target_size(cpi, target);
return target;
int target = rc->av_per_frame_bandwidth * kf_ratio;
return vp9_rc_clamp_iframe_target_size(cpi, target);
}
void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) {
@ -1094,7 +1120,7 @@ void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) {
cpi->rc.frames_till_gf_update_due = cpi->rc.frames_to_key;
cpi->refresh_golden_frame = 1;
cpi->rc.source_alt_ref_pending = USE_ALTREF_FOR_ONE_PASS;
cpi->rc.gfu_boost = 2000;
cpi->rc.gfu_boost = DEFAULT_GF_BOOST;
}
if (cm->frame_type == KEY_FRAME)
target = calc_iframe_target_size_one_pass_vbr(cpi);