Commit 03e8f133 authored by Marco's avatar Marco

vp9: Modification to adapt the ARF usage for 1 pass vbr

Add stats for past ARF usage, and use it to disable
ARF usage based on some conditions.

Overall improvement on ytlive set, reduces the regression
on the problem clips for this feature.

Only affects when sf->use_altref_onepass is enabled
(currently off by default).

Change-Id: I66267f227ea132dc86acb730e9882f85bead2cdb
parent d203a91a
......@@ -189,6 +189,9 @@ struct macroblock {
// 32x32, 9~24 for 16x16.
uint8_t variance_low[25];
uint8_t arf_frame_usage;
uint8_t lastgolden_frame_usage;
void (*fwd_txfm4x4)(const int16_t *input, tran_low_t *output, int stride);
void (*inv_txfm_add)(const tran_low_t *input, uint8_t *dest, int stride,
int eob);
......
......@@ -4163,6 +4163,8 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, ThreadData *td,
x->sb_mvcol_part = 0;
x->sb_mvrow_part = 0;
x->sb_pickmode_part = 0;
x->arf_frame_usage = 0;
x->lastgolden_frame_usage = 0;
if (seg->enabled) {
const uint8_t *const map =
......@@ -4241,6 +4243,17 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, ThreadData *td,
default: assert(0); break;
}
// Update ref_frame usage for inter frame if this group is ARF group.
if (!cpi->rc.is_src_frame_alt_ref && !cpi->refresh_golden_frame &&
!cpi->refresh_alt_ref_frame && cpi->rc.alt_ref_gf_group &&
cpi->sf.use_altref_onepass) {
int sboffset = ((cm->mi_cols + 7) >> 3) * (mi_row >> 3) + (mi_col >> 3);
if (cpi->count_arf_frame_usage != NULL)
cpi->count_arf_frame_usage[sboffset] = x->arf_frame_usage;
if (cpi->count_lastgolden_frame_usage != NULL)
cpi->count_lastgolden_frame_usage[sboffset] = x->lastgolden_frame_usage;
}
(*(cpi->row_mt_sync_write_ptr))(&tile_data->row_mt_sync, sb_row,
sb_col_in_tile, num_sb_cols);
}
......
......@@ -798,6 +798,11 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
vpx_free(cpi->content_state_sb_fd);
cpi->content_state_sb_fd = NULL;
vpx_free(cpi->count_arf_frame_usage);
cpi->count_arf_frame_usage = NULL;
vpx_free(cpi->count_lastgolden_frame_usage);
cpi->count_lastgolden_frame_usage = NULL;
vp9_cyclic_refresh_free(cpi->cyclic_refresh);
cpi->cyclic_refresh = NULL;
......
......@@ -717,6 +717,9 @@ typedef struct VP9_COMP {
int compute_source_sad_onepass;
LevelConstraint level_constraint;
uint8_t *count_arf_frame_usage;
uint8_t *count_lastgolden_frame_usage;
} VP9_COMP;
void vp9_initialize_enc(void);
......
......@@ -2288,6 +2288,11 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
}
#endif
if (best_ref_frame == ALTREF_FRAME)
x->arf_frame_usage++;
else if (best_ref_frame != INTRA_FRAME)
x->lastgolden_frame_usage++;
if (cpi->sf.adaptive_rd_thresh) {
THR_MODES best_mode_idx = mode_idx[best_ref_frame][mode_offset(mi->mode)];
......
......@@ -591,12 +591,6 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
q = clamp(q, VPXMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame),
VPXMAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame));
}
if (cpi->sf.use_altref_onepass && cpi->oxcf.enable_auto_arf &&
cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_VBR &&
cpi->oxcf.lag_in_frames > 0 && cpi->rc.is_src_frame_alt_ref &&
!cpi->rc.alt_ref_gf_group) {
q = VPXMIN(q, (q + cpi->rc.last_boosted_qindex) >> 1);
}
return q;
}
......@@ -1337,6 +1331,28 @@ static void update_golden_frame_stats(VP9_COMP *cpi) {
}
}
static void update_altref_usage(VP9_COMP *const cpi) {
VP9_COMMON *const cm = &cpi->common;
int sum_ref_frame_usage = 0;
int arf_frame_usage = 0;
int mi_row, mi_col;
if (cpi->rc.alt_ref_gf_group && !cpi->rc.is_src_frame_alt_ref &&
!cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame)
for (mi_row = 0; mi_row < cm->mi_rows; mi_row += 8) {
for (mi_col = 0; mi_col < cm->mi_cols; mi_col += 8) {
int sboffset = ((cm->mi_cols + 7) >> 3) * (mi_row >> 3) + (mi_col >> 3);
sum_ref_frame_usage += cpi->count_arf_frame_usage[sboffset] +
cpi->count_lastgolden_frame_usage[sboffset];
arf_frame_usage += cpi->count_arf_frame_usage[sboffset];
}
}
if (sum_ref_frame_usage > 0) {
double altref_count = 100.0 * arf_frame_usage / sum_ref_frame_usage;
cpi->rc.perc_arf_usage =
0.75 * cpi->rc.perc_arf_usage + 0.25 * altref_count;
}
}
static void compute_frame_low_motion(VP9_COMP *const cpi) {
VP9_COMMON *const cm = &cpi->common;
int mi_row, mi_col;
......@@ -1460,7 +1476,10 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
}
if (oxcf->pass == 0) {
if (cm->frame_type != KEY_FRAME) compute_frame_low_motion(cpi);
if (cm->frame_type != KEY_FRAME) {
compute_frame_low_motion(cpi);
if (cpi->sf.use_altref_onepass) update_altref_usage(cpi);
}
}
if (cm->frame_type != KEY_FRAME) rc->reset_high_source_sad = 0;
}
......@@ -2202,9 +2221,15 @@ static void adjust_gf_boost_lag_one_pass_vbr(VP9_COMP *cpi,
rc->gfu_boost = DEFAULT_GF_BOOST >> 2;
}
if (cpi->sf.use_altref_onepass && cpi->oxcf.enable_auto_arf) {
// Don't use alt-ref if there is a scene cut within the group,
// or content is not low.
if ((rc->high_source_sad_lagindex > 0 &&
// Flag to disable usage of ARF based on past usage, only allow this
// disabling if current frame/group does not start with key frame or
// scene cut. Note perc_arf_usage is only computed for speed >= 5.
int arf_usage_low =
(cm->frame_type != KEY_FRAME && !rc->high_source_sad &&
cpi->rc.perc_arf_usage < 15 && cpi->oxcf.speed >= 5);
// Don't use alt-ref for this group under certain conditions.
if (arf_usage_low ||
(rc->high_source_sad_lagindex > 0 &&
rc->high_source_sad_lagindex <= rc->frames_till_gf_update_due) ||
(avg_source_sad_lag > 3 * sad_thresh1 >> 3)) {
rc->source_alt_ref_pending = 0;
......
......@@ -170,6 +170,7 @@ typedef struct {
int af_ratio_onepass_vbr;
int force_qpmin;
int reset_high_source_sad;
double perc_arf_usage;
} RATE_CONTROL;
struct VP9_COMP;
......
......@@ -525,9 +525,13 @@ static void set_rt_speed_feature_framesize_independent(
if (speed >= 6) {
sf->partition_search_type = VAR_BASED_PARTITION;
if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0 &&
cpi->rc.is_src_frame_alt_ref && !is_keyframe) {
sf->partition_search_type = FIXED_PARTITION;
sf->always_this_block_size = BLOCK_64X64;
!is_keyframe) {
if (cpi->rc.is_src_frame_alt_ref) {
sf->partition_search_type = FIXED_PARTITION;
sf->always_this_block_size = BLOCK_64X64;
} else if (sf->use_altref_onepass && cpi->refresh_alt_ref_frame) {
sf->partition_search_type = REFERENCE_PARTITION;
}
}
// Turn on this to use non-RD key frame coding mode.
sf->use_nonrd_pick_mode = 1;
......@@ -632,6 +636,16 @@ static void set_rt_speed_feature_framesize_independent(
sf->limit_newmv_early_exit = 0;
sf->use_simple_block_yrd = 1;
}
if (sf->use_altref_onepass) {
if (cpi->count_arf_frame_usage == NULL)
cpi->count_arf_frame_usage =
(uint8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1),
sizeof(*cpi->count_arf_frame_usage));
if (cpi->count_lastgolden_frame_usage == NULL)
cpi->count_lastgolden_frame_usage =
(uint8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1),
sizeof(*cpi->count_lastgolden_frame_usage));
}
}
void vp9_set_speed_features_framesize_dependent(VP9_COMP *cpi) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment