Merge "Prepare for dynamic frame resizing in the recode loop"
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user