Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(488)

Side by Side Diff: source/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c

Issue 1015483002: libvpx: Pull from upstream (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libvpx.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 29 matching lines...) Expand all
40 signed char *map; 40 signed char *map;
41 // Thresholds applied to the projected rate/distortion of the coding block, 41 // Thresholds applied to the projected rate/distortion of the coding block,
42 // when deciding whether block should be refreshed. 42 // when deciding whether block should be refreshed.
43 int64_t thresh_rate_sb; 43 int64_t thresh_rate_sb;
44 int64_t thresh_dist_sb; 44 int64_t thresh_dist_sb;
45 // Threshold applied to the motion vector (in units of 1/8 pel) of the 45 // Threshold applied to the motion vector (in units of 1/8 pel) of the
46 // coding block, when deciding whether block should be refreshed. 46 // coding block, when deciding whether block should be refreshed.
47 int16_t motion_thresh; 47 int16_t motion_thresh;
48 // Rate target ratio to set q delta. 48 // Rate target ratio to set q delta.
49 double rate_ratio_qdelta; 49 double rate_ratio_qdelta;
50 double low_content_avg;
50 }; 51 };
51 52
52 CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) { 53 CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) {
53 CYCLIC_REFRESH *const cr = vpx_calloc(1, sizeof(*cr)); 54 CYCLIC_REFRESH *const cr = vpx_calloc(1, sizeof(*cr));
54 if (cr == NULL) 55 if (cr == NULL)
55 return NULL; 56 return NULL;
56 57
57 cr->map = vpx_calloc(mi_rows * mi_cols, sizeof(*cr->map)); 58 cr->map = vpx_calloc(mi_rows * mi_cols, sizeof(*cr->map));
58 if (cr->map == NULL) { 59 if (cr->map == NULL) {
59 vpx_free(cr); 60 vpx_free(cr);
60 return NULL; 61 return NULL;
61 } 62 }
62 63
63 return cr; 64 return cr;
64 } 65 }
65 66
66 void vp9_cyclic_refresh_free(CYCLIC_REFRESH *cr) { 67 void vp9_cyclic_refresh_free(CYCLIC_REFRESH *cr) {
67 vpx_free(cr->map); 68 vpx_free(cr->map);
68 vpx_free(cr); 69 vpx_free(cr);
69 } 70 }
70 71
71 // Check if we should turn off cyclic refresh based on bitrate condition. 72 // Check if we should turn off cyclic refresh based on bitrate condition.
72 static int apply_cyclic_refresh_bitrate(const VP9_COMMON *cm, 73 static int apply_cyclic_refresh_bitrate(const VP9_COMMON *cm,
73 const RATE_CONTROL *rc) { 74 const RATE_CONTROL *rc) {
74 // Turn off cyclic refresh if bits available per frame is not sufficiently 75 // Turn off cyclic refresh if bits available per frame is not sufficiently
75 // larger than bit cost of segmentation. Segment map bit cost should scale 76 // larger than bit cost of segmentation. Segment map bit cost should scale
76 // with number of seg blocks, so compare available bits to number of blocks. 77 // with number of seg blocks, so compare available bits to number of blocks.
77 // Average bits available per frame = avg_frame_bandwidth 78 // Average bits available per frame = avg_frame_bandwidth
78 // Number of (8x8) blocks in frame = mi_rows * mi_cols; 79 // Number of (8x8) blocks in frame = mi_rows * mi_cols;
79 const float factor = 0.5; 80 const float factor = 0.25;
80 const int number_blocks = cm->mi_rows * cm->mi_cols; 81 const int number_blocks = cm->mi_rows * cm->mi_cols;
81 // The condition below corresponds to turning off at target bitrates: 82 // The condition below corresponds to turning off at target bitrates:
82 // ~24kbps for CIF, 72kbps for VGA (at 30fps). 83 // (at 30fps), ~12kbps for CIF, 36kbps for VGA, 100kps for HD/720p.
83 // Also turn off at very small frame sizes, to avoid too large fraction of 84 // Also turn off at very small frame sizes, to avoid too large fraction of
84 // superblocks to be refreshed per frame. Threshold below is less than QCIF. 85 // superblocks to be refreshed per frame. Threshold below is less than QCIF.
85 if (rc->avg_frame_bandwidth < factor * number_blocks || 86 if (rc->avg_frame_bandwidth < factor * number_blocks ||
86 number_blocks / 64 < 5) 87 number_blocks / 64 < 5)
87 return 0; 88 return 0;
88 else 89 else
89 return 1; 90 return 1;
90 } 91 }
91 92
92 // Check if this coding block, of size bsize, should be considered for refresh 93 // Check if this coding block, of size bsize, should be considered for refresh
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 const int ymis = MIN(cm->mi_rows - mi_row, bh); 207 const int ymis = MIN(cm->mi_rows - mi_row, bh);
207 const int block_index = mi_row * cm->mi_cols + mi_col; 208 const int block_index = mi_row * cm->mi_cols + mi_col;
208 const int refresh_this_block = candidate_refresh_aq(cr, mbmi, rate, dist, 209 const int refresh_this_block = candidate_refresh_aq(cr, mbmi, rate, dist,
209 bsize); 210 bsize);
210 // Default is to not update the refresh map. 211 // Default is to not update the refresh map.
211 int new_map_value = cr->map[block_index]; 212 int new_map_value = cr->map[block_index];
212 int x = 0; int y = 0; 213 int x = 0; int y = 0;
213 214
214 // If this block is labeled for refresh, check if we should reset the 215 // If this block is labeled for refresh, check if we should reset the
215 // segment_id. 216 // segment_id.
216 if (mbmi->segment_id != CR_SEGMENT_ID_BASE) 217 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
217 mbmi->segment_id = refresh_this_block; 218 mbmi->segment_id = refresh_this_block;
218 219
219 // Update the cyclic refresh map, to be used for setting segmentation map 220 // Update the cyclic refresh map, to be used for setting segmentation map
220 // for the next frame. If the block will be refreshed this frame, mark it 221 // for the next frame. If the block will be refreshed this frame, mark it
221 // as clean. The magnitude of the -ve influences how long before we consider 222 // as clean. The magnitude of the -ve influences how long before we consider
222 // it for refresh again. 223 // it for refresh again.
223 if (mbmi->segment_id != CR_SEGMENT_ID_BASE) { 224 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id)) {
224 new_map_value = -cr->time_for_refresh; 225 new_map_value = -cr->time_for_refresh;
225 } else if (refresh_this_block) { 226 } else if (refresh_this_block) {
226 // Else if it is accepted as candidate for refresh, and has not already 227 // Else if it is accepted as candidate for refresh, and has not already
227 // been refreshed (marked as 1) then mark it as a candidate for cleanup 228 // been refreshed (marked as 1) then mark it as a candidate for cleanup
228 // for future time (marked as 0), otherwise don't update it. 229 // for future time (marked as 0), otherwise don't update it.
229 if (cr->map[block_index] == 1) 230 if (cr->map[block_index] == 1)
230 new_map_value = 0; 231 new_map_value = 0;
231 } else { 232 } else {
232 // Leave it marked as block that is not candidate for refresh. 233 // Leave it marked as block that is not candidate for refresh.
233 new_map_value = 1; 234 new_map_value = 1;
234 } 235 }
235 236
236 // Update entries in the cyclic refresh map with new_map_value, and 237 // Update entries in the cyclic refresh map with new_map_value, and
237 // copy mbmi->segment_id into global segmentation map. 238 // copy mbmi->segment_id into global segmentation map.
238 for (y = 0; y < ymis; y++) 239 for (y = 0; y < ymis; y++)
239 for (x = 0; x < xmis; x++) { 240 for (x = 0; x < xmis; x++) {
240 cr->map[block_index + y * cm->mi_cols + x] = new_map_value; 241 cr->map[block_index + y * cm->mi_cols + x] = new_map_value;
241 cpi->segmentation_map[block_index + y * cm->mi_cols + x] = 242 cpi->segmentation_map[block_index + y * cm->mi_cols + x] =
242 mbmi->segment_id; 243 mbmi->segment_id;
243 } 244 }
244 } 245 }
245 246
246 // Update the actual number of blocks that were applied the segment delta q. 247 // Update the actual number of blocks that were applied the segment delta q.
247 void vp9_cyclic_refresh_update_actual_count(struct VP9_COMP *const cpi) { 248 void vp9_cyclic_refresh_postencode(VP9_COMP *const cpi) {
248 VP9_COMMON *const cm = &cpi->common; 249 VP9_COMMON *const cm = &cpi->common;
249 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; 250 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
250 unsigned char *const seg_map = cpi->segmentation_map; 251 unsigned char *const seg_map = cpi->segmentation_map;
251 int mi_row, mi_col; 252 int mi_row, mi_col;
252 cr->actual_num_seg_blocks = 0; 253 cr->actual_num_seg_blocks = 0;
253 for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) 254 for (mi_row = 0; mi_row < cm->mi_rows; mi_row++)
254 for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { 255 for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
255 if (seg_map[mi_row * cm->mi_cols + mi_col] != CR_SEGMENT_ID_BASE) 256 if (cyclic_refresh_segment_id_boosted(
256 cr->actual_num_seg_blocks++; 257 seg_map[mi_row * cm->mi_cols + mi_col]))
258 cr->actual_num_seg_blocks++;
259 }
260 }
261
262 // Set golden frame update interval, for non-svc 1 pass CBR mode.
263 void vp9_cyclic_refresh_set_golden_update(VP9_COMP *const cpi) {
264 RATE_CONTROL *const rc = &cpi->rc;
265 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
266 // Set minimum gf_interval for GF update to a multiple (== 2) of refresh
267 // period. Depending on past encoding stats, GF flag may be reset and update
268 // may not occur until next baseline_gf_interval.
269 if (cr->percent_refresh > 0)
270 rc->baseline_gf_interval = 2 * (100 / cr->percent_refresh);
271 else
272 rc->baseline_gf_interval = 20;
273 }
274
275 // Update some encoding stats (from the just encoded frame), and if the golden
276 // reference is to be updated check if we should NOT update the golden ref.
277 void vp9_cyclic_refresh_check_golden_update(VP9_COMP *const cpi) {
278 VP9_COMMON *const cm = &cpi->common;
279 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
280 int mi_row, mi_col;
281 double fraction_low = 0.0;
282 int low_content_frame = 0;
283 for (mi_row = 0; mi_row < cm->mi_rows; mi_row++)
284 for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
285 if (cr->map[mi_row * cm->mi_cols + mi_col] < 1)
286 low_content_frame++;
287 }
288 fraction_low =
289 (double)low_content_frame / (cm->mi_rows * cm->mi_cols);
290 // Update average.
291 cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4;
292 if (cpi->refresh_golden_frame == 1) {
293 // Don't update golden reference if the amount of low_content for the
294 // current encoded frame is small, or if the recursive average of the
295 // low_content over the update interval window falls below threshold.
296 if (fraction_low < 0.8 || cr->low_content_avg < 0.7)
297 cpi->refresh_golden_frame = 0;
298 // Reset for next internal.
299 cr->low_content_avg = fraction_low;
257 } 300 }
258 } 301 }
259 302
260 // Update the segmentation map, and related quantities: cyclic refresh map, 303 // Update the segmentation map, and related quantities: cyclic refresh map,
261 // refresh sb_index, and target number of blocks to be refreshed. 304 // refresh sb_index, and target number of blocks to be refreshed.
262 // The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to 305 // The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to
263 // 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock. 306 // 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock.
264 // Blocks labeled as BOOST1 may later get set to BOOST2 (during the 307 // Blocks labeled as BOOST1 may later get set to BOOST2 (during the
265 // encoding of the superblock). 308 // encoding of the superblock).
266 void vp9_cyclic_refresh_update_map(VP9_COMP *const cpi) { 309 void vp9_cyclic_refresh_update_map(VP9_COMP *const cpi) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 cr->rate_ratio_qdelta = 2.0; 383 cr->rate_ratio_qdelta = 2.0;
341 } 384 }
342 385
343 // Setup cyclic background refresh: set delta q and segmentation map. 386 // Setup cyclic background refresh: set delta q and segmentation map.
344 void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { 387 void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
345 VP9_COMMON *const cm = &cpi->common; 388 VP9_COMMON *const cm = &cpi->common;
346 const RATE_CONTROL *const rc = &cpi->rc; 389 const RATE_CONTROL *const rc = &cpi->rc;
347 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; 390 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
348 struct segmentation *const seg = &cm->seg; 391 struct segmentation *const seg = &cm->seg;
349 const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc); 392 const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc);
393 if (cm->current_video_frame == 0)
394 cr->low_content_avg = 0.0;
350 // Don't apply refresh on key frame or enhancement layer frames. 395 // Don't apply refresh on key frame or enhancement layer frames.
351 if (!apply_cyclic_refresh || 396 if (!apply_cyclic_refresh ||
352 (cm->frame_type == KEY_FRAME) || 397 (cm->frame_type == KEY_FRAME) ||
353 (cpi->svc.temporal_layer_id > 0) || 398 (cpi->svc.temporal_layer_id > 0) ||
354 (cpi->svc.spatial_layer_id > 0)) { 399 (cpi->svc.spatial_layer_id > 0)) {
355 // Set segmentation map to 0 and disable. 400 // Set segmentation map to 0 and disable.
356 unsigned char *const seg_map = cpi->segmentation_map; 401 unsigned char *const seg_map = cpi->segmentation_map;
357 vpx_memset(seg_map, 0, cm->mi_rows * cm->mi_cols); 402 vpx_memset(seg_map, 0, cm->mi_rows * cm->mi_cols);
358 vp9_disable_segmentation(&cm->seg); 403 vp9_disable_segmentation(&cm->seg);
359 if (cm->frame_type == KEY_FRAME) 404 if (cm->frame_type == KEY_FRAME)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta); 456 vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta);
412 457
413 // Update the segmentation and refresh map. 458 // Update the segmentation and refresh map.
414 vp9_cyclic_refresh_update_map(cpi); 459 vp9_cyclic_refresh_update_map(cpi);
415 } 460 }
416 } 461 }
417 462
418 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) { 463 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) {
419 return cr->rdmult; 464 return cr->rdmult;
420 } 465 }
OLDNEW
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.h ('k') | source/libvpx/vp9/encoder/vp9_encodeframe.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698