ref: 6b3f4bc794bc5bc58a583b3925bd2e05f4eec4a1
parent: 41fac447073466a1186f28f3cff21fbc528592f5
author: Marco <[email protected]>
date: Wed Mar 29 12:57:53 EDT 2017
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
--- a/vp9/encoder/vp9_aq_cyclicrefresh.c
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.c
@@ -240,24 +240,64 @@
}
}
-// 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 @@
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 @@
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 ||
--- a/vp9/encoder/vp9_aq_cyclicrefresh.h
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.h
@@ -105,14 +105,14 @@
// 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);
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3261,13 +3261,10 @@
}
}
- // 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.
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1363,10 +1363,6 @@
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);