Merge "Prepare for dynamic frame resizing in the recode loop"

This commit is contained in:
Adrian Grange
2014-11-13 15:01:49 -08:00
committed by Gerrit Code Review
9 changed files with 274 additions and 190 deletions

View File

@@ -1625,7 +1625,8 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
}
}
vp9_set_speed_features(cpi);
vp9_set_speed_features_framesize_independent(cpi);
vp9_set_speed_features_framesize_dependent(cpi);
// Allocate memory to store variances for a frame.
CHECK_MEM_ERROR(cm, cpi->source_diff_var,
@@ -2309,7 +2310,6 @@ static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
static int recode_loop_test(const VP9_COMP *cpi,
int high_limit, int low_limit,
int q, int maxq, int minq) {
const VP9_COMMON *const cm = &cpi->common;
const RATE_CONTROL *const rc = &cpi->rc;
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
int force_recode = 0;
@@ -2323,8 +2323,7 @@ static int recode_loop_test(const VP9_COMP *cpi,
// and the frame is a key frame, golden frame or alt_ref_frame
} 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))) {
frame_is_kf_gf_arf(cpi))) {
// General over and under shoot tests
if ((rc->projected_frame_size > high_limit && q < maxq) ||
(rc->projected_frame_size < low_limit && q > minq)) {
@@ -2505,8 +2504,10 @@ static void release_scaled_references(VP9_COMP *cpi) {
const int idx = cpi->scaled_ref_idx[i];
RefCntBuffer *const buf =
idx != INVALID_REF_BUFFER_IDX ? &cm->frame_bufs[idx] : NULL;
if (buf != NULL)
if (buf != NULL) {
--buf->ref_count;
cpi->scaled_ref_idx[i] = INVALID_REF_BUFFER_IDX;
}
}
}
@@ -2617,13 +2618,27 @@ static void set_mv_search_params(VP9_COMP *cpi) {
}
}
static void set_size_independent_vars(VP9_COMP *cpi) {
vp9_set_speed_features_framesize_independent(cpi);
vp9_set_rd_speed_thresholds(cpi);
vp9_set_rd_speed_thresholds_sub8x8(cpi);
cpi->common.interp_filter = cpi->sf.default_interp_filter;
}
static void set_size_dependent_vars(VP9_COMP *cpi, int *q,
int *bottom_index, int *top_index) {
VP9_COMMON *const cm = &cpi->common;
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
// Setup variables that depend on the dimensions of the frame.
set_mv_search_params(cpi);
vp9_set_speed_features_framesize_dependent(cpi);
// Decide q and q bounds.
*q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
if (!frame_is_intra_only(cm)) {
vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
}
// Configure experimental use of segmentation for enhanced coding of
// static regions if indicated.
@@ -2656,19 +2671,6 @@ static void set_size_dependent_vars(VP9_COMP *cpi, int *q,
vp9_denoise(cpi->Source, cpi->Source, l);
}
#endif // CONFIG_VP9_POSTPROC
vp9_set_speed_features(cpi);
vp9_set_rd_speed_thresholds(cpi);
vp9_set_rd_speed_thresholds_sub8x8(cpi);
// Decide q and q bounds.
*q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
if (!frame_is_intra_only(cm)) {
cm->interp_filter = cpi->sf.default_interp_filter;
vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
}
}
static void init_motion_estimation(VP9_COMP *cpi) {
@@ -2681,34 +2683,26 @@ static void init_motion_estimation(VP9_COMP *cpi) {
}
}
extern void vbr_rate_correction(VP9_COMP *cpi,
int * this_frame_target,
const int64_t vbr_bits_off_target);
void set_frame_size(VP9_COMP *cpi) {
int ref_frame;
VP9_COMMON *const cm = &cpi->common;
const RATE_CONTROL *const rc = &cpi->rc;
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
if (oxcf->pass == 2 &&
cm->current_video_frame == 0 &&
oxcf->resize_mode == RESIZE_FIXED &&
oxcf->rc_mode == VPX_VBR) {
// Internal scaling is triggered on the first frame.
vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
oxcf->scaled_frame_height);
}
if ((oxcf->pass == 2) &&
(!cpi->use_svc ||
(is_two_pass_svc(cpi) &&
cpi->svc.encode_empty_frame_state != ENCODING))) {
int target_rate = rc->base_frame_target;
if (oxcf->rc_mode == VPX_VBR)
vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target);
vp9_rc_set_frame_target(cpi, target_rate);
}
if (oxcf->pass == 2 &&
cm->current_video_frame == 0 &&
oxcf->allow_spatial_resampling &&
oxcf->rc_mode == VPX_VBR) {
// Internal scaling is triggered on the first frame.
vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
oxcf->scaled_frame_height);
vp9_set_target_rate(cpi);
}
// Reset the frame pointers to the current frame size.
@@ -2748,9 +2742,8 @@ void set_frame_size(VP9_COMP *cpi) {
}
static void encode_without_recode_loop(VP9_COMP *cpi) {
int q;
int bottom_index, top_index; // Dummy.
VP9_COMMON *const cm = &cpi->common;
int q, bottom_index, top_index; // Dummy variables.
vp9_clear_system_state();
@@ -2763,8 +2756,11 @@ static void encode_without_recode_loop(VP9_COMP *cpi) {
cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
&cpi->scaled_last_source);
vp9_scale_references(cpi);
if (frame_is_intra_only(cm) == 0) {
vp9_scale_references(cpi);
}
set_size_independent_vars(cpi);
set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
vp9_set_quantizer(cm, q);
@@ -2792,8 +2788,6 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
uint8_t *dest) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
int q;
int q_low, q_high;
int bottom_index, top_index;
int loop_count = 0;
int loop = 0;
@@ -2801,31 +2795,42 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
int undershoot_seen = 0;
int frame_over_shoot_limit;
int frame_under_shoot_limit;
int q = 0, q_low = 0, q_high = 0;
int frame_size_changed = 0;
set_size_independent_vars(cpi);
do {
vp9_clear_system_state();
if (loop_count == 0) {
set_frame_size(cpi);
// Decide frame size bounds
vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
&frame_under_shoot_limit,
&frame_over_shoot_limit);
cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
&cpi->scaled_source);
if (cpi->unscaled_last_source != NULL)
cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
&cpi->scaled_last_source);
vp9_scale_references(cpi);
set_frame_size(cpi);
if (loop_count == 0 || frame_size_changed != 0) {
set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
q_low = bottom_index;
q_high = top_index;
// TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
set_mv_search_params(cpi);
}
// Decide frame size bounds
vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
&frame_under_shoot_limit,
&frame_over_shoot_limit);
cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
&cpi->scaled_source);
if (cpi->unscaled_last_source != NULL)
cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
&cpi->scaled_last_source);
if (frame_is_intra_only(cm) == 0) {
if (loop_count > 0) {
release_scaled_references(cpi);
}
vp9_scale_references(cpi);
}
vp9_set_quantizer(cm, q);
@@ -3272,7 +3277,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
if (cm->seg.update_map)
update_reference_segmentation_map(cpi);
release_scaled_references(cpi);
if (frame_is_intra_only(cm) == 0) {
release_scaled_references(cpi);
}
vp9_update_reference_frames(cpi);
for (t = TX_4X4; t <= TX_32X32; t++)
@@ -3751,7 +3758,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
// No frame encoded, or frame was dropped, release scaled references.
if (*size == 0) {
if ((*size == 0) && (frame_is_intra_only(cm) == 0)) {
release_scaled_references(cpi);
}