Modify update golden reference update under aq-mode=3 mode.
For non-SVC 1 pass CBR: make the GF update interval a multiple of the cyclic refresh period, and use encoding stats to prevent GF update at certain times. Change-Id: I4c44cacc2f70f1d27391a47644837e1eaa065017
This commit is contained in:
Родитель
78df712216
Коммит
fb31aa09e2
|
@ -47,6 +47,7 @@ struct CYCLIC_REFRESH {
|
||||||
int16_t motion_thresh;
|
int16_t motion_thresh;
|
||||||
// Rate target ratio to set q delta.
|
// Rate target ratio to set q delta.
|
||||||
double rate_ratio_qdelta;
|
double rate_ratio_qdelta;
|
||||||
|
double low_content_avg;
|
||||||
};
|
};
|
||||||
|
|
||||||
CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) {
|
CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) {
|
||||||
|
@ -244,7 +245,7 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the actual number of blocks that were applied the segment delta q.
|
// Update the actual number of blocks that were applied the segment delta q.
|
||||||
void vp9_cyclic_refresh_update_actual_count(struct VP9_COMP *const cpi) {
|
void vp9_cyclic_refresh_postencode(VP9_COMP *const cpi) {
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||||
unsigned char *const seg_map = cpi->segmentation_map;
|
unsigned char *const seg_map = cpi->segmentation_map;
|
||||||
|
@ -257,6 +258,47 @@ void vp9_cyclic_refresh_update_actual_count(struct VP9_COMP *const cpi) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set golden frame update interval, for non-svc 1 pass CBR mode.
|
||||||
|
void vp9_cyclic_refresh_set_golden_update(VP9_COMP *const cpi) {
|
||||||
|
RATE_CONTROL *const rc = &cpi->rc;
|
||||||
|
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||||
|
// Set minimum gf_interval for GF update to a multiple (== 2) of refresh
|
||||||
|
// period. Depending on past encoding stats, GF flag may be reset and update
|
||||||
|
// may not occur until next baseline_gf_interval.
|
||||||
|
if (cr->percent_refresh > 0)
|
||||||
|
rc->baseline_gf_interval = 2 * (100 / cr->percent_refresh);
|
||||||
|
else
|
||||||
|
rc->baseline_gf_interval = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update some encoding stats (from the just encoded frame), and if the golden
|
||||||
|
// reference is to be updated check if we should NOT update the golden ref.
|
||||||
|
void vp9_cyclic_refresh_check_golden_update(VP9_COMP *const cpi) {
|
||||||
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
|
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||||
|
int mi_row, mi_col;
|
||||||
|
double fraction_low = 0.0;
|
||||||
|
int low_content_frame = 0;
|
||||||
|
for (mi_row = 0; mi_row < cm->mi_rows; mi_row++)
|
||||||
|
for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
|
||||||
|
if (cr->map[mi_row * cm->mi_cols + mi_col] < 1)
|
||||||
|
low_content_frame++;
|
||||||
|
}
|
||||||
|
fraction_low =
|
||||||
|
(double)low_content_frame / (cm->mi_rows * cm->mi_cols);
|
||||||
|
// Update average.
|
||||||
|
cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4;
|
||||||
|
if (cpi->refresh_golden_frame == 1) {
|
||||||
|
// Don't update golden reference if the amount of low_content for the
|
||||||
|
// current encoded frame is small, or if the recursive average of the
|
||||||
|
// low_content over the update interval window falls below threshold.
|
||||||
|
if (fraction_low < 0.8 || cr->low_content_avg < 0.7)
|
||||||
|
cpi->refresh_golden_frame = 0;
|
||||||
|
// Reset for next internal.
|
||||||
|
cr->low_content_avg = fraction_low;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the segmentation map, and related quantities: cyclic refresh map,
|
// Update the segmentation map, and related quantities: cyclic refresh map,
|
||||||
// refresh sb_index, and target number of blocks to be refreshed.
|
// refresh sb_index, and target number of blocks to be refreshed.
|
||||||
// The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to
|
// The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to
|
||||||
|
@ -347,6 +389,8 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
|
||||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||||
struct segmentation *const seg = &cm->seg;
|
struct segmentation *const seg = &cm->seg;
|
||||||
const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc);
|
const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc);
|
||||||
|
if (cm->current_video_frame == 0)
|
||||||
|
cr->low_content_avg = 0.0;
|
||||||
// Don't apply refresh on key frame or enhancement layer frames.
|
// Don't apply refresh on key frame or enhancement layer frames.
|
||||||
if (!apply_cyclic_refresh ||
|
if (!apply_cyclic_refresh ||
|
||||||
(cm->frame_type == KEY_FRAME) ||
|
(cm->frame_type == KEY_FRAME) ||
|
||||||
|
|
|
@ -62,7 +62,13 @@ void vp9_cyclic_refresh_update_segment(struct VP9_COMP *const cpi,
|
||||||
void vp9_cyclic_refresh_update__map(struct VP9_COMP *const cpi);
|
void vp9_cyclic_refresh_update__map(struct VP9_COMP *const cpi);
|
||||||
|
|
||||||
// Update the actual number of blocks that were applied the segment delta q.
|
// Update the actual number of blocks that were applied the segment delta q.
|
||||||
void vp9_cyclic_refresh_update_actual_count(struct VP9_COMP *const cpi);
|
void vp9_cyclic_refresh_postencode(struct VP9_COMP *const cpi);
|
||||||
|
|
||||||
|
// Set golden frame update interval, for non-svc 1 pass CBR mode.
|
||||||
|
void vp9_cyclic_refresh_set_golden_update(struct VP9_COMP *cpi);
|
||||||
|
|
||||||
|
// Check if we should not update golden reference, based on past refresh stats.
|
||||||
|
void vp9_cyclic_refresh_check_golden_update(struct VP9_COMP *const cpi);
|
||||||
|
|
||||||
// Set/update global/frame level refresh parameters.
|
// Set/update global/frame level refresh parameters.
|
||||||
void vp9_cyclic_refresh_update_parameters(struct VP9_COMP *const cpi);
|
void vp9_cyclic_refresh_update_parameters(struct VP9_COMP *const cpi);
|
||||||
|
|
|
@ -2843,6 +2843,14 @@ static void encode_without_recode_loop(VP9_COMP *cpi) {
|
||||||
// transform / motion compensation build reconstruction frame
|
// transform / motion compensation build reconstruction frame
|
||||||
vp9_encode_frame(cpi);
|
vp9_encode_frame(cpi);
|
||||||
|
|
||||||
|
// Update some stats from cyclic refresh, and check if we should not update
|
||||||
|
// golden reference, for non-SVC 1 pass CBR.
|
||||||
|
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ &&
|
||||||
|
cm->frame_type != KEY_FRAME &&
|
||||||
|
!cpi->use_svc &&
|
||||||
|
(cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR))
|
||||||
|
vp9_cyclic_refresh_check_golden_update(cpi);
|
||||||
|
|
||||||
// Update the skip mb flag probabilities based on the distribution
|
// Update the skip mb flag probabilities based on the distribution
|
||||||
// seen in the last encoder iteration.
|
// seen in the last encoder iteration.
|
||||||
// update_base_skip_probs(cpi);
|
// update_base_skip_probs(cpi);
|
||||||
|
@ -3220,7 +3228,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
||||||
TX_SIZE t;
|
TX_SIZE t;
|
||||||
|
|
||||||
set_ext_overrides(cpi);
|
set_ext_overrides(cpi);
|
||||||
|
|
||||||
vp9_clear_system_state();
|
vp9_clear_system_state();
|
||||||
|
|
||||||
// Set the arf sign bias for this frame.
|
// Set the arf sign bias for this frame.
|
||||||
|
|
|
@ -1229,7 +1229,7 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
|
||||||
const int qindex = cm->base_qindex;
|
const int qindex = cm->base_qindex;
|
||||||
|
|
||||||
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
|
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
|
||||||
vp9_cyclic_refresh_update_actual_count(cpi);
|
vp9_cyclic_refresh_postencode(cpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update rate control heuristics
|
// Update rate control heuristics
|
||||||
|
@ -1535,7 +1535,10 @@ void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) {
|
||||||
cm->frame_type = INTER_FRAME;
|
cm->frame_type = INTER_FRAME;
|
||||||
}
|
}
|
||||||
if (rc->frames_till_gf_update_due == 0) {
|
if (rc->frames_till_gf_update_due == 0) {
|
||||||
rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
|
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
|
||||||
|
vp9_cyclic_refresh_set_golden_update(cpi);
|
||||||
|
else
|
||||||
|
rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
|
||||||
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
|
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
|
||||||
// NOTE: frames_till_gf_update_due must be <= frames_to_key.
|
// NOTE: frames_till_gf_update_due must be <= frames_to_key.
|
||||||
if (rc->frames_till_gf_update_due > rc->frames_to_key)
|
if (rc->frames_till_gf_update_due > rc->frames_to_key)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче