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