Merge "Move frame re-sizing into the recode loop"
This commit is contained in:
commit
3758650c98
@ -2409,30 +2409,37 @@ void vp9_scale_references(VP9_COMP *cpi) {
|
|||||||
const VP9_REFFRAME ref_mask[3] = {VP9_LAST_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG};
|
const VP9_REFFRAME ref_mask[3] = {VP9_LAST_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG};
|
||||||
|
|
||||||
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
||||||
const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
|
||||||
const YV12_BUFFER_CONFIG *const ref = &cm->frame_bufs[idx].buf;
|
|
||||||
|
|
||||||
// Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
|
// Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
|
||||||
if ((cpi->ref_frame_flags & ref_mask[ref_frame - 1]) &&
|
if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
|
||||||
(ref->y_crop_width != cm->width || ref->y_crop_height != cm->height)) {
|
const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
||||||
const int new_fb = get_free_fb(cm);
|
const YV12_BUFFER_CONFIG *const ref = &cm->frame_bufs[idx].buf;
|
||||||
vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
|
|
||||||
cm->width, cm->height,
|
|
||||||
cm->subsampling_x, cm->subsampling_y,
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
cm->use_highbitdepth,
|
if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
const int new_fb = get_free_fb(cm);
|
||||||
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
cm->width, cm->height,
|
||||||
scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf,
|
cm->subsampling_x, cm->subsampling_y,
|
||||||
(int)cm->bit_depth);
|
cm->use_highbitdepth,
|
||||||
|
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
||||||
|
scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf,
|
||||||
|
(int)cm->bit_depth);
|
||||||
#else
|
#else
|
||||||
scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
|
if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
|
||||||
|
const int new_fb = get_free_fb(cm);
|
||||||
|
vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
|
||||||
|
cm->width, cm->height,
|
||||||
|
cm->subsampling_x, cm->subsampling_y,
|
||||||
|
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
||||||
|
scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
|
cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
|
||||||
|
} else {
|
||||||
|
cpi->scaled_ref_idx[ref_frame - 1] = idx;
|
||||||
|
++cm->frame_bufs[idx].ref_count;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cpi->scaled_ref_idx[ref_frame - 1] = idx;
|
cpi->scaled_ref_idx[ref_frame - 1] = INVALID_REF_BUFFER_IDX;
|
||||||
cm->frame_bufs[idx].ref_count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2440,9 +2447,13 @@ void vp9_scale_references(VP9_COMP *cpi) {
|
|||||||
static void release_scaled_references(VP9_COMP *cpi) {
|
static void release_scaled_references(VP9_COMP *cpi) {
|
||||||
VP9_COMMON *cm = &cpi->common;
|
VP9_COMMON *cm = &cpi->common;
|
||||||
int i;
|
int i;
|
||||||
|
for (i = 0; i < MAX_REF_FRAMES; ++i) {
|
||||||
for (i = 0; i < 3; i++)
|
const int idx = cpi->scaled_ref_idx[i];
|
||||||
cm->frame_bufs[cpi->scaled_ref_idx[i]].ref_count--;
|
RefCntBuffer *const buf =
|
||||||
|
idx != INVALID_REF_BUFFER_IDX ? &cm->frame_bufs[idx] : NULL;
|
||||||
|
if (buf != NULL)
|
||||||
|
--buf->ref_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void full_to_model_count(unsigned int *model_count,
|
static void full_to_model_count(unsigned int *model_count,
|
||||||
@ -2527,10 +2538,181 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void encode_without_recode_loop(VP9_COMP *cpi,
|
static void set_mv_search_params(VP9_COMP *cpi) {
|
||||||
int q) {
|
const VP9_COMMON *const cm = &cpi->common;
|
||||||
|
const unsigned int max_mv_def = MIN(cm->width, cm->height);
|
||||||
|
|
||||||
|
// Default based on max resolution.
|
||||||
|
cpi->mv_step_param = vp9_init_search_range(max_mv_def);
|
||||||
|
|
||||||
|
if (cpi->sf.mv.auto_mv_step_size) {
|
||||||
|
if (frame_is_intra_only(cm)) {
|
||||||
|
// Initialize max_mv_magnitude for use in the first INTER frame
|
||||||
|
// after a key/intra-only frame.
|
||||||
|
cpi->max_mv_magnitude = max_mv_def;
|
||||||
|
} else {
|
||||||
|
if (cm->show_frame) {
|
||||||
|
// Allow mv_steps to correspond to twice the max mv magnitude found
|
||||||
|
// in the previous frame, capped by the default max_mv_magnitude based
|
||||||
|
// on resolution.
|
||||||
|
cpi->mv_step_param =
|
||||||
|
vp9_init_search_range(MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
|
||||||
|
}
|
||||||
|
cpi->max_mv_magnitude = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_size_dependent_vars(VP9_COMP *cpi, int *q,
|
||||||
|
int *bottom_index, int *top_index) {
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
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);
|
||||||
|
|
||||||
|
// Configure experimental use of segmentation for enhanced coding of
|
||||||
|
// static regions if indicated.
|
||||||
|
// Only allowed in the second pass of a two pass encode, as it requires
|
||||||
|
// lagged coding, and if the relevant speed feature flag is set.
|
||||||
|
if (oxcf->pass == 2 && cpi->sf.static_segmentation)
|
||||||
|
configure_static_seg_features(cpi);
|
||||||
|
|
||||||
|
#if CONFIG_VP9_POSTPROC
|
||||||
|
if (oxcf->noise_sensitivity > 0) {
|
||||||
|
int l = 0;
|
||||||
|
switch (oxcf->noise_sensitivity) {
|
||||||
|
case 1:
|
||||||
|
l = 20;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
l = 40;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
l = 60;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
l = 100;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
l = 150;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
int y_stride = cpi->scaled_source.y_stride;
|
||||||
|
|
||||||
|
if (cpi->sf.mv.search_method == NSTEP) {
|
||||||
|
vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
|
||||||
|
} else if (cpi->sf.mv.search_method == DIAMOND) {
|
||||||
|
vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) &&
|
||||||
|
(!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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the frame pointers to the current frame size.
|
||||||
|
vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
|
||||||
|
cm->width, cm->height,
|
||||||
|
cm->subsampling_x, cm->subsampling_y,
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
cm->use_highbitdepth,
|
||||||
|
#endif
|
||||||
|
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
alloc_util_frame_buffers(cpi);
|
||||||
|
init_motion_estimation(cpi);
|
||||||
|
|
||||||
|
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
||||||
|
const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
||||||
|
YV12_BUFFER_CONFIG *const buf = &cm->frame_bufs[idx].buf;
|
||||||
|
RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
|
||||||
|
ref_buf->buf = buf;
|
||||||
|
ref_buf->idx = idx;
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
||||||
|
buf->y_crop_width, buf->y_crop_height,
|
||||||
|
cm->width, cm->height,
|
||||||
|
(buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
|
||||||
|
1 : 0);
|
||||||
|
#else
|
||||||
|
vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
||||||
|
buf->y_crop_width, buf->y_crop_height,
|
||||||
|
cm->width, cm->height);
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
if (vp9_is_scaled(&ref_buf->sf))
|
||||||
|
vp9_extend_frame_borders(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void encode_without_recode_loop(VP9_COMP *cpi) {
|
||||||
|
int q;
|
||||||
|
int bottom_index, top_index; // Dummy.
|
||||||
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
|
|
||||||
vp9_clear_system_state();
|
vp9_clear_system_state();
|
||||||
|
|
||||||
|
set_frame_size(cpi);
|
||||||
|
|
||||||
|
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_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
|
||||||
|
|
||||||
vp9_set_quantizer(cm, q);
|
vp9_set_quantizer(cm, q);
|
||||||
setup_frame(cpi);
|
setup_frame(cpi);
|
||||||
// Variance adaptive and in frame q adjustment experiments are mutually
|
// Variance adaptive and in frame q adjustment experiments are mutually
|
||||||
@ -2553,28 +2735,45 @@ static void encode_without_recode_loop(VP9_COMP *cpi,
|
|||||||
|
|
||||||
static void encode_with_recode_loop(VP9_COMP *cpi,
|
static void encode_with_recode_loop(VP9_COMP *cpi,
|
||||||
size_t *size,
|
size_t *size,
|
||||||
uint8_t *dest,
|
uint8_t *dest) {
|
||||||
int q,
|
|
||||||
int bottom_index,
|
|
||||||
int top_index) {
|
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
RATE_CONTROL *const rc = &cpi->rc;
|
RATE_CONTROL *const rc = &cpi->rc;
|
||||||
|
int q;
|
||||||
|
int q_low, q_high;
|
||||||
|
int bottom_index, top_index;
|
||||||
int loop_count = 0;
|
int loop_count = 0;
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
int overshoot_seen = 0;
|
int overshoot_seen = 0;
|
||||||
int undershoot_seen = 0;
|
int undershoot_seen = 0;
|
||||||
int q_low = bottom_index, q_high = top_index;
|
|
||||||
int frame_over_shoot_limit;
|
int frame_over_shoot_limit;
|
||||||
int frame_under_shoot_limit;
|
int frame_under_shoot_limit;
|
||||||
|
|
||||||
// Decide frame size bounds
|
|
||||||
vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
|
|
||||||
&frame_under_shoot_limit,
|
|
||||||
&frame_over_shoot_limit);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
vp9_clear_system_state();
|
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_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
|
||||||
|
|
||||||
|
q_low = bottom_index;
|
||||||
|
q_high = top_index;
|
||||||
|
}
|
||||||
|
|
||||||
vp9_set_quantizer(cm, q);
|
vp9_set_quantizer(cm, q);
|
||||||
|
|
||||||
if (loop_count == 0)
|
if (loop_count == 0)
|
||||||
@ -2816,25 +3015,6 @@ YV12_BUFFER_CONFIG *vp9_scale_if_required(VP9_COMMON *cm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_arf_sign_bias(VP9_COMP *cpi) {
|
static void set_arf_sign_bias(VP9_COMP *cpi) {
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
int arf_sign_bias;
|
int arf_sign_bias;
|
||||||
@ -2851,31 +3031,6 @@ static void set_arf_sign_bias(VP9_COMP *cpi) {
|
|||||||
cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
|
cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_mv_search_params(VP9_COMP *cpi) {
|
|
||||||
const VP9_COMMON *const cm = &cpi->common;
|
|
||||||
const unsigned int max_mv_def = MIN(cm->width, cm->height);
|
|
||||||
|
|
||||||
// Default based on max resolution.
|
|
||||||
cpi->mv_step_param = vp9_init_search_range(max_mv_def);
|
|
||||||
|
|
||||||
if (cpi->sf.mv.auto_mv_step_size) {
|
|
||||||
if (frame_is_intra_only(cm)) {
|
|
||||||
// Initialize max_mv_magnitude for use in the first INTER frame
|
|
||||||
// after a key/intra-only frame.
|
|
||||||
cpi->max_mv_magnitude = max_mv_def;
|
|
||||||
} else {
|
|
||||||
if (cm->show_frame)
|
|
||||||
// Allow mv_steps to correspond to twice the max mv magnitude found
|
|
||||||
// in the previous frame, capped by the default max_mv_magnitude based
|
|
||||||
// on resolution.
|
|
||||||
cpi->mv_step_param =
|
|
||||||
vp9_init_search_range(MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
|
|
||||||
cpi->max_mv_magnitude = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int setup_interp_filter_search_mask(VP9_COMP *cpi) {
|
int setup_interp_filter_search_mask(VP9_COMP *cpi) {
|
||||||
INTERP_FILTER ifilter;
|
INTERP_FILTER ifilter;
|
||||||
int ref_total[MAX_REF_FRAMES] = {0};
|
int ref_total[MAX_REF_FRAMES] = {0};
|
||||||
@ -2910,21 +3065,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||||||
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
||||||
struct segmentation *const seg = &cm->seg;
|
struct segmentation *const seg = &cm->seg;
|
||||||
TX_SIZE t;
|
TX_SIZE t;
|
||||||
int q;
|
|
||||||
int top_index;
|
|
||||||
int bottom_index;
|
|
||||||
|
|
||||||
set_ext_overrides(cpi);
|
set_ext_overrides(cpi);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
vp9_clear_system_state();
|
vp9_clear_system_state();
|
||||||
|
|
||||||
// Enable or disable mode based tweaking of the zbin.
|
// Enable or disable mode based tweaking of the zbin.
|
||||||
@ -2939,14 +3082,11 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||||||
// Set default state for segment based loop filter update flags.
|
// Set default state for segment based loop filter update flags.
|
||||||
cm->lf.mode_ref_delta_update = 0;
|
cm->lf.mode_ref_delta_update = 0;
|
||||||
|
|
||||||
set_mv_search_params(cpi);
|
|
||||||
|
|
||||||
if (cpi->oxcf.pass == 2 &&
|
if (cpi->oxcf.pass == 2 &&
|
||||||
cpi->sf.adaptive_interp_filter_search)
|
cpi->sf.adaptive_interp_filter_search)
|
||||||
cpi->sf.interp_filter_search_mask =
|
cpi->sf.interp_filter_search_mask =
|
||||||
setup_interp_filter_search_mask(cpi);
|
setup_interp_filter_search_mask(cpi);
|
||||||
|
|
||||||
|
|
||||||
// Set various flags etc to special state if it is a key frame.
|
// Set various flags etc to special state if it is a key frame.
|
||||||
if (frame_is_intra_only(cm)) {
|
if (frame_is_intra_only(cm)) {
|
||||||
// Reset the loop filter deltas and segmentation map.
|
// Reset the loop filter deltas and segmentation map.
|
||||||
@ -3006,20 +3146,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure experimental use of segmentation for enhanced coding of
|
|
||||||
// static regions if indicated.
|
|
||||||
// Only allowed in second pass of two pass (as requires lagged coding)
|
|
||||||
// and if the relevant speed feature flag is set.
|
|
||||||
if (oxcf->pass == 2 && cpi->sf.static_segmentation)
|
|
||||||
configure_static_seg_features(cpi);
|
|
||||||
|
|
||||||
// Check if the current frame is skippable for the partition search in the
|
|
||||||
// second pass according to the first pass stats
|
|
||||||
if (cpi->sf.allow_partition_search_skip && oxcf->pass == 2 &&
|
|
||||||
(!cpi->use_svc || is_two_pass_svc(cpi))) {
|
|
||||||
cpi->partition_search_skippable_frame = is_skippable_frame(cpi);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For 1 pass CBR, check if we are dropping this frame.
|
// For 1 pass CBR, check if we are dropping this frame.
|
||||||
// Never drop on key frame.
|
// Never drop on key frame.
|
||||||
if (oxcf->pass == 0 &&
|
if (oxcf->pass == 0 &&
|
||||||
@ -3034,31 +3160,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||||||
|
|
||||||
vp9_clear_system_state();
|
vp9_clear_system_state();
|
||||||
|
|
||||||
#if CONFIG_VP9_POSTPROC
|
|
||||||
if (oxcf->noise_sensitivity > 0) {
|
|
||||||
int l = 0;
|
|
||||||
switch (oxcf->noise_sensitivity) {
|
|
||||||
case 1:
|
|
||||||
l = 20;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
l = 40;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
l = 60;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
l = 100;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
l = 150;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
vp9_denoise(cpi->Source, cpi->Source, l);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_INTERNAL_STATS
|
#if CONFIG_INTERNAL_STATS
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -3067,24 +3168,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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;
|
|
||||||
/* TODO: Decide this more intelligently */
|
|
||||||
vp9_set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
|
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
|
||||||
encode_without_recode_loop(cpi, q);
|
encode_without_recode_loop(cpi);
|
||||||
} else {
|
} else {
|
||||||
encode_with_recode_loop(cpi, size, dest, q, bottom_index, top_index);
|
encode_with_recode_loop(cpi, size, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||||
@ -3227,16 +3314,6 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size,
|
|||||||
vp9_twopass_postencode_update(cpi);
|
vp9_twopass_postencode_update(cpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_motion_estimation(VP9_COMP *cpi) {
|
|
||||||
int y_stride = cpi->scaled_source.y_stride;
|
|
||||||
|
|
||||||
if (cpi->sf.mv.search_method == NSTEP) {
|
|
||||||
vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
|
|
||||||
} else if (cpi->sf.mv.search_method == DIAMOND) {
|
|
||||||
vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_initial_width(VP9_COMP *cpi,
|
static void check_initial_width(VP9_COMP *cpi,
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
int use_highbitdepth,
|
int use_highbitdepth,
|
||||||
@ -3255,10 +3332,11 @@ static void check_initial_width(VP9_COMP *cpi,
|
|||||||
alloc_ref_frame_buffers(cpi);
|
alloc_ref_frame_buffers(cpi);
|
||||||
alloc_util_frame_buffers(cpi);
|
alloc_util_frame_buffers(cpi);
|
||||||
|
|
||||||
init_motion_estimation(cpi);
|
init_motion_estimation(cpi); // TODO(agrange) This can be removed.
|
||||||
|
|
||||||
cpi->initial_width = cm->width;
|
cpi->initial_width = cm->width;
|
||||||
cpi->initial_height = cm->height;
|
cpi->initial_height = cm->height;
|
||||||
|
cpi->initial_mbs = cm->MBs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3400,14 +3478,13 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
|||||||
int64_t *time_stamp, int64_t *time_end, int flush) {
|
int64_t *time_stamp, int64_t *time_end, int flush) {
|
||||||
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
|
|
||||||
RATE_CONTROL *const rc = &cpi->rc;
|
RATE_CONTROL *const rc = &cpi->rc;
|
||||||
struct vpx_usec_timer cmptimer;
|
struct vpx_usec_timer cmptimer;
|
||||||
YV12_BUFFER_CONFIG *force_src_buffer = NULL;
|
YV12_BUFFER_CONFIG *force_src_buffer = NULL;
|
||||||
struct lookahead_entry *last_source = NULL;
|
struct lookahead_entry *last_source = NULL;
|
||||||
struct lookahead_entry *source = NULL;
|
struct lookahead_entry *source = NULL;
|
||||||
MV_REFERENCE_FRAME ref_frame;
|
|
||||||
int arf_src_index;
|
int arf_src_index;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (is_two_pass_svc(cpi)) {
|
if (is_two_pass_svc(cpi)) {
|
||||||
#if CONFIG_SPATIAL_SVC
|
#if CONFIG_SPATIAL_SVC
|
||||||
@ -3546,24 +3623,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
|||||||
vp9_restore_layer_context(cpi);
|
vp9_restore_layer_context(cpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// start with a 0 size frame
|
// Find a free buffer for the new frame, releasing the reference previously
|
||||||
*size = 0;
|
// held.
|
||||||
|
|
||||||
/* find a free buffer for the new frame, releasing the reference previously
|
|
||||||
* held.
|
|
||||||
*/
|
|
||||||
cm->frame_bufs[cm->new_fb_idx].ref_count--;
|
cm->frame_bufs[cm->new_fb_idx].ref_count--;
|
||||||
cm->new_fb_idx = get_free_fb(cm);
|
cm->new_fb_idx = get_free_fb(cm);
|
||||||
|
|
||||||
// For two pass encodes analyse the first pass stats and determine
|
|
||||||
// the bit allocation and other parameters for this frame / group of frames.
|
|
||||||
if ((oxcf->pass == 2) &&
|
|
||||||
(!cpi->use_svc ||
|
|
||||||
(is_two_pass_svc(cpi) &&
|
|
||||||
cpi->svc.encode_empty_frame_state != ENCODING))) {
|
|
||||||
vp9_rc_get_second_pass_params(cpi);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cpi->use_svc && cpi->multi_arf_allowed) {
|
if (!cpi->use_svc && cpi->multi_arf_allowed) {
|
||||||
if (cm->frame_type == KEY_FRAME) {
|
if (cm->frame_type == KEY_FRAME) {
|
||||||
init_buffer_indices(cpi);
|
init_buffer_indices(cpi);
|
||||||
@ -3573,56 +3637,27 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start with a 0 size frame.
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
cpi->frame_flags = *frame_flags;
|
cpi->frame_flags = *frame_flags;
|
||||||
|
|
||||||
if (oxcf->pass == 2 &&
|
if ((oxcf->pass == 2) &&
|
||||||
cm->current_video_frame == 0 &&
|
(!cpi->use_svc ||
|
||||||
oxcf->allow_spatial_resampling &&
|
(is_two_pass_svc(cpi) &&
|
||||||
oxcf->rc_mode == VPX_VBR) {
|
cpi->svc.encode_empty_frame_state != ENCODING))) {
|
||||||
// Internal scaling is triggered on the first frame.
|
vp9_rc_get_second_pass_params(cpi);
|
||||||
vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
|
} else {
|
||||||
oxcf->scaled_frame_height);
|
set_frame_size(cpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the frame pointers to the current frame size
|
|
||||||
vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
|
|
||||||
cm->width, cm->height,
|
|
||||||
cm->subsampling_x, cm->subsampling_y,
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
cm->use_highbitdepth,
|
|
||||||
#endif
|
|
||||||
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
alloc_util_frame_buffers(cpi);
|
|
||||||
init_motion_estimation(cpi);
|
|
||||||
|
|
||||||
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
|
||||||
const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
|
||||||
YV12_BUFFER_CONFIG *const buf = &cm->frame_bufs[idx].buf;
|
|
||||||
RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
|
|
||||||
ref_buf->buf = buf;
|
|
||||||
ref_buf->idx = idx;
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
|
||||||
buf->y_crop_width, buf->y_crop_height,
|
|
||||||
cm->width, cm->height,
|
|
||||||
(buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
|
|
||||||
1 : 0);
|
|
||||||
#else
|
|
||||||
vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
|
||||||
buf->y_crop_width, buf->y_crop_height,
|
|
||||||
cm->width, cm->height);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
if (vp9_is_scaled(&ref_buf->sf))
|
|
||||||
vp9_extend_frame_borders(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
|
|
||||||
|
|
||||||
if (oxcf->aq_mode == VARIANCE_AQ) {
|
if (oxcf->aq_mode == VARIANCE_AQ) {
|
||||||
vp9_vaq_init();
|
vp9_vaq_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_REF_FRAMES; ++i)
|
||||||
|
cpi->scaled_ref_idx[i] = INVALID_REF_BUFFER_IDX;
|
||||||
|
|
||||||
if (oxcf->pass == 1 &&
|
if (oxcf->pass == 1 &&
|
||||||
(!cpi->use_svc || is_two_pass_svc(cpi))) {
|
(!cpi->use_svc || is_two_pass_svc(cpi))) {
|
||||||
const int lossless = is_lossless_requested(oxcf);
|
const int lossless = is_lossless_requested(oxcf);
|
||||||
@ -3651,7 +3686,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
|||||||
if (cm->refresh_frame_context)
|
if (cm->refresh_frame_context)
|
||||||
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
|
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
|
||||||
|
|
||||||
// Frame was dropped, release scaled references.
|
// No frame encoded, or frame was dropped, release scaled references.
|
||||||
if (*size == 0) {
|
if (*size == 0) {
|
||||||
release_scaled_references(cpi);
|
release_scaled_references(cpi);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_GF_INTERVAL 10
|
#define DEFAULT_GF_INTERVAL 10
|
||||||
|
#define INVALID_REF_BUFFER_IDX -1 // Marks an invalid reference buffer id.
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int nmvjointcost[MV_JOINTS];
|
int nmvjointcost[MV_JOINTS];
|
||||||
@ -241,7 +242,7 @@ typedef struct VP9_COMP {
|
|||||||
// For a still frame, this flag is set to 1 to skip partition search.
|
// For a still frame, this flag is set to 1 to skip partition search.
|
||||||
int partition_search_skippable_frame;
|
int partition_search_skippable_frame;
|
||||||
|
|
||||||
int scaled_ref_idx[3];
|
int scaled_ref_idx[MAX_REF_FRAMES];
|
||||||
int lst_fb_idx;
|
int lst_fb_idx;
|
||||||
int gld_fb_idx;
|
int gld_fb_idx;
|
||||||
int alt_fb_idx;
|
int alt_fb_idx;
|
||||||
@ -374,6 +375,10 @@ typedef struct VP9_COMP {
|
|||||||
|
|
||||||
int initial_width;
|
int initial_width;
|
||||||
int initial_height;
|
int initial_height;
|
||||||
|
int initial_mbs; // Number of MBs in the full-size frame; to be used to
|
||||||
|
// normalize the firstpass stats. This will differ from the
|
||||||
|
// number of MBs in the current frame when the frame is
|
||||||
|
// scaled.
|
||||||
|
|
||||||
int use_svc;
|
int use_svc;
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ static void output_fpmb_stats(uint8_t *this_frame_mb_stats, VP9_COMMON *cm,
|
|||||||
struct vpx_codec_cx_pkt pkt;
|
struct vpx_codec_cx_pkt pkt;
|
||||||
pkt.kind = VPX_CODEC_FPMB_STATS_PKT;
|
pkt.kind = VPX_CODEC_FPMB_STATS_PKT;
|
||||||
pkt.data.firstpass_mb_stats.buf = this_frame_mb_stats;
|
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);
|
vpx_codec_pkt_list_add(pktlist, &pkt);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -483,7 +483,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
|||||||
|
|
||||||
#if CONFIG_FP_MB_STATS
|
#if CONFIG_FP_MB_STATS
|
||||||
if (cpi->use_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
|
#endif
|
||||||
|
|
||||||
@ -934,12 +934,14 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
|||||||
vp9_clear_system_state();
|
vp9_clear_system_state();
|
||||||
{
|
{
|
||||||
FIRSTPASS_STATS fps;
|
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
|
// in static regions. The allocation per MB declines for larger formats
|
||||||
// where the typical "real" energy per MB also falls.
|
// where the typical "real" energy per MB also falls.
|
||||||
// Initial estimate here uses sqrt(mbs) to define the min_err, where the
|
// Initial estimate here uses sqrt(mbs) to define the min_err, where the
|
||||||
// number of mbs is propotional to image area.
|
// number of mbs is proportional to the image area.
|
||||||
const double min_err = 200 * sqrt(cm->MBs);
|
const int num_mbs =
|
||||||
|
cpi->oxcf.allow_spatial_resampling ? cpi->initial_mbs : cpi->common.MBs;
|
||||||
|
const double min_err = 200 * sqrt(num_mbs);
|
||||||
|
|
||||||
fps.frame = cm->current_video_frame;
|
fps.frame = cm->current_video_frame;
|
||||||
fps.spatial_layer_id = cpi->svc.spatial_layer_id;
|
fps.spatial_layer_id = cpi->svc.spatial_layer_id;
|
||||||
@ -947,9 +949,9 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
|||||||
fps.sr_coded_error = (double)(sr_coded_error >> 8) + min_err;
|
fps.sr_coded_error = (double)(sr_coded_error >> 8) + min_err;
|
||||||
fps.intra_error = (double)(intra_error >> 8) + min_err;
|
fps.intra_error = (double)(intra_error >> 8) + min_err;
|
||||||
fps.count = 1.0;
|
fps.count = 1.0;
|
||||||
fps.pcnt_inter = (double)intercount / cm->MBs;
|
fps.pcnt_inter = (double)intercount / num_mbs;
|
||||||
fps.pcnt_second_ref = (double)second_ref_count / cm->MBs;
|
fps.pcnt_second_ref = (double)second_ref_count / num_mbs;
|
||||||
fps.pcnt_neutral = (double)neutral_count / cm->MBs;
|
fps.pcnt_neutral = (double)neutral_count / num_mbs;
|
||||||
|
|
||||||
if (mvcount > 0) {
|
if (mvcount > 0) {
|
||||||
fps.MVr = (double)sum_mvr / mvcount;
|
fps.MVr = (double)sum_mvr / mvcount;
|
||||||
@ -960,7 +962,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
|||||||
fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / 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.mv_in_out_count = (double)sum_in_vectors / (mvcount * 2);
|
||||||
fps.new_mv_count = new_mv_count;
|
fps.new_mv_count = new_mv_count;
|
||||||
fps.pcnt_motion = (double)mvcount / cm->MBs;
|
fps.pcnt_motion = (double)mvcount / num_mbs;
|
||||||
} else {
|
} else {
|
||||||
fps.MVr = 0.0;
|
fps.MVr = 0.0;
|
||||||
fps.mvr_abs = 0.0;
|
fps.mvr_abs = 0.0;
|
||||||
@ -1074,7 +1076,8 @@ static int get_twopass_worst_quality(const VP9_COMP *cpi,
|
|||||||
if (section_target_bandwidth <= 0) {
|
if (section_target_bandwidth <= 0) {
|
||||||
return rc->worst_quality; // Highest value allowed
|
return rc->worst_quality; // Highest value allowed
|
||||||
} else {
|
} else {
|
||||||
const int num_mbs = cpi->common.MBs;
|
const int num_mbs =
|
||||||
|
cpi->oxcf.allow_spatial_resampling ? cpi->initial_mbs : cpi->common.MBs;
|
||||||
const double section_err = stats->coded_error / stats->count;
|
const double section_err = stats->coded_error / stats->count;
|
||||||
const double err_per_mb = section_err / num_mbs;
|
const double err_per_mb = section_err / num_mbs;
|
||||||
const double speed_term = 1.0 + 0.04 * oxcf->speed;
|
const double speed_term = 1.0 + 0.04 * oxcf->speed;
|
||||||
@ -1188,9 +1191,12 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
|
|||||||
#define LOW_SR_DIFF_TRHESH 0.1
|
#define LOW_SR_DIFF_TRHESH 0.1
|
||||||
#define SR_DIFF_MAX 128.0
|
#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) {
|
const FIRSTPASS_STATS *frame) {
|
||||||
double sr_diff = (frame->sr_coded_error - frame->coded_error) / cm->MBs;
|
const int num_mbs =
|
||||||
|
cpi->oxcf.allow_spatial_resampling ? cpi->initial_mbs : cpi->common.MBs;
|
||||||
|
double sr_diff =
|
||||||
|
(frame->sr_coded_error - frame->coded_error) / num_mbs;
|
||||||
double sr_decay = 1.0;
|
double sr_decay = 1.0;
|
||||||
const double motion_amplitude_factor =
|
const double motion_amplitude_factor =
|
||||||
frame->pcnt_motion * ((frame->mvc_abs + frame->mvr_abs) / 2);
|
frame->pcnt_motion * ((frame->mvc_abs + frame->mvr_abs) / 2);
|
||||||
@ -1207,19 +1213,19 @@ static double get_sr_decay_rate(const VP9_COMMON *cm,
|
|||||||
|
|
||||||
// This function gives an estimate of how badly we believe the prediction
|
// This function gives an estimate of how badly we believe the prediction
|
||||||
// quality is decaying from frame to frame.
|
// 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 FIRSTPASS_STATS *frame) {
|
||||||
const double zero_motion_pct = frame->pcnt_inter -
|
const double zero_motion_pct = frame->pcnt_inter -
|
||||||
frame->pcnt_motion;
|
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);
|
return MIN(sr_decay, zero_motion_pct);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ZM_POWER_FACTOR 0.75
|
#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 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 =
|
const double zero_motion_factor =
|
||||||
(0.95 * pow((next_frame->pcnt_inter - next_frame->pcnt_motion),
|
(0.95 * pow((next_frame->pcnt_inter - next_frame->pcnt_motion),
|
||||||
ZM_POWER_FACTOR));
|
ZM_POWER_FACTOR));
|
||||||
@ -1314,9 +1320,11 @@ static double calc_frame_boost(VP9_COMP *cpi,
|
|||||||
vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[INTER_FRAME],
|
vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[INTER_FRAME],
|
||||||
cpi->common.bit_depth);
|
cpi->common.bit_depth);
|
||||||
const double boost_correction = MIN((0.5 + (lq * 0.015)), 1.5);
|
const double boost_correction = MIN((0.5 + (lq * 0.015)), 1.5);
|
||||||
|
const int num_mbs =
|
||||||
|
cpi->oxcf.allow_spatial_resampling ? cpi->initial_mbs : cpi->common.MBs;
|
||||||
|
|
||||||
// Underlying boost factor is based on inter error ratio.
|
// 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);
|
DOUBLE_DIVIDE_CHECK(this_frame->coded_error);
|
||||||
frame_boost = frame_boost * BOOST_FACTOR * boost_correction;
|
frame_boost = frame_boost * BOOST_FACTOR * boost_correction;
|
||||||
|
|
||||||
@ -1365,7 +1373,7 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset,
|
|||||||
|
|
||||||
// Accumulate the effect of prediction quality decay.
|
// Accumulate the effect of prediction quality decay.
|
||||||
if (!flash_detected) {
|
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
|
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
|
||||||
? MIN_DECAY_FACTOR : decay_accumulator;
|
? MIN_DECAY_FACTOR : decay_accumulator;
|
||||||
}
|
}
|
||||||
@ -1404,7 +1412,7 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset,
|
|||||||
|
|
||||||
// Cumulative effect of prediction quality decay.
|
// Cumulative effect of prediction quality decay.
|
||||||
if (!flash_detected) {
|
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
|
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
|
||||||
? MIN_DECAY_FACTOR : decay_accumulator;
|
? MIN_DECAY_FACTOR : decay_accumulator;
|
||||||
}
|
}
|
||||||
@ -1723,7 +1731,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
gf_group_err -= gf_first_frame_err;
|
gf_group_err -= gf_first_frame_err;
|
||||||
|
|
||||||
// Motion breakout threshold for loop below depends on image size.
|
// 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->common.height + cpi->common.width) / 4.0;
|
||||||
|
|
||||||
// Set a maximum and minimum interval for the GF group.
|
// Set a maximum and minimum interval for the GF group.
|
||||||
// If the image appears almost completely static we can extend beyond this.
|
// If the image appears almost completely static we can extend beyond this.
|
||||||
@ -1775,14 +1784,14 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
// Accumulate the effect of prediction quality decay.
|
// Accumulate the effect of prediction quality decay.
|
||||||
if (!flash_detected) {
|
if (!flash_detected) {
|
||||||
last_loop_decay_rate = loop_decay_rate;
|
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;
|
decay_accumulator = decay_accumulator * loop_decay_rate;
|
||||||
|
|
||||||
// Monitor for static sections.
|
// Monitor for static sections.
|
||||||
zero_motion_accumulator =
|
zero_motion_accumulator =
|
||||||
MIN(zero_motion_accumulator,
|
MIN(zero_motion_accumulator,
|
||||||
get_zero_motion_factor(&cpi->common, &next_frame));
|
get_zero_motion_factor(cpi, &next_frame));
|
||||||
|
|
||||||
// Break clause to detect very still sections after motion. For example,
|
// Break clause to detect very still sections after motion. For example,
|
||||||
// a static image after a fade or other transition.
|
// a static image after a fade or other transition.
|
||||||
@ -2048,8 +2057,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// How fast is the prediction quality decaying?
|
// How fast is the prediction quality decaying?
|
||||||
loop_decay_rate = get_prediction_decay_rate(&cpi->common,
|
loop_decay_rate = get_prediction_decay_rate(cpi, twopass->stats_in);
|
||||||
twopass->stats_in);
|
|
||||||
|
|
||||||
// We want to know something about the recent past... rather than
|
// We want to know something about the recent past... rather than
|
||||||
// as used elsewhere where we are concerned with decay in prediction
|
// as used elsewhere where we are concerned with decay in prediction
|
||||||
@ -2160,7 +2168,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
// Monitor for static sections.
|
// Monitor for static sections.
|
||||||
zero_motion_accumulator =
|
zero_motion_accumulator =
|
||||||
MIN(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.
|
// Not all frames in the group are necessarily used in calculating boost.
|
||||||
if ((i <= rc->max_gf_interval) ||
|
if ((i <= rc->max_gf_interval) ||
|
||||||
@ -2171,7 +2179,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
// How fast is prediction quality decaying.
|
// How fast is prediction quality decaying.
|
||||||
if (!detect_flash(twopass, 0)) {
|
if (!detect_flash(twopass, 0)) {
|
||||||
const double loop_decay_rate =
|
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 *= loop_decay_rate;
|
||||||
decay_accumulator = MAX(decay_accumulator, MIN_DECAY_FACTOR);
|
decay_accumulator = MAX(decay_accumulator, MIN_DECAY_FACTOR);
|
||||||
av_decay_accumulator += decay_accumulator;
|
av_decay_accumulator += decay_accumulator;
|
||||||
@ -2295,6 +2303,24 @@ void configure_buffer_updates(VP9_COMP *cpi) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
@ -2329,11 +2355,6 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
|||||||
target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
|
target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
|
||||||
rc->base_frame_target = 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;
|
cm->frame_type = INTER_FRAME;
|
||||||
|
|
||||||
if (lc != NULL) {
|
if (lc != NULL) {
|
||||||
@ -2347,6 +2368,13 @@ void vp9_rc_get_second_pass_params(VP9_COMP *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);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2377,8 +2405,7 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
|||||||
this_frame_copy = this_frame;
|
this_frame_copy = this_frame;
|
||||||
|
|
||||||
// Keyframe and section processing.
|
// Keyframe and section processing.
|
||||||
if (rc->frames_to_key == 0 ||
|
if (rc->frames_to_key == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY)) {
|
||||||
(cpi->frame_flags & FRAMEFLAGS_KEY)) {
|
|
||||||
// Define next KF group and assign bits to it.
|
// Define next KF group and assign bits to it.
|
||||||
find_next_key_frame(cpi, &this_frame_copy);
|
find_next_key_frame(cpi, &this_frame_copy);
|
||||||
} else {
|
} else {
|
||||||
@ -2431,6 +2458,13 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
|||||||
|
|
||||||
configure_buffer_updates(cpi);
|
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];
|
target_rate = gf_group->bit_allocation[gf_group->index];
|
||||||
if (cpi->common.frame_type == KEY_FRAME)
|
if (cpi->common.frame_type == KEY_FRAME)
|
||||||
target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate);
|
target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate);
|
||||||
@ -2439,12 +2473,6 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
|||||||
|
|
||||||
rc->base_frame_target = 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);
|
|
||||||
|
|
||||||
// Update the total stats remaining structure.
|
// Update the total stats remaining structure.
|
||||||
subtract_stats(&twopass->total_left_stats, &this_frame);
|
subtract_stats(&twopass->total_left_stats, &this_frame);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user