Commit 6b3f4bc7 authored by Marco's avatar Marco

vp9: 1 pass CBR: cleanup to cyclic refresh.

Code cleanup: merged two functions that were doing postencode
update for cylic refresh, remove some unused code and fix comments.

No change in behavior.

Change-Id: I9be0d7e346d34dec29bf4e5bb380a7bf81c8480a
parent 41fac447
......@@ -240,24 +240,64 @@ void vp9_cyclic_refresh_update_sb_postencode(VP9_COMP *const cpi,
}
}
// Update the actual number of blocks that were applied the segment delta q.
// From the just encoded frame: update the actual number of blocks that were
// applied the segment delta q, and the amount of low motion in the frame.
// Also check conditions for forcing golden update, or preventing golden
// update if the period is up.
void vp9_cyclic_refresh_postencode(VP9_COMP *const cpi) {
VP9_COMMON *const cm = &cpi->common;
MODE_INFO **mi = cm->mi_grid_visible;
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
RATE_CONTROL *const rc = &cpi->rc;
unsigned char *const seg_map = cpi->segmentation_map;
double fraction_low = 0.0;
int force_gf_refresh = 0;
int low_content_frame = 0;
int mi_row, mi_col;
cr->actual_num_seg1_blocks = 0;
cr->actual_num_seg2_blocks = 0;
for (mi_row = 0; mi_row < cm->mi_rows; mi_row++)
for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) {
for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
if (cyclic_refresh_segment_id(seg_map[mi_row * cm->mi_cols + mi_col]) ==
CR_SEGMENT_ID_BOOST1)
int map_index = mi_row * cm->mi_cols + mi_col;
if (cyclic_refresh_segment_id(seg_map[map_index]) == CR_SEGMENT_ID_BOOST1)
cr->actual_num_seg1_blocks++;
else if (cyclic_refresh_segment_id(
seg_map[mi_row * cm->mi_cols + mi_col]) ==
else if (cyclic_refresh_segment_id(seg_map[map_index]) ==
CR_SEGMENT_ID_BOOST2)
cr->actual_num_seg2_blocks++;
// Accumulate low_content_frame.
if (cr->map[map_index] < 1) low_content_frame++;
mi++;
}
mi += 8;
}
// Check for golden frame update: only for non-SVC and non-golden boost.
if (!cpi->use_svc && cpi->ext_refresh_frame_flags_pending == 0 &&
!cpi->oxcf.gf_cbr_boost_pct) {
// Force this frame as a golden update frame if this frame changes the
// resolution (resize_pending != 0).
// TODO(marpan): check on forcing golden update if the background has very
// high motion in current frame.
if (cpi->resize_pending != 0) {
vp9_cyclic_refresh_set_golden_update(cpi);
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
if (rc->frames_till_gf_update_due > rc->frames_to_key)
rc->frames_till_gf_update_due = rc->frames_to_key;
cpi->refresh_golden_frame = 1;
force_gf_refresh = 1;
}
// Update average of low content/motion in the frame.
fraction_low = (double)low_content_frame / (cm->mi_rows * cm->mi_cols);
cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4;
if (!force_gf_refresh && 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;
}
}
}
// Set golden frame update interval, for non-svc 1 pass CBR mode.
......@@ -274,72 +314,6 @@ void vp9_cyclic_refresh_set_golden_update(VP9_COMP *const cpi) {
if (cpi->oxcf.rc_mode == VPX_VBR) rc->baseline_gf_interval = 20;
}
// Update some encoding stats (from the just encoded frame). If this frame's
// background has high motion, refresh the golden frame. Otherwise, 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;
MODE_INFO **mi = cm->mi_grid_visible;
RATE_CONTROL *const rc = &cpi->rc;
const int rows = cm->mi_rows, cols = cm->mi_cols;
int cnt1 = 0, cnt2 = 0;
int force_gf_refresh = 0;
int flag_force_gf_high_motion = 0;
for (mi_row = 0; mi_row < rows; mi_row++) {
for (mi_col = 0; mi_col < cols; mi_col++) {
if (flag_force_gf_high_motion == 1) {
int16_t abs_mvr = mi[0]->mv[0].as_mv.row >= 0
? mi[0]->mv[0].as_mv.row
: -1 * mi[0]->mv[0].as_mv.row;
int16_t abs_mvc = mi[0]->mv[0].as_mv.col >= 0
? mi[0]->mv[0].as_mv.col
: -1 * mi[0]->mv[0].as_mv.col;
// Calculate the motion of the background.
if (abs_mvr <= 16 && abs_mvc <= 16) {
cnt1++;
if (abs_mvr == 0 && abs_mvc == 0) cnt2++;
}
}
mi++;
// Accumulate low_content_frame.
if (cr->map[mi_row * cols + mi_col] < 1) low_content_frame++;
}
mi += 8;
}
// For video conference clips, if the background has high motion in current
// frame because of the camera movement, set this frame as the golden frame.
// Use 70% and 5% as the thresholds for golden frame refreshing.
// Also, force this frame as a golden update frame if this frame will change
// the resolution (resize_pending != 0).
if (cpi->resize_pending != 0 ||
(cnt1 * 100 > (70 * rows * cols) && cnt2 * 20 < cnt1)) {
vp9_cyclic_refresh_set_golden_update(cpi);
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
if (rc->frames_till_gf_update_due > rc->frames_to_key)
rc->frames_till_gf_update_due = rc->frames_to_key;
cpi->refresh_golden_frame = 1;
force_gf_refresh = 1;
}
fraction_low = (double)low_content_frame / (rows * cols);
// Update average.
cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4;
if (!force_gf_refresh && 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,
// 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
......@@ -406,7 +380,7 @@ static void cyclic_refresh_update_map(VP9_COMP *const cpi) {
const int bl_index2 = bl_index + y * cm->mi_cols + x;
// If the block is as a candidate for clean up then mark it
// for possible boost/refresh (segment 1). The segment id may get
// reset to 0 later if block gets coded anything other than ZEROMV.
// reset to 0 later depending on the coding mode.
if (cr->map[bl_index2] == 0) {
count_tot++;
if (cr->last_coded_q_map[bl_index2] > qindex_thresh ||
......
......@@ -105,15 +105,15 @@ void vp9_cyclic_refresh_update_sb_postencode(struct VP9_COMP *const cpi,
// refresh sb_index, and target number of blocks to be refreshed.
void vp9_cyclic_refresh_update__map(struct VP9_COMP *const cpi);
// Update the actual number of blocks that were applied the segment delta q.
// From the just encoded frame: update the actual number of blocks that were
// applied the segment delta q, and the amount of low motion in the frame.
// Also check conditions for forcing golden update, or preventing golden
// update if the period is up.
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 *const 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.
void vp9_cyclic_refresh_update_parameters(struct VP9_COMP *const cpi);
......
......@@ -3261,13 +3261,10 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
}
}
// 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->ext_refresh_frame_flags_pending == 0 &&
(cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR &&
!cpi->oxcf.gf_cbr_boost_pct))
vp9_cyclic_refresh_check_golden_update(cpi);
// Update some stats from cyclic refresh, and check for golden frame update.
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled &&
cm->frame_type != KEY_FRAME)
vp9_cyclic_refresh_postencode(cpi);
// Update the skip mb flag probabilities based on the distribution
// seen in the last encoder iteration.
......
......@@ -1363,10 +1363,6 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
RATE_CONTROL *const rc = &cpi->rc;
const int qindex = cm->base_qindex;
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
vp9_cyclic_refresh_postencode(cpi);
}
// Update rate control heuristics
rc->projected_frame_size = (int)(bytes_used << 3);
......
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