OLD | NEW |
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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 } | 272 } |
273 | 273 |
274 // Set golden frame update interval, for non-svc 1 pass CBR mode. | 274 // Set golden frame update interval, for non-svc 1 pass CBR mode. |
275 void vp9_cyclic_refresh_set_golden_update(VP9_COMP *const cpi) { | 275 void vp9_cyclic_refresh_set_golden_update(VP9_COMP *const cpi) { |
276 RATE_CONTROL *const rc = &cpi->rc; | 276 RATE_CONTROL *const rc = &cpi->rc; |
277 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; | 277 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |
278 // Set minimum gf_interval for GF update to a multiple (== 2) of refresh | 278 // Set minimum gf_interval for GF update to a multiple (== 2) of refresh |
279 // period. Depending on past encoding stats, GF flag may be reset and update | 279 // period. Depending on past encoding stats, GF flag may be reset and update |
280 // may not occur until next baseline_gf_interval. | 280 // may not occur until next baseline_gf_interval. |
281 if (cr->percent_refresh > 0) | 281 if (cr->percent_refresh > 0) |
282 rc->baseline_gf_interval = 2 * (100 / cr->percent_refresh); | 282 rc->baseline_gf_interval = 4 * (100 / cr->percent_refresh); |
283 else | 283 else |
284 rc->baseline_gf_interval = 20; | 284 rc->baseline_gf_interval = 40; |
285 } | 285 } |
286 | 286 |
287 // Update some encoding stats (from the just encoded frame), and if the golden | 287 // Update some encoding stats (from the just encoded frame). If this frame's |
288 // reference is to be updated check if we should NOT update the golden ref. | 288 // background has high motion, refresh the golden frame. Otherwise, if the |
| 289 // golden reference is to be updated check if we should NOT update the golden |
| 290 // ref. |
289 void vp9_cyclic_refresh_check_golden_update(VP9_COMP *const cpi) { | 291 void vp9_cyclic_refresh_check_golden_update(VP9_COMP *const cpi) { |
290 VP9_COMMON *const cm = &cpi->common; | 292 VP9_COMMON *const cm = &cpi->common; |
291 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; | 293 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |
292 int mi_row, mi_col; | 294 int mi_row, mi_col; |
293 double fraction_low = 0.0; | 295 double fraction_low = 0.0; |
294 int low_content_frame = 0; | 296 int low_content_frame = 0; |
295 for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) | 297 |
296 for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { | 298 MODE_INFO **mi = cm->mi_grid_visible; |
297 if (cr->map[mi_row * cm->mi_cols + mi_col] < 1) | 299 RATE_CONTROL *const rc = &cpi->rc; |
| 300 const int rows = cm->mi_rows, cols = cm->mi_cols; |
| 301 int cnt1 = 0, cnt2 = 0; |
| 302 int force_gf_refresh = 0; |
| 303 |
| 304 for (mi_row = 0; mi_row < rows; mi_row++) { |
| 305 for (mi_col = 0; mi_col < cols; mi_col++) { |
| 306 int16_t abs_mvr = mi[0]->mbmi.mv[0].as_mv.row >= 0 ? |
| 307 mi[0]->mbmi.mv[0].as_mv.row : -1 * mi[0]->mbmi.mv[0].as_mv.row; |
| 308 int16_t abs_mvc = mi[0]->mbmi.mv[0].as_mv.col >= 0 ? |
| 309 mi[0]->mbmi.mv[0].as_mv.col : -1 * mi[0]->mbmi.mv[0].as_mv.col; |
| 310 |
| 311 // Calculate the motion of the background. |
| 312 if (abs_mvr <= 16 && abs_mvc <= 16) { |
| 313 cnt1++; |
| 314 if (abs_mvr == 0 && abs_mvc == 0) |
| 315 cnt2++; |
| 316 } |
| 317 mi++; |
| 318 |
| 319 // Accumulate low_content_frame. |
| 320 if (cr->map[mi_row * cols + mi_col] < 1) |
298 low_content_frame++; | 321 low_content_frame++; |
299 } | 322 } |
| 323 mi += 8; |
| 324 } |
| 325 |
| 326 // For video conference clips, if the background has high motion in current |
| 327 // frame because of the camera movement, set this frame as the golden frame. |
| 328 // Use 70% and 5% as the thresholds for golden frame refreshing. |
| 329 if (cnt1 * 10 > (70 * rows * cols) && cnt2 * 20 < cnt1) { |
| 330 vp9_cyclic_refresh_set_golden_update(cpi); |
| 331 rc->frames_till_gf_update_due = rc->baseline_gf_interval; |
| 332 |
| 333 if (rc->frames_till_gf_update_due > rc->frames_to_key) |
| 334 rc->frames_till_gf_update_due = rc->frames_to_key; |
| 335 cpi->refresh_golden_frame = 1; |
| 336 force_gf_refresh = 1; |
| 337 } |
| 338 |
300 fraction_low = | 339 fraction_low = |
301 (double)low_content_frame / (cm->mi_rows * cm->mi_cols); | 340 (double)low_content_frame / (rows * cols); |
302 // Update average. | 341 // Update average. |
303 cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4; | 342 cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4; |
304 if (cpi->refresh_golden_frame == 1) { | 343 if (!force_gf_refresh && cpi->refresh_golden_frame == 1) { |
305 // Don't update golden reference if the amount of low_content for the | 344 // Don't update golden reference if the amount of low_content for the |
306 // current encoded frame is small, or if the recursive average of the | 345 // current encoded frame is small, or if the recursive average of the |
307 // low_content over the update interval window falls below threshold. | 346 // low_content over the update interval window falls below threshold. |
308 if (fraction_low < 0.8 || cr->low_content_avg < 0.7) | 347 if (fraction_low < 0.8 || cr->low_content_avg < 0.7) |
309 cpi->refresh_golden_frame = 0; | 348 cpi->refresh_golden_frame = 0; |
310 // Reset for next internal. | 349 // Reset for next internal. |
311 cr->low_content_avg = fraction_low; | 350 cr->low_content_avg = fraction_low; |
312 } | 351 } |
313 } | 352 } |
314 | 353 |
315 // Update the segmentation map, and related quantities: cyclic refresh map, | 354 // Update the segmentation map, and related quantities: cyclic refresh map, |
316 // refresh sb_index, and target number of blocks to be refreshed. | 355 // refresh sb_index, and target number of blocks to be refreshed. |
317 // The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to | 356 // The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to |
318 // 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock. | 357 // 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock. |
319 // Blocks labeled as BOOST1 may later get set to BOOST2 (during the | 358 // Blocks labeled as BOOST1 may later get set to BOOST2 (during the |
320 // encoding of the superblock). | 359 // encoding of the superblock). |
321 void vp9_cyclic_refresh_update_map(VP9_COMP *const cpi) { | 360 void vp9_cyclic_refresh_update_map(VP9_COMP *const cpi) { |
322 VP9_COMMON *const cm = &cpi->common; | 361 VP9_COMMON *const cm = &cpi->common; |
323 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; | 362 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |
324 unsigned char *const seg_map = cpi->segmentation_map; | 363 unsigned char *const seg_map = cpi->segmentation_map; |
325 int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame; | 364 int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame; |
326 int xmis, ymis, x, y; | 365 int xmis, ymis, x, y; |
327 vpx_memset(seg_map, CR_SEGMENT_ID_BASE, cm->mi_rows * cm->mi_cols); | 366 memset(seg_map, CR_SEGMENT_ID_BASE, cm->mi_rows * cm->mi_cols); |
328 sb_cols = (cm->mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; | 367 sb_cols = (cm->mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; |
329 sb_rows = (cm->mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; | 368 sb_rows = (cm->mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; |
330 sbs_in_frame = sb_cols * sb_rows; | 369 sbs_in_frame = sb_cols * sb_rows; |
331 // Number of target blocks to get the q delta (segment 1). | 370 // Number of target blocks to get the q delta (segment 1). |
332 block_count = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100; | 371 block_count = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100; |
333 // Set the segmentation map: cycle through the superblocks, starting at | 372 // Set the segmentation map: cycle through the superblocks, starting at |
334 // cr->mb_index, and stopping when either block_count blocks have been found | 373 // cr->mb_index, and stopping when either block_count blocks have been found |
335 // to be refreshed, or we have passed through whole frame. | 374 // to be refreshed, or we have passed through whole frame. |
336 assert(cr->sb_index < sbs_in_frame); | 375 assert(cr->sb_index < sbs_in_frame); |
337 i = cr->sb_index; | 376 i = cr->sb_index; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc); | 443 const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc); |
405 if (cm->current_video_frame == 0) | 444 if (cm->current_video_frame == 0) |
406 cr->low_content_avg = 0.0; | 445 cr->low_content_avg = 0.0; |
407 // Don't apply refresh on key frame or enhancement layer frames. | 446 // Don't apply refresh on key frame or enhancement layer frames. |
408 if (!apply_cyclic_refresh || | 447 if (!apply_cyclic_refresh || |
409 (cm->frame_type == KEY_FRAME) || | 448 (cm->frame_type == KEY_FRAME) || |
410 (cpi->svc.temporal_layer_id > 0) || | 449 (cpi->svc.temporal_layer_id > 0) || |
411 (cpi->svc.spatial_layer_id > 0)) { | 450 (cpi->svc.spatial_layer_id > 0)) { |
412 // Set segmentation map to 0 and disable. | 451 // Set segmentation map to 0 and disable. |
413 unsigned char *const seg_map = cpi->segmentation_map; | 452 unsigned char *const seg_map = cpi->segmentation_map; |
414 vpx_memset(seg_map, 0, cm->mi_rows * cm->mi_cols); | 453 memset(seg_map, 0, cm->mi_rows * cm->mi_cols); |
415 vp9_disable_segmentation(&cm->seg); | 454 vp9_disable_segmentation(&cm->seg); |
416 if (cm->frame_type == KEY_FRAME) | 455 if (cm->frame_type == KEY_FRAME) |
417 cr->sb_index = 0; | 456 cr->sb_index = 0; |
418 return; | 457 return; |
419 } else { | 458 } else { |
420 int qindex_delta = 0; | 459 int qindex_delta = 0; |
421 int qindex2; | 460 int qindex2; |
422 const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); | 461 const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); |
423 vp9_clear_system_state(); | 462 vp9_clear_system_state(); |
424 cr->max_qdelta_perc = 50; | 463 cr->max_qdelta_perc = 50; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta); | 510 vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta); |
472 | 511 |
473 // Update the segmentation and refresh map. | 512 // Update the segmentation and refresh map. |
474 vp9_cyclic_refresh_update_map(cpi); | 513 vp9_cyclic_refresh_update_map(cpi); |
475 } | 514 } |
476 } | 515 } |
477 | 516 |
478 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) { | 517 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) { |
479 return cr->rdmult; | 518 return cr->rdmult; |
480 } | 519 } |
OLD | NEW |