| 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 20 matching lines...) Expand all Loading... |
| 31 // Controls how long a block will need to wait to be refreshed again. | 31 // Controls how long a block will need to wait to be refreshed again. |
| 32 int time_for_refresh; | 32 int time_for_refresh; |
| 33 // Actual number of (8x8) blocks that were applied delta-q (segment 1). | 33 // Actual number of (8x8) blocks that were applied delta-q (segment 1). |
| 34 int num_seg_blocks; | 34 int num_seg_blocks; |
| 35 // Actual encoding bits for segment 1. | 35 // Actual encoding bits for segment 1. |
| 36 int actual_seg_bits; | 36 int actual_seg_bits; |
| 37 // RD mult. parameters for segment 1. | 37 // RD mult. parameters for segment 1. |
| 38 int rdmult; | 38 int rdmult; |
| 39 // Cyclic refresh map. | 39 // Cyclic refresh map. |
| 40 signed char *map; | 40 signed char *map; |
| 41 // Projected rate and distortion for the current superblock. | |
| 42 int64_t projected_rate_sb; | |
| 43 int64_t projected_dist_sb; | |
| 44 // Thresholds applied to projected rate/distortion of the superblock. | 41 // Thresholds applied to projected rate/distortion of the superblock. |
| 45 int64_t thresh_rate_sb; | 42 int64_t thresh_rate_sb; |
| 46 int64_t thresh_dist_sb; | 43 int64_t thresh_dist_sb; |
| 47 }; | 44 }; |
| 48 | 45 |
| 49 CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) { | 46 CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) { |
| 50 CYCLIC_REFRESH *const cr = vpx_calloc(1, sizeof(*cr)); | 47 CYCLIC_REFRESH *const cr = vpx_calloc(1, sizeof(*cr)); |
| 51 if (cr == NULL) | 48 if (cr == NULL) |
| 52 return NULL; | 49 return NULL; |
| 53 | 50 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 else | 82 else |
| 86 return 1; | 83 return 1; |
| 87 } | 84 } |
| 88 | 85 |
| 89 // Check if this coding block, of size bsize, should be considered for refresh | 86 // Check if this coding block, of size bsize, should be considered for refresh |
| 90 // (lower-qp coding). Decision can be based on various factors, such as | 87 // (lower-qp coding). Decision can be based on various factors, such as |
| 91 // size of the coding block (i.e., below min_block size rejected), coding | 88 // size of the coding block (i.e., below min_block size rejected), coding |
| 92 // mode, and rate/distortion. | 89 // mode, and rate/distortion. |
| 93 static int candidate_refresh_aq(const CYCLIC_REFRESH *cr, | 90 static int candidate_refresh_aq(const CYCLIC_REFRESH *cr, |
| 94 const MB_MODE_INFO *mbmi, | 91 const MB_MODE_INFO *mbmi, |
| 95 BLOCK_SIZE bsize, int use_rd) { | 92 BLOCK_SIZE bsize, int use_rd, |
| 93 int64_t rate_sb) { |
| 96 if (use_rd) { | 94 if (use_rd) { |
| 95 MV mv = mbmi->mv[0].as_mv; |
| 97 // If projected rate is below the thresh_rate (well below target, | 96 // If projected rate is below the thresh_rate (well below target, |
| 98 // so undershoot expected), accept it for lower-qp coding. | 97 // so undershoot expected), accept it for lower-qp coding. |
| 99 if (cr->projected_rate_sb < cr->thresh_rate_sb) | 98 if (rate_sb < cr->thresh_rate_sb) |
| 100 return 1; | 99 return 1; |
| 101 // Otherwise, reject the block for lower-qp coding if any of the following: | 100 // Otherwise, reject the block for lower-qp coding if any of the following: |
| 102 // 1) prediction block size is below min_block_size | 101 // 1) mode uses large mv |
| 103 // 2) mode is non-zero mv and projected distortion is above thresh_dist | 102 // 2) mode is an intra-mode (we may want to allow some of this under |
| 104 // 3) mode is an intra-mode (we may want to allow some of this under | |
| 105 // another thresh_dist) | 103 // another thresh_dist) |
| 106 else if (bsize < cr->min_block_size || | 104 else if (mv.row > 32 || mv.row < -32 || |
| 107 (mbmi->mv[0].as_int != 0 && | 105 mv.col > 32 || mv.col < -32 || !is_inter_block(mbmi)) |
| 108 cr->projected_dist_sb > cr->thresh_dist_sb) || | |
| 109 !is_inter_block(mbmi)) | |
| 110 return 0; | 106 return 0; |
| 111 else | 107 else |
| 112 return 1; | 108 return 1; |
| 113 } else { | 109 } else { |
| 114 // Rate/distortion not used for update. | 110 // Rate/distortion not used for update. |
| 115 if (bsize < cr->min_block_size || | 111 if (bsize < cr->min_block_size || |
| 116 mbmi->mv[0].as_int != 0 || | 112 mbmi->mv[0].as_int != 0 || |
| 117 !is_inter_block(mbmi)) | 113 !is_inter_block(mbmi)) |
| 118 return 0; | 114 return 0; |
| 119 else | 115 else |
| 120 return 1; | 116 return 1; |
| 121 } | 117 } |
| 122 } | 118 } |
| 123 | 119 |
| 124 // Prior to coding a given prediction block, of size bsize at (mi_row, mi_col), | 120 // Prior to coding a given prediction block, of size bsize at (mi_row, mi_col), |
| 125 // check if we should reset the segment_id, and update the cyclic_refresh map | 121 // check if we should reset the segment_id, and update the cyclic_refresh map |
| 126 // and segmentation map. | 122 // and segmentation map. |
| 127 void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi, | 123 void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi, |
| 128 MB_MODE_INFO *const mbmi, | 124 MB_MODE_INFO *const mbmi, |
| 129 int mi_row, int mi_col, | 125 int mi_row, int mi_col, |
| 130 BLOCK_SIZE bsize, int use_rd) { | 126 BLOCK_SIZE bsize, int use_rd, |
| 127 int64_t rate_sb) { |
| 131 const VP9_COMMON *const cm = &cpi->common; | 128 const VP9_COMMON *const cm = &cpi->common; |
| 132 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; | 129 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |
| 133 const int bw = num_8x8_blocks_wide_lookup[bsize]; | 130 const int bw = num_8x8_blocks_wide_lookup[bsize]; |
| 134 const int bh = num_8x8_blocks_high_lookup[bsize]; | 131 const int bh = num_8x8_blocks_high_lookup[bsize]; |
| 135 const int xmis = MIN(cm->mi_cols - mi_col, bw); | 132 const int xmis = MIN(cm->mi_cols - mi_col, bw); |
| 136 const int ymis = MIN(cm->mi_rows - mi_row, bh); | 133 const int ymis = MIN(cm->mi_rows - mi_row, bh); |
| 137 const int block_index = mi_row * cm->mi_cols + mi_col; | 134 const int block_index = mi_row * cm->mi_cols + mi_col; |
| 138 const int refresh_this_block = cpi->mb.in_static_area || | 135 const int refresh_this_block = candidate_refresh_aq(cr, mbmi, bsize, use_rd, |
| 139 candidate_refresh_aq(cr, mbmi, bsize, use_rd); | 136 rate_sb); |
| 140 // Default is to not update the refresh map. | 137 // Default is to not update the refresh map. |
| 141 int new_map_value = cr->map[block_index]; | 138 int new_map_value = cr->map[block_index]; |
| 142 int x = 0; int y = 0; | 139 int x = 0; int y = 0; |
| 143 | 140 |
| 144 // Check if we should reset the segment_id for this block. | 141 // Check if we should reset the segment_id for this block. |
| 145 if (mbmi->segment_id > 0 && !refresh_this_block) | 142 if (mbmi->segment_id > 0 && !refresh_this_block) |
| 146 mbmi->segment_id = 0; | 143 mbmi->segment_id = 0; |
| 147 | 144 |
| 148 // Update the cyclic refresh map, to be used for setting segmentation map | 145 // Update the cyclic refresh map, to be used for setting segmentation map |
| 149 // for the next frame. If the block will be refreshed this frame, mark it | 146 // for the next frame. If the block will be refreshed this frame, mark it |
| 150 // as clean. The magnitude of the -ve influences how long before we consider | 147 // as clean. The magnitude of the -ve influences how long before we consider |
| 151 // it for refresh again. | 148 // it for refresh again. |
| 152 if (mbmi->segment_id == 1) { | 149 if (mbmi->segment_id == 1) { |
| 153 new_map_value = -cr->time_for_refresh; | 150 new_map_value = -cr->time_for_refresh; |
| 154 } else if (refresh_this_block) { | 151 } else if (refresh_this_block) { |
| 155 // Else if it is accepted as candidate for refresh, and has not already | 152 // Else if it is accepted as candidate for refresh, and has not already |
| 156 // been refreshed (marked as 1) then mark it as a candidate for cleanup | 153 // been refreshed (marked as 1) then mark it as a candidate for cleanup |
| 157 // for future time (marked as 0), otherwise don't update it. | 154 // for future time (marked as 0), otherwise don't update it. |
| 158 if (cr->map[block_index] == 1) | 155 if (cr->map[block_index] == 1) |
| 159 new_map_value = 0; | 156 new_map_value = 0; |
| 160 } else { | 157 } else { |
| 161 // Leave it marked as block that is not candidate for refresh. | 158 // Leave it marked as block that is not candidate for refresh. |
| 162 new_map_value = 1; | 159 new_map_value = 1; |
| 163 } | 160 } |
| 161 |
| 164 // Update entries in the cyclic refresh map with new_map_value, and | 162 // Update entries in the cyclic refresh map with new_map_value, and |
| 165 // copy mbmi->segment_id into global segmentation map. | 163 // copy mbmi->segment_id into global segmentation map. |
| 166 for (y = 0; y < ymis; y++) | 164 for (y = 0; y < ymis; y++) |
| 167 for (x = 0; x < xmis; x++) { | 165 for (x = 0; x < xmis; x++) { |
| 168 cr->map[block_index + y * cm->mi_cols + x] = new_map_value; | 166 cr->map[block_index + y * cm->mi_cols + x] = new_map_value; |
| 169 cpi->segmentation_map[block_index + y * cm->mi_cols + x] = | 167 cpi->segmentation_map[block_index + y * cm->mi_cols + x] = |
| 170 mbmi->segment_id; | 168 mbmi->segment_id; |
| 171 } | 169 } |
| 172 // Keep track of actual number (in units of 8x8) of blocks in segment 1 used | 170 // Keep track of actual number (in units of 8x8) of blocks in segment 1 used |
| 173 // for encoding this frame. | 171 // for encoding this frame. |
| 174 if (mbmi->segment_id) | 172 if (mbmi->segment_id) |
| 175 cr->num_seg_blocks += xmis * ymis; | 173 cr->num_seg_blocks += xmis * ymis; |
| 176 } | 174 } |
| 177 | 175 |
| 178 // Setup cyclic background refresh: set delta q and segmentation map. | 176 // Setup cyclic background refresh: set delta q and segmentation map. |
| 179 void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { | 177 void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { |
| 180 VP9_COMMON *const cm = &cpi->common; | 178 VP9_COMMON *const cm = &cpi->common; |
| 181 const RATE_CONTROL *const rc = &cpi->rc; | 179 const RATE_CONTROL *const rc = &cpi->rc; |
| 182 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; | 180 CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |
| 183 struct segmentation *const seg = &cm->seg; | 181 struct segmentation *const seg = &cm->seg; |
| 184 unsigned char *const seg_map = cpi->segmentation_map; | 182 unsigned char *const seg_map = cpi->segmentation_map; |
| 185 const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc); | 183 const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc); |
| 186 // Don't apply refresh on key frame or enhancement layer frames. | 184 // Don't apply refresh on key frame or enhancement layer frames. |
| 187 if (!apply_cyclic_refresh || | 185 if (!apply_cyclic_refresh || |
| 188 (cm->frame_type == KEY_FRAME) || | 186 (cm->frame_type == KEY_FRAME) || |
| 189 (cpi->svc.temporal_layer_id > 0)) { | 187 (cpi->svc.temporal_layer_id > 0) || |
| 188 (cpi->svc.spatial_layer_id > 0)) { |
| 190 // Set segmentation map to 0 and disable. | 189 // Set segmentation map to 0 and disable. |
| 191 vpx_memset(seg_map, 0, cm->mi_rows * cm->mi_cols); | 190 vpx_memset(seg_map, 0, cm->mi_rows * cm->mi_cols); |
| 192 vp9_disable_segmentation(&cm->seg); | 191 vp9_disable_segmentation(&cm->seg); |
| 193 if (cm->frame_type == KEY_FRAME) | 192 if (cm->frame_type == KEY_FRAME) |
| 194 cr->sb_index = 0; | 193 cr->sb_index = 0; |
| 195 return; | 194 return; |
| 196 } else { | 195 } else { |
| 197 int qindex_delta = 0; | 196 int qindex_delta = 0; |
| 198 int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame; | 197 int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame; |
| 199 int xmis, ymis, x, y, qindex2; | 198 int xmis, ymis, x, y, qindex2; |
| 200 | 199 |
| 201 // Rate target ratio to set q delta. | 200 // Rate target ratio to set q delta. |
| 202 const float rate_ratio_qdelta = 2.0; | 201 const float rate_ratio_qdelta = 2.0; |
| 203 const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); | 202 const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); |
| 204 vp9_clear_system_state(); | 203 vp9_clear_system_state(); |
| 205 // Some of these parameters may be set via codec-control function later. | 204 // Some of these parameters may be set via codec-control function later. |
| 206 cr->max_sbs_perframe = 10; | 205 cr->max_sbs_perframe = 10; |
| 207 cr->max_qdelta_perc = 50; | 206 cr->max_qdelta_perc = 50; |
| 208 cr->min_block_size = BLOCK_8X8; | 207 cr->min_block_size = BLOCK_8X8; |
| 209 cr->time_for_refresh = 1; | 208 cr->time_for_refresh = 1; |
| 210 // Set rate threshold to some fraction of target (and scaled by 256). | 209 // Set rate threshold to some fraction of target (and scaled by 256). |
| 211 cr->thresh_rate_sb = (rc->sb64_target_rate * 256) >> 2; | 210 cr->thresh_rate_sb = (rc->sb64_target_rate * 256) >> 2; |
| 212 // Distortion threshold, quadratic in Q, scale factor to be adjusted. | 211 // Distortion threshold, quadratic in Q, scale factor to be adjusted. |
| 213 cr->thresh_dist_sb = 8 * (int)(q * q); | 212 cr->thresh_dist_sb = 8 * (int)(q * q); |
| 214 if (cpi->sf.use_nonrd_pick_mode) { | 213 if (cpi->sf.use_nonrd_pick_mode) { |
| 215 // May want to be more conservative with thresholds in non-rd mode for now | 214 // May want to be more conservative with thresholds in non-rd mode for now |
| 216 // as rate/distortion are derived from model based on prediction residual. | 215 // as rate/distortion are derived from model based on prediction residual. |
| 217 cr->thresh_rate_sb = (rc->sb64_target_rate * 256) >> 3; | 216 cr->thresh_rate_sb = (rc->sb64_target_rate * 256); |
| 218 cr->thresh_dist_sb = 4 * (int)(q * q); | 217 cr->thresh_dist_sb = 16 * (int)(q * q); |
| 219 } | 218 } |
| 220 | 219 |
| 221 cr->num_seg_blocks = 0; | 220 cr->num_seg_blocks = 0; |
| 222 // Set up segmentation. | 221 // Set up segmentation. |
| 223 // Clear down the segment map. | 222 // Clear down the segment map. |
| 224 vpx_memset(seg_map, 0, cm->mi_rows * cm->mi_cols); | 223 vpx_memset(seg_map, 0, cm->mi_rows * cm->mi_cols); |
| 225 vp9_enable_segmentation(&cm->seg); | 224 vp9_enable_segmentation(&cm->seg); |
| 226 vp9_clearall_segfeatures(seg); | 225 vp9_clearall_segfeatures(seg); |
| 227 // Select delta coding method. | 226 // Select delta coding method. |
| 228 seg->abs_delta = SEGMENT_DELTADATA; | 227 seg->abs_delta = SEGMENT_DELTADATA; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 if (i == sbs_in_frame) { | 305 if (i == sbs_in_frame) { |
| 307 i = 0; | 306 i = 0; |
| 308 } | 307 } |
| 309 if (sum_map >= xmis * ymis /2) | 308 if (sum_map >= xmis * ymis /2) |
| 310 block_count--; | 309 block_count--; |
| 311 } while (block_count && i != cr->sb_index); | 310 } while (block_count && i != cr->sb_index); |
| 312 cr->sb_index = i; | 311 cr->sb_index = i; |
| 313 } | 312 } |
| 314 } | 313 } |
| 315 | 314 |
| 316 void vp9_cyclic_refresh_set_rate_and_dist_sb(CYCLIC_REFRESH *cr, | |
| 317 int64_t rate_sb, int64_t dist_sb) { | |
| 318 cr->projected_rate_sb = rate_sb; | |
| 319 cr->projected_dist_sb = dist_sb; | |
| 320 } | |
| 321 | |
| 322 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) { | 315 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) { |
| 323 return cr->rdmult; | 316 return cr->rdmult; |
| 324 } | 317 } |
| OLD | NEW |