| Index: source/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c
|
| diff --git a/source/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c b/source/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c
|
| index 154068052c7c3db569aa01a29928fd44813c3a8c..958d52acfd5b2e1e38db9803ce1ee212a9559859 100644
|
| --- a/source/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c
|
| +++ b/source/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c
|
| @@ -47,6 +47,7 @@ struct CYCLIC_REFRESH {
|
| int16_t motion_thresh;
|
| // Rate target ratio to set q delta.
|
| double rate_ratio_qdelta;
|
| + double low_content_avg;
|
| };
|
|
|
| CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) {
|
| @@ -76,10 +77,10 @@ static int apply_cyclic_refresh_bitrate(const VP9_COMMON *cm,
|
| // with number of seg blocks, so compare available bits to number of blocks.
|
| // Average bits available per frame = avg_frame_bandwidth
|
| // Number of (8x8) blocks in frame = mi_rows * mi_cols;
|
| - const float factor = 0.5;
|
| + const float factor = 0.25;
|
| const int number_blocks = cm->mi_rows * cm->mi_cols;
|
| // The condition below corresponds to turning off at target bitrates:
|
| - // ~24kbps for CIF, 72kbps for VGA (at 30fps).
|
| + // (at 30fps), ~12kbps for CIF, 36kbps for VGA, 100kps for HD/720p.
|
| // Also turn off at very small frame sizes, to avoid too large fraction of
|
| // superblocks to be refreshed per frame. Threshold below is less than QCIF.
|
| if (rc->avg_frame_bandwidth < factor * number_blocks ||
|
| @@ -213,14 +214,14 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi,
|
|
|
| // If this block is labeled for refresh, check if we should reset the
|
| // segment_id.
|
| - if (mbmi->segment_id != CR_SEGMENT_ID_BASE)
|
| + if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
|
| mbmi->segment_id = refresh_this_block;
|
|
|
| // Update the cyclic refresh map, to be used for setting segmentation map
|
| // for the next frame. If the block will be refreshed this frame, mark it
|
| // as clean. The magnitude of the -ve influences how long before we consider
|
| // it for refresh again.
|
| - if (mbmi->segment_id != CR_SEGMENT_ID_BASE) {
|
| + if (cyclic_refresh_segment_id_boosted(mbmi->segment_id)) {
|
| new_map_value = -cr->time_for_refresh;
|
| } else if (refresh_this_block) {
|
| // Else if it is accepted as candidate for refresh, and has not already
|
| @@ -244,16 +245,58 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi,
|
| }
|
|
|
| // 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;
|
| CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
| unsigned char *const seg_map = cpi->segmentation_map;
|
| int mi_row, mi_col;
|
| cr->actual_num_seg_blocks = 0;
|
| for (mi_row = 0; mi_row < cm->mi_rows; mi_row++)
|
| - for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
|
| - if (seg_map[mi_row * cm->mi_cols + mi_col] != CR_SEGMENT_ID_BASE)
|
| - cr->actual_num_seg_blocks++;
|
| + for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
|
| + if (cyclic_refresh_segment_id_boosted(
|
| + seg_map[mi_row * cm->mi_cols + mi_col]))
|
| + cr->actual_num_seg_blocks++;
|
| + }
|
| +}
|
| +
|
| +// 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;
|
| }
|
| }
|
|
|
| @@ -347,6 +390,8 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
|
| CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
| struct segmentation *const seg = &cm->seg;
|
| 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.
|
| if (!apply_cyclic_refresh ||
|
| (cm->frame_type == KEY_FRAME) ||
|
|
|