| 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 |