]> granicus.if.org Git - libvpx/blob - vp9/encoder/vp9_aq_cyclicrefresh.c
vp9_cyclic_refresh_alloc: correct cleanup on error
[libvpx] / vp9 / encoder / vp9_aq_cyclicrefresh.c
1 /*
2  *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include <limits.h>
12 #include <math.h>
13
14 #include "vpx_dsp/vpx_dsp_common.h"
15 #include "vpx_ports/system_state.h"
16
17 #include "vp9/encoder/vp9_aq_cyclicrefresh.h"
18
19 #include "vp9/common/vp9_seg_common.h"
20
21 #include "vp9/encoder/vp9_ratectrl.h"
22 #include "vp9/encoder/vp9_segmentation.h"
23
24 CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) {
25   size_t last_coded_q_map_size;
26   size_t consec_zero_mv_size;
27   CYCLIC_REFRESH *const cr = vpx_calloc(1, sizeof(*cr));
28   if (cr == NULL)
29     return NULL;
30
31   cr->map = vpx_calloc(mi_rows * mi_cols, sizeof(*cr->map));
32   if (cr->map == NULL) {
33     vp9_cyclic_refresh_free(cr);
34     return NULL;
35   }
36   last_coded_q_map_size = mi_rows * mi_cols * sizeof(*cr->last_coded_q_map);
37   cr->last_coded_q_map = vpx_malloc(last_coded_q_map_size);
38   if (cr->last_coded_q_map == NULL) {
39     vp9_cyclic_refresh_free(cr);
40     return NULL;
41   }
42   assert(MAXQ <= 255);
43   memset(cr->last_coded_q_map, MAXQ, last_coded_q_map_size);
44
45   consec_zero_mv_size = mi_rows * mi_cols * sizeof(*cr->consec_zero_mv);
46   cr->consec_zero_mv = vpx_malloc(consec_zero_mv_size);
47   if (cr->consec_zero_mv == NULL) {
48     vp9_cyclic_refresh_free(cr);
49     return NULL;
50   }
51   memset(cr->consec_zero_mv, 0, consec_zero_mv_size);
52   return cr;
53 }
54
55 void vp9_cyclic_refresh_free(CYCLIC_REFRESH *cr) {
56   vpx_free(cr->map);
57   vpx_free(cr->last_coded_q_map);
58   vpx_free(cr->consec_zero_mv);
59   vpx_free(cr);
60 }
61
62 // Check if this coding block, of size bsize, should be considered for refresh
63 // (lower-qp coding). Decision can be based on various factors, such as
64 // size of the coding block (i.e., below min_block size rejected), coding
65 // mode, and rate/distortion.
66 static int candidate_refresh_aq(const CYCLIC_REFRESH *cr,
67                                 const MODE_INFO *mi,
68                                 int64_t rate,
69                                 int64_t dist,
70                                 int bsize) {
71   MV mv = mi->mv[0].as_mv;
72   // Reject the block for lower-qp coding if projected distortion
73   // is above the threshold, and any of the following is true:
74   // 1) mode uses large mv
75   // 2) mode is an intra-mode
76   // Otherwise accept for refresh.
77   if (dist > cr->thresh_dist_sb &&
78       (mv.row > cr->motion_thresh || mv.row < -cr->motion_thresh ||
79        mv.col > cr->motion_thresh || mv.col < -cr->motion_thresh ||
80        !is_inter_block(mi)))
81     return CR_SEGMENT_ID_BASE;
82   else  if (bsize >= BLOCK_16X16 &&
83             rate < cr->thresh_rate_sb &&
84             is_inter_block(mi) &&
85             mi->mv[0].as_int == 0 &&
86             cr->rate_boost_fac > 10)
87     // More aggressive delta-q for bigger blocks with zero motion.
88     return CR_SEGMENT_ID_BOOST2;
89   else
90     return CR_SEGMENT_ID_BOOST1;
91 }
92
93 // Compute delta-q for the segment.
94 static int compute_deltaq(const VP9_COMP *cpi, int q, double rate_factor) {
95   const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
96   const RATE_CONTROL *const rc = &cpi->rc;
97   int deltaq = vp9_compute_qdelta_by_rate(rc, cpi->common.frame_type,
98                                           q, rate_factor,
99                                           cpi->common.bit_depth);
100   if ((-deltaq) > cr->max_qdelta_perc * q / 100) {
101     deltaq = -cr->max_qdelta_perc * q / 100;
102   }
103   return deltaq;
104 }
105
106 // For the just encoded frame, estimate the bits, incorporating the delta-q
107 // from non-base segment. For now ignore effect of multiple segments
108 // (with different delta-q). Note this function is called in the postencode
109 // (called from rc_update_rate_correction_factors()).
110 int vp9_cyclic_refresh_estimate_bits_at_q(const VP9_COMP *cpi,
111                                           double correction_factor) {
112   const VP9_COMMON *const cm = &cpi->common;
113   const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
114   int estimated_bits;
115   int mbs = cm->MBs;
116   int num8x8bl = mbs << 2;
117   // Weight for non-base segments: use actual number of blocks refreshed in
118   // previous/just encoded frame. Note number of blocks here is in 8x8 units.
119   double weight_segment1 = (double)cr->actual_num_seg1_blocks / num8x8bl;
120   double weight_segment2 = (double)cr->actual_num_seg2_blocks / num8x8bl;
121   // Take segment weighted average for estimated bits.
122   estimated_bits = (int)((1.0 - weight_segment1 - weight_segment2) *
123       vp9_estimate_bits_at_q(cm->frame_type, cm->base_qindex, mbs,
124                              correction_factor, cm->bit_depth) +
125                              weight_segment1 *
126       vp9_estimate_bits_at_q(cm->frame_type,
127                              cm->base_qindex + cr->qindex_delta[1], mbs,
128                              correction_factor, cm->bit_depth) +
129                              weight_segment2 *
130       vp9_estimate_bits_at_q(cm->frame_type,
131                              cm->base_qindex + cr->qindex_delta[2], mbs,
132                              correction_factor, cm->bit_depth));
133   return estimated_bits;
134 }
135
136 // Prior to encoding the frame, estimate the bits per mb, for a given q = i and
137 // a corresponding delta-q (for segment 1). This function is called in the
138 // rc_regulate_q() to set the base qp index.
139 // Note: the segment map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or
140 // to 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock, prior to encoding.
141 int vp9_cyclic_refresh_rc_bits_per_mb(const VP9_COMP *cpi, int i,
142                                       double correction_factor) {
143   const VP9_COMMON *const cm = &cpi->common;
144   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
145   int bits_per_mb;
146   int num8x8bl = cm->MBs << 2;
147   // Weight for segment prior to encoding: take the average of the target
148   // number for the frame to be encoded and the actual from the previous frame.
149   int target_refresh = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100;
150   double weight_segment = (double)((target_refresh +
151       cr->actual_num_seg1_blocks + cr->actual_num_seg2_blocks) >> 1) /
152       num8x8bl;
153   // Compute delta-q corresponding to qindex i.
154   int deltaq = compute_deltaq(cpi, i, cr->rate_ratio_qdelta);
155   // Take segment weighted average for bits per mb.
156   bits_per_mb = (int)((1.0 - weight_segment) *
157       vp9_rc_bits_per_mb(cm->frame_type, i, correction_factor, cm->bit_depth) +
158       weight_segment *
159       vp9_rc_bits_per_mb(cm->frame_type, i + deltaq, correction_factor,
160                          cm->bit_depth));
161   return bits_per_mb;
162 }
163
164 // Prior to coding a given prediction block, of size bsize at (mi_row, mi_col),
165 // check if we should reset the segment_id, and update the cyclic_refresh map
166 // and segmentation map.
167 void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi,
168                                        MODE_INFO *const mi,
169                                        int mi_row, int mi_col,
170                                        BLOCK_SIZE bsize,
171                                        int64_t rate,
172                                        int64_t dist,
173                                        int skip,
174                                        struct macroblock_plane *const p) {
175   const VP9_COMMON *const cm = &cpi->common;
176   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
177   const int bw = num_8x8_blocks_wide_lookup[bsize];
178   const int bh = num_8x8_blocks_high_lookup[bsize];
179   const int xmis = VPXMIN(cm->mi_cols - mi_col, bw);
180   const int ymis = VPXMIN(cm->mi_rows - mi_row, bh);
181   const int block_index = mi_row * cm->mi_cols + mi_col;
182   int refresh_this_block = candidate_refresh_aq(cr, mi, rate, dist, bsize);
183   // Default is to not update the refresh map.
184   int new_map_value = cr->map[block_index];
185   int x = 0; int y = 0;
186
187   int is_skin = 0;
188   if (refresh_this_block == 0 &&
189       bsize <= BLOCK_16X16 &&
190       cpi->use_skin_detection) {
191     is_skin = vp9_compute_skin_block(p[0].src.buf,
192                                      p[1].src.buf,
193                                      p[2].src.buf,
194                                      p[0].src.stride,
195                                      p[1].src.stride,
196                                      bsize);
197     if (is_skin)
198       refresh_this_block = 1;
199   }
200
201   // If this block is labeled for refresh, check if we should reset the
202   // segment_id.
203   if (cyclic_refresh_segment_id_boosted(mi->segment_id)) {
204     mi->segment_id = refresh_this_block;
205     // Reset segment_id if it will be skipped.
206     if (skip)
207       mi->segment_id = CR_SEGMENT_ID_BASE;
208   }
209
210   // Update the cyclic refresh map, to be used for setting segmentation map
211   // for the next frame. If the block  will be refreshed this frame, mark it
212   // as clean. The magnitude of the -ve influences how long before we consider
213   // it for refresh again.
214   if (cyclic_refresh_segment_id_boosted(mi->segment_id)) {
215     new_map_value = -cr->time_for_refresh;
216   } else if (refresh_this_block) {
217     // Else if it is accepted as candidate for refresh, and has not already
218     // been refreshed (marked as 1) then mark it as a candidate for cleanup
219     // for future time (marked as 0), otherwise don't update it.
220     if (cr->map[block_index] == 1)
221       new_map_value = 0;
222   } else {
223     // Leave it marked as block that is not candidate for refresh.
224     new_map_value = 1;
225   }
226
227   // Update entries in the cyclic refresh map with new_map_value, and
228   // copy mbmi->segment_id into global segmentation map.
229   for (y = 0; y < ymis; y++)
230     for (x = 0; x < xmis; x++) {
231       int map_offset = block_index + y * cm->mi_cols + x;
232       cr->map[map_offset] = new_map_value;
233       cpi->segmentation_map[map_offset] = mi->segment_id;
234     }
235 }
236
237 void vp9_cyclic_refresh_update_sb_postencode(VP9_COMP *const cpi,
238                                              const MODE_INFO *const mi,
239                                              int mi_row, int mi_col,
240                                              BLOCK_SIZE bsize) {
241   const VP9_COMMON *const cm = &cpi->common;
242   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
243   MV mv = mi->mv[0].as_mv;
244   const int bw = num_8x8_blocks_wide_lookup[bsize];
245   const int bh = num_8x8_blocks_high_lookup[bsize];
246   const int xmis = VPXMIN(cm->mi_cols - mi_col, bw);
247   const int ymis = VPXMIN(cm->mi_rows - mi_row, bh);
248   const int block_index = mi_row * cm->mi_cols + mi_col;
249   int x, y;
250   for (y = 0; y < ymis; y++)
251     for (x = 0; x < xmis; x++) {
252       int map_offset = block_index + y * cm->mi_cols + x;
253       // Inter skip blocks were clearly not coded at the current qindex, so
254       // don't update the map for them. For cases where motion is non-zero or
255       // the reference frame isn't the previous frame, the previous value in
256       // the map for this spatial location is not entirely correct.
257       if ((!is_inter_block(mi) || !mi->skip) &&
258           mi->segment_id <= CR_SEGMENT_ID_BOOST2) {
259         cr->last_coded_q_map[map_offset] = clamp(
260             cm->base_qindex + cr->qindex_delta[mi->segment_id], 0, MAXQ);
261       } else if (is_inter_block(mi) && mi->skip &&
262                  mi->segment_id <= CR_SEGMENT_ID_BOOST2) {
263         cr->last_coded_q_map[map_offset] = VPXMIN(
264             clamp(cm->base_qindex + cr->qindex_delta[mi->segment_id],
265                   0, MAXQ),
266             cr->last_coded_q_map[map_offset]);
267       // Update the consecutive zero/low_mv count.
268       if (is_inter_block(mi) && (abs(mv.row) < 8 && abs(mv.col) < 8)) {
269         if (cr->consec_zero_mv[map_offset] < 255)
270           cr->consec_zero_mv[map_offset]++;
271       } else {
272         cr->consec_zero_mv[map_offset] = 0;
273       }
274     }
275   }
276 }
277
278 // Update the actual number of blocks that were applied the segment delta q.
279 void vp9_cyclic_refresh_postencode(VP9_COMP *const cpi) {
280   VP9_COMMON *const cm = &cpi->common;
281   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
282   unsigned char *const seg_map = cpi->segmentation_map;
283   int mi_row, mi_col;
284   cr->actual_num_seg1_blocks = 0;
285   cr->actual_num_seg2_blocks = 0;
286   for (mi_row = 0; mi_row < cm->mi_rows; mi_row++)
287     for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
288       if (cyclic_refresh_segment_id(
289           seg_map[mi_row * cm->mi_cols + mi_col]) == CR_SEGMENT_ID_BOOST1)
290         cr->actual_num_seg1_blocks++;
291       else if (cyclic_refresh_segment_id(
292           seg_map[mi_row * cm->mi_cols + mi_col]) == CR_SEGMENT_ID_BOOST2)
293         cr->actual_num_seg2_blocks++;
294     }
295 }
296
297 // Set golden frame update interval, for non-svc 1 pass CBR mode.
298 void vp9_cyclic_refresh_set_golden_update(VP9_COMP *const cpi) {
299   RATE_CONTROL *const rc = &cpi->rc;
300   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
301   // Set minimum gf_interval for GF update to a multiple of the refresh period,
302   // with some max limit. Depending on past encoding stats, GF flag may be
303   // reset and update may not occur until next baseline_gf_interval.
304   if (cr->percent_refresh > 0)
305     rc->baseline_gf_interval = VPXMIN(4 * (100 / cr->percent_refresh), 40);
306   else
307     rc->baseline_gf_interval = 40;
308 }
309
310 // Update some encoding stats (from the just encoded frame). If this frame's
311 // background has high motion, refresh the golden frame. Otherwise, if the
312 // golden reference is to be updated check if we should NOT update the golden
313 // ref.
314 void vp9_cyclic_refresh_check_golden_update(VP9_COMP *const cpi) {
315   VP9_COMMON *const cm = &cpi->common;
316   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
317   int mi_row, mi_col;
318   double fraction_low = 0.0;
319   int low_content_frame = 0;
320
321   MODE_INFO **mi = cm->mi_grid_visible;
322   RATE_CONTROL *const rc = &cpi->rc;
323   const int rows = cm->mi_rows, cols = cm->mi_cols;
324   int cnt1 = 0, cnt2 = 0;
325   int force_gf_refresh = 0;
326
327   for (mi_row = 0; mi_row < rows; mi_row++) {
328     for (mi_col = 0; mi_col < cols; mi_col++) {
329       int16_t abs_mvr = mi[0]->mv[0].as_mv.row >= 0 ?
330           mi[0]->mv[0].as_mv.row : -1 * mi[0]->mv[0].as_mv.row;
331       int16_t abs_mvc = mi[0]->mv[0].as_mv.col >= 0 ?
332           mi[0]->mv[0].as_mv.col : -1 * mi[0]->mv[0].as_mv.col;
333
334       // Calculate the motion of the background.
335       if (abs_mvr <= 16 && abs_mvc <= 16) {
336         cnt1++;
337         if (abs_mvr == 0 && abs_mvc == 0)
338           cnt2++;
339       }
340       mi++;
341
342       // Accumulate low_content_frame.
343       if (cr->map[mi_row * cols + mi_col] < 1)
344         low_content_frame++;
345     }
346     mi += 8;
347   }
348
349   // For video conference clips, if the background has high motion in current
350   // frame because of the camera movement, set this frame as the golden frame.
351   // Use 70% and 5% as the thresholds for golden frame refreshing.
352   // Also, force this frame as a golden update frame if this frame will change
353   // the resolution (resize_pending != 0).
354   if (cpi->resize_pending != 0 ||
355      (cnt1 * 10 > (70 * rows * cols) && cnt2 * 20 < cnt1)) {
356     vp9_cyclic_refresh_set_golden_update(cpi);
357     rc->frames_till_gf_update_due = rc->baseline_gf_interval;
358
359     if (rc->frames_till_gf_update_due > rc->frames_to_key)
360       rc->frames_till_gf_update_due = rc->frames_to_key;
361     cpi->refresh_golden_frame = 1;
362     force_gf_refresh = 1;
363   }
364
365   fraction_low =
366       (double)low_content_frame / (rows * cols);
367   // Update average.
368   cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4;
369   if (!force_gf_refresh && cpi->refresh_golden_frame == 1) {
370     // Don't update golden reference if the amount of low_content for the
371     // current encoded frame is small, or if the recursive average of the
372     // low_content over the update interval window falls below threshold.
373     if (fraction_low < 0.8 || cr->low_content_avg < 0.7)
374       cpi->refresh_golden_frame = 0;
375     // Reset for next internal.
376     cr->low_content_avg = fraction_low;
377   }
378 }
379
380 // Update the segmentation map, and related quantities: cyclic refresh map,
381 // refresh sb_index, and target number of blocks to be refreshed.
382 // The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to
383 // 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock.
384 // Blocks labeled as BOOST1 may later get set to BOOST2 (during the
385 // encoding of the superblock).
386 static void cyclic_refresh_update_map(VP9_COMP *const cpi) {
387   VP9_COMMON *const cm = &cpi->common;
388   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
389   unsigned char *const seg_map = cpi->segmentation_map;
390   int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame;
391   int xmis, ymis, x, y;
392   int consec_zero_mv_thresh = 0;
393   int qindex_thresh = 0;
394   int count_sel = 0;
395   int count_tot = 0;
396   memset(seg_map, CR_SEGMENT_ID_BASE, cm->mi_rows * cm->mi_cols);
397   sb_cols = (cm->mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
398   sb_rows = (cm->mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
399   sbs_in_frame = sb_cols * sb_rows;
400   // Number of target blocks to get the q delta (segment 1).
401   block_count = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100;
402   // Set the segmentation map: cycle through the superblocks, starting at
403   // cr->mb_index, and stopping when either block_count blocks have been found
404   // to be refreshed, or we have passed through whole frame.
405   assert(cr->sb_index < sbs_in_frame);
406   i = cr->sb_index;
407   cr->target_num_seg_blocks = 0;
408   if (cpi->oxcf.content != VP9E_CONTENT_SCREEN) {
409     consec_zero_mv_thresh = 100;
410    if (cpi->noise_estimate.enabled && cpi->noise_estimate.level >= kMedium)
411      consec_zero_mv_thresh = 80;
412   }
413   qindex_thresh =
414       cpi->oxcf.content == VP9E_CONTENT_SCREEN
415       ? vp9_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST2, cm->base_qindex)
416       : vp9_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST1, cm->base_qindex);
417   do {
418     int sum_map = 0;
419     // Get the mi_row/mi_col corresponding to superblock index i.
420     int sb_row_index = (i / sb_cols);
421     int sb_col_index = i - sb_row_index * sb_cols;
422     int mi_row = sb_row_index * MI_BLOCK_SIZE;
423     int mi_col = sb_col_index * MI_BLOCK_SIZE;
424     assert(mi_row >= 0 && mi_row < cm->mi_rows);
425     assert(mi_col >= 0 && mi_col < cm->mi_cols);
426     bl_index = mi_row * cm->mi_cols + mi_col;
427     // Loop through all 8x8 blocks in superblock and update map.
428     xmis =
429         VPXMIN(cm->mi_cols - mi_col, num_8x8_blocks_wide_lookup[BLOCK_64X64]);
430     ymis =
431         VPXMIN(cm->mi_rows - mi_row, num_8x8_blocks_high_lookup[BLOCK_64X64]);
432     for (y = 0; y < ymis; y++) {
433       for (x = 0; x < xmis; x++) {
434         const int bl_index2 = bl_index + y * cm->mi_cols + x;
435         // If the block is as a candidate for clean up then mark it
436         // for possible boost/refresh (segment 1). The segment id may get
437         // reset to 0 later if block gets coded anything other than ZEROMV.
438         if (cr->map[bl_index2] == 0) {
439           count_tot++;
440           if (cr->last_coded_q_map[bl_index2] > qindex_thresh ||
441               cr->consec_zero_mv[bl_index2] < consec_zero_mv_thresh) {
442             sum_map++;
443             count_sel++;
444           }
445         } else if (cr->map[bl_index2] < 0) {
446           cr->map[bl_index2]++;
447         }
448       }
449     }
450     // Enforce constant segment over superblock.
451     // If segment is at least half of superblock, set to 1.
452     if (sum_map >= xmis * ymis / 2) {
453       for (y = 0; y < ymis; y++)
454         for (x = 0; x < xmis; x++) {
455           seg_map[bl_index + y * cm->mi_cols + x] = CR_SEGMENT_ID_BOOST1;
456         }
457       cr->target_num_seg_blocks += xmis * ymis;
458     }
459     i++;
460     if (i == sbs_in_frame) {
461       i = 0;
462     }
463   } while (cr->target_num_seg_blocks < block_count && i != cr->sb_index);
464   cr->sb_index = i;
465   cr->reduce_refresh = 0;
466   if (count_sel < (3 * count_tot) >> 2)
467     cr->reduce_refresh = 1;
468 }
469
470 // Set cyclic refresh parameters.
471 void vp9_cyclic_refresh_update_parameters(VP9_COMP *const cpi) {
472   const RATE_CONTROL *const rc = &cpi->rc;
473   const VP9_COMMON *const cm = &cpi->common;
474   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
475   cr->percent_refresh = 10;
476   if (cr->reduce_refresh)
477     cr->percent_refresh = 5;
478   cr->max_qdelta_perc = 50;
479   cr->time_for_refresh = 0;
480   // Use larger delta-qp (increase rate_ratio_qdelta) for first few (~4)
481   // periods of the refresh cycle, after a key frame.
482   // Account for larger interval on base layer for temporal layers.
483   if (cr->percent_refresh > 0 &&
484       rc->frames_since_key <  (4 * cpi->svc.number_temporal_layers) *
485       (100 / cr->percent_refresh)) {
486     cr->rate_ratio_qdelta = 3.0;
487   } else {
488     cr->rate_ratio_qdelta = 2.0;
489   if (cpi->noise_estimate.enabled && cpi->noise_estimate.level >= kMedium)
490     // Reduce the delta-qp if the estimated source noise is above threshold.
491     cr->rate_ratio_qdelta = 1.5;
492   }
493   // Adjust some parameters for low resolutions at low bitrates.
494   if (cm->width <= 352 &&
495       cm->height <= 288 &&
496       rc->avg_frame_bandwidth < 3400) {
497     cr->motion_thresh = 4;
498     cr->rate_boost_fac = 10;
499   } else {
500     cr->motion_thresh = 32;
501     cr->rate_boost_fac = 15;
502   }
503   if (cpi->svc.spatial_layer_id > 0) {
504     cr->motion_thresh = 4;
505     cr->rate_boost_fac = 12;
506   }
507 }
508
509 // Setup cyclic background refresh: set delta q and segmentation map.
510 void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
511   VP9_COMMON *const cm = &cpi->common;
512   const RATE_CONTROL *const rc = &cpi->rc;
513   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
514   struct segmentation *const seg = &cm->seg;
515   // TODO(marpan): Look into whether we should reduce the amount/delta-qp
516   // instead of completely shutting off at low bitrates. For now keep it on.
517   // const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc);
518   const int apply_cyclic_refresh = 1;
519   if (cm->current_video_frame == 0)
520     cr->low_content_avg = 0.0;
521   // Don't apply refresh on key frame or temporal enhancement layer frames.
522   if (!apply_cyclic_refresh ||
523       (cm->frame_type == KEY_FRAME) ||
524       (cpi->svc.temporal_layer_id > 0)) {
525     // Set segmentation map to 0 and disable.
526     unsigned char *const seg_map = cpi->segmentation_map;
527     memset(seg_map, 0, cm->mi_rows * cm->mi_cols);
528     vp9_disable_segmentation(&cm->seg);
529     if (cm->frame_type == KEY_FRAME) {
530       memset(cr->last_coded_q_map, MAXQ,
531              cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map));
532       memset(cr->consec_zero_mv, 0,
533              cm->mi_rows * cm->mi_cols * sizeof(*cr->consec_zero_mv));
534       cr->sb_index = 0;
535     }
536     return;
537   } else {
538     int qindex_delta = 0;
539     int qindex2;
540     const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth);
541     vpx_clear_system_state();
542     // Set rate threshold to some multiple (set to 2 for now) of the target
543     // rate (target is given by sb64_target_rate and scaled by 256).
544     cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 2;
545     // Distortion threshold, quadratic in Q, scale factor to be adjusted.
546     // q will not exceed 457, so (q * q) is within 32bit; see:
547     // vp9_convert_qindex_to_q(), vp9_ac_quant(), ac_qlookup*[].
548     cr->thresh_dist_sb = ((int64_t)(q * q)) << 2;
549
550     // Set up segmentation.
551     // Clear down the segment map.
552     vp9_enable_segmentation(&cm->seg);
553     vp9_clearall_segfeatures(seg);
554     // Select delta coding method.
555     seg->abs_delta = SEGMENT_DELTADATA;
556
557     // Note: setting temporal_update has no effect, as the seg-map coding method
558     // (temporal or spatial) is determined in vp9_choose_segmap_coding_method(),
559     // based on the coding cost of each method. For error_resilient mode on the
560     // last_frame_seg_map is set to 0, so if temporal coding is used, it is
561     // relative to 0 previous map.
562     // seg->temporal_update = 0;
563
564     // Segment BASE "Q" feature is disabled so it defaults to the baseline Q.
565     vp9_disable_segfeature(seg, CR_SEGMENT_ID_BASE, SEG_LVL_ALT_Q);
566     // Use segment BOOST1 for in-frame Q adjustment.
567     vp9_enable_segfeature(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q);
568     // Use segment BOOST2 for more aggressive in-frame Q adjustment.
569     vp9_enable_segfeature(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q);
570
571     // Set the q delta for segment BOOST1.
572     qindex_delta = compute_deltaq(cpi, cm->base_qindex, cr->rate_ratio_qdelta);
573     cr->qindex_delta[1] = qindex_delta;
574
575     // Compute rd-mult for segment BOOST1.
576     qindex2 = clamp(cm->base_qindex + cm->y_dc_delta_q + qindex_delta, 0, MAXQ);
577
578     cr->rdmult = vp9_compute_rd_mult(cpi, qindex2);
579
580     vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q, qindex_delta);
581
582     // Set a more aggressive (higher) q delta for segment BOOST2.
583     qindex_delta = compute_deltaq(
584         cpi, cm->base_qindex,
585         VPXMIN(CR_MAX_RATE_TARGET_RATIO,
586                0.1 * cr->rate_boost_fac * cr->rate_ratio_qdelta));
587     cr->qindex_delta[2] = qindex_delta;
588     vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta);
589
590     // Reset if resoluton change has occurred.
591     if (cpi->resize_pending != 0)
592       vp9_cyclic_refresh_reset_resize(cpi);
593
594     // Update the segmentation and refresh map.
595     cyclic_refresh_update_map(cpi);
596   }
597 }
598
599 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) {
600   return cr->rdmult;
601 }
602
603 void vp9_cyclic_refresh_reset_resize(VP9_COMP *const cpi) {
604   const VP9_COMMON *const cm = &cpi->common;
605   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
606   memset(cr->map, 0, cm->mi_rows * cm->mi_cols);
607   memset(cr->last_coded_q_map, MAXQ, cm->mi_rows * cm->mi_cols);
608   memset(cr->consec_zero_mv, 0, cm->mi_rows * cm->mi_cols);
609   cr->sb_index = 0;
610   cpi->refresh_golden_frame = 1;
611   cpi->refresh_alt_ref_frame = 1;
612 }