| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 cost += segcounts[4] * vp9_cost_zero(probs[5]) + | 110 cost += segcounts[4] * vp9_cost_zero(probs[5]) + |
| 111 segcounts[5] * vp9_cost_one(probs[5]); | 111 segcounts[5] * vp9_cost_one(probs[5]); |
| 112 if (c67 > 0) | 112 if (c67 > 0) |
| 113 cost += segcounts[6] * vp9_cost_zero(probs[6]) + | 113 cost += segcounts[6] * vp9_cost_zero(probs[6]) + |
| 114 segcounts[7] * vp9_cost_one(probs[6]); | 114 segcounts[7] * vp9_cost_one(probs[6]); |
| 115 } | 115 } |
| 116 | 116 |
| 117 return cost; | 117 return cost; |
| 118 } | 118 } |
| 119 | 119 |
| 120 static void count_segs(VP9_COMP *cpi, MODE_INFO **mi_8x8, | 120 static void count_segs(VP9_COMP *cpi, const TileInfo *const tile, |
| 121 MODE_INFO **mi_8x8, |
| 121 int *no_pred_segcounts, | 122 int *no_pred_segcounts, |
| 122 int (*temporal_predictor_count)[2], | 123 int (*temporal_predictor_count)[2], |
| 123 int *t_unpred_seg_counts, | 124 int *t_unpred_seg_counts, |
| 124 int bw, int bh, int mi_row, int mi_col) { | 125 int bw, int bh, int mi_row, int mi_col) { |
| 125 VP9_COMMON *const cm = &cpi->common; | 126 VP9_COMMON *const cm = &cpi->common; |
| 126 MACROBLOCKD *const xd = &cpi->mb.e_mbd; | 127 MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
| 127 int segment_id; | 128 int segment_id; |
| 128 | 129 |
| 129 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) | 130 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
| 130 return; | 131 return; |
| 131 | 132 |
| 132 segment_id = mi_8x8[0]->mbmi.segment_id; | 133 xd->mi_8x8 = mi_8x8; |
| 134 segment_id = xd->mi_8x8[0]->mbmi.segment_id; |
| 133 | 135 |
| 134 set_mi_row_col(cm, xd, mi_row, bh, mi_col, bw); | 136 set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); |
| 135 | 137 |
| 136 // Count the number of hits on each segment with no prediction | 138 // Count the number of hits on each segment with no prediction |
| 137 no_pred_segcounts[segment_id]++; | 139 no_pred_segcounts[segment_id]++; |
| 138 | 140 |
| 139 // Temporal prediction not allowed on key frames | 141 // Temporal prediction not allowed on key frames |
| 140 if (cm->frame_type != KEY_FRAME) { | 142 if (cm->frame_type != KEY_FRAME) { |
| 141 const BLOCK_SIZE bsize = mi_8x8[0]->mbmi.sb_type; | 143 const BLOCK_SIZE bsize = mi_8x8[0]->mbmi.sb_type; |
| 142 // Test to see if the segment id matches the predicted value. | 144 // Test to see if the segment id matches the predicted value. |
| 143 const int pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map, | 145 const int pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map, |
| 144 bsize, mi_row, mi_col); | 146 bsize, mi_row, mi_col); |
| 145 const int pred_flag = pred_segment_id == segment_id; | 147 const int pred_flag = pred_segment_id == segment_id; |
| 146 const int pred_context = vp9_get_pred_context_seg_id(xd); | 148 const int pred_context = vp9_get_pred_context_seg_id(xd); |
| 147 | 149 |
| 148 // Store the prediction status for this mb and update counts | 150 // Store the prediction status for this mb and update counts |
| 149 // as appropriate | 151 // as appropriate |
| 150 vp9_set_pred_flag_seg_id(xd, pred_flag); | 152 vp9_set_pred_flag_seg_id(xd, pred_flag); |
| 151 temporal_predictor_count[pred_context][pred_flag]++; | 153 temporal_predictor_count[pred_context][pred_flag]++; |
| 152 | 154 |
| 153 if (!pred_flag) | 155 if (!pred_flag) |
| 154 // Update the "unpredicted" segment count | 156 // Update the "unpredicted" segment count |
| 155 t_unpred_seg_counts[segment_id]++; | 157 t_unpred_seg_counts[segment_id]++; |
| 156 } | 158 } |
| 157 } | 159 } |
| 158 | 160 |
| 159 static void count_segs_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, | 161 static void count_segs_sb(VP9_COMP *cpi, const TileInfo *const tile, |
| 162 MODE_INFO **mi_8x8, |
| 160 int *no_pred_segcounts, | 163 int *no_pred_segcounts, |
| 161 int (*temporal_predictor_count)[2], | 164 int (*temporal_predictor_count)[2], |
| 162 int *t_unpred_seg_counts, | 165 int *t_unpred_seg_counts, |
| 163 int mi_row, int mi_col, | 166 int mi_row, int mi_col, |
| 164 BLOCK_SIZE bsize) { | 167 BLOCK_SIZE bsize) { |
| 165 const VP9_COMMON *const cm = &cpi->common; | 168 const VP9_COMMON *const cm = &cpi->common; |
| 166 const int mis = cm->mode_info_stride; | 169 const int mis = cm->mode_info_stride; |
| 167 int bw, bh; | 170 int bw, bh; |
| 168 const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2; | 171 const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2; |
| 169 | 172 |
| 170 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) | 173 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
| 171 return; | 174 return; |
| 172 | 175 |
| 173 bw = num_8x8_blocks_wide_lookup[mi_8x8[0]->mbmi.sb_type]; | 176 bw = num_8x8_blocks_wide_lookup[mi_8x8[0]->mbmi.sb_type]; |
| 174 bh = num_8x8_blocks_high_lookup[mi_8x8[0]->mbmi.sb_type]; | 177 bh = num_8x8_blocks_high_lookup[mi_8x8[0]->mbmi.sb_type]; |
| 175 | 178 |
| 176 if (bw == bs && bh == bs) { | 179 if (bw == bs && bh == bs) { |
| 177 count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, | 180 count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count, |
| 178 t_unpred_seg_counts, bs, bs, mi_row, mi_col); | 181 t_unpred_seg_counts, bs, bs, mi_row, mi_col); |
| 179 } else if (bw == bs && bh < bs) { | 182 } else if (bw == bs && bh < bs) { |
| 180 count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, | 183 count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count, |
| 181 t_unpred_seg_counts, bs, hbs, mi_row, mi_col); | 184 t_unpred_seg_counts, bs, hbs, mi_row, mi_col); |
| 182 count_segs(cpi, mi_8x8 + hbs * mis, no_pred_segcounts, | 185 count_segs(cpi, tile, mi_8x8 + hbs * mis, no_pred_segcounts, |
| 183 temporal_predictor_count, t_unpred_seg_counts, bs, hbs, | 186 temporal_predictor_count, t_unpred_seg_counts, bs, hbs, |
| 184 mi_row + hbs, mi_col); | 187 mi_row + hbs, mi_col); |
| 185 } else if (bw < bs && bh == bs) { | 188 } else if (bw < bs && bh == bs) { |
| 186 count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, | 189 count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count, |
| 187 t_unpred_seg_counts, hbs, bs, mi_row, mi_col); | 190 t_unpred_seg_counts, hbs, bs, mi_row, mi_col); |
| 188 count_segs(cpi, mi_8x8 + hbs, no_pred_segcounts, temporal_predictor_count, | 191 count_segs(cpi, tile, mi_8x8 + hbs, |
| 189 t_unpred_seg_counts, hbs, bs, mi_row, mi_col + hbs); | 192 no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, |
| 193 hbs, bs, mi_row, mi_col + hbs); |
| 190 } else { | 194 } else { |
| 191 const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize]; | 195 const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize]; |
| 192 int n; | 196 int n; |
| 193 | 197 |
| 194 assert(bw < bs && bh < bs); | 198 assert(bw < bs && bh < bs); |
| 195 | 199 |
| 196 for (n = 0; n < 4; n++) { | 200 for (n = 0; n < 4; n++) { |
| 197 const int mi_dc = hbs * (n & 1); | 201 const int mi_dc = hbs * (n & 1); |
| 198 const int mi_dr = hbs * (n >> 1); | 202 const int mi_dr = hbs * (n >> 1); |
| 199 | 203 |
| 200 count_segs_sb(cpi, &mi_8x8[mi_dr * mis + mi_dc], | 204 count_segs_sb(cpi, tile, &mi_8x8[mi_dr * mis + mi_dc], |
| 201 no_pred_segcounts, temporal_predictor_count, | 205 no_pred_segcounts, temporal_predictor_count, |
| 202 t_unpred_seg_counts, | 206 t_unpred_seg_counts, |
| 203 mi_row + mi_dr, mi_col + mi_dc, subsize); | 207 mi_row + mi_dr, mi_col + mi_dc, subsize); |
| 204 } | 208 } |
| 205 } | 209 } |
| 206 } | 210 } |
| 207 | 211 |
| 208 void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { | 212 void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { |
| 209 VP9_COMMON *const cm = &cpi->common; | 213 VP9_COMMON *const cm = &cpi->common; |
| 210 struct segmentation *seg = &cm->seg; | 214 struct segmentation *seg = &cm->seg; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 226 MODE_INFO **mi_ptr, **mi; | 230 MODE_INFO **mi_ptr, **mi; |
| 227 | 231 |
| 228 // Set default state for the segment tree probabilities and the | 232 // Set default state for the segment tree probabilities and the |
| 229 // temporal coding probabilities | 233 // temporal coding probabilities |
| 230 vpx_memset(seg->tree_probs, 255, sizeof(seg->tree_probs)); | 234 vpx_memset(seg->tree_probs, 255, sizeof(seg->tree_probs)); |
| 231 vpx_memset(seg->pred_probs, 255, sizeof(seg->pred_probs)); | 235 vpx_memset(seg->pred_probs, 255, sizeof(seg->pred_probs)); |
| 232 | 236 |
| 233 // First of all generate stats regarding how well the last segment map | 237 // First of all generate stats regarding how well the last segment map |
| 234 // predicts this one | 238 // predicts this one |
| 235 for (tile_col = 0; tile_col < 1 << cm->log2_tile_cols; tile_col++) { | 239 for (tile_col = 0; tile_col < 1 << cm->log2_tile_cols; tile_col++) { |
| 236 vp9_get_tile_col_offsets(cm, tile_col); | 240 TileInfo tile; |
| 237 mi_ptr = cm->mi_grid_visible + cm->cur_tile_mi_col_start; | 241 |
| 242 vp9_tile_init(&tile, cm, 0, tile_col); |
| 243 mi_ptr = cm->mi_grid_visible + tile.mi_col_start; |
| 238 for (mi_row = 0; mi_row < cm->mi_rows; | 244 for (mi_row = 0; mi_row < cm->mi_rows; |
| 239 mi_row += 8, mi_ptr += 8 * mis) { | 245 mi_row += 8, mi_ptr += 8 * mis) { |
| 240 mi = mi_ptr; | 246 mi = mi_ptr; |
| 241 for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end; | 247 for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end; |
| 242 mi_col += 8, mi += 8) | 248 mi_col += 8, mi += 8) |
| 243 count_segs_sb(cpi, mi, no_pred_segcounts, temporal_predictor_count, | 249 count_segs_sb(cpi, &tile, mi, no_pred_segcounts, |
| 244 t_unpred_seg_counts, mi_row, mi_col, BLOCK_64X64); | 250 temporal_predictor_count, t_unpred_seg_counts, |
| 251 mi_row, mi_col, BLOCK_64X64); |
| 245 } | 252 } |
| 246 } | 253 } |
| 247 | 254 |
| 248 // Work out probability tree for coding segments without prediction | 255 // Work out probability tree for coding segments without prediction |
| 249 // and the cost. | 256 // and the cost. |
| 250 calc_segtree_probs(no_pred_segcounts, no_pred_tree); | 257 calc_segtree_probs(no_pred_segcounts, no_pred_tree); |
| 251 no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree); | 258 no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree); |
| 252 | 259 |
| 253 // Key frames cannot use temporal prediction | 260 // Key frames cannot use temporal prediction |
| 254 if (cm->frame_type != KEY_FRAME) { | 261 if (!frame_is_intra_only(cm)) { |
| 255 // Work out probability tree for coding those segments not | 262 // Work out probability tree for coding those segments not |
| 256 // predicted using the temporal method and the cost. | 263 // predicted using the temporal method and the cost. |
| 257 calc_segtree_probs(t_unpred_seg_counts, t_pred_tree); | 264 calc_segtree_probs(t_unpred_seg_counts, t_pred_tree); |
| 258 t_pred_cost = cost_segmap(t_unpred_seg_counts, t_pred_tree); | 265 t_pred_cost = cost_segmap(t_unpred_seg_counts, t_pred_tree); |
| 259 | 266 |
| 260 // Add in the cost of the signalling for each prediction context | 267 // Add in the cost of the signaling for each prediction context. |
| 261 for (i = 0; i < PREDICTION_PROBS; i++) { | 268 for (i = 0; i < PREDICTION_PROBS; i++) { |
| 262 const int count0 = temporal_predictor_count[i][0]; | 269 const int count0 = temporal_predictor_count[i][0]; |
| 263 const int count1 = temporal_predictor_count[i][1]; | 270 const int count1 = temporal_predictor_count[i][1]; |
| 264 | 271 |
| 265 t_nopred_prob[i] = get_binary_prob(count0, count1); | 272 t_nopred_prob[i] = get_binary_prob(count0, count1); |
| 266 | 273 |
| 267 // Add in the predictor signaling cost | 274 // Add in the predictor signaling cost |
| 268 t_pred_cost += count0 * vp9_cost_zero(t_nopred_prob[i]) + | 275 t_pred_cost += count0 * vp9_cost_zero(t_nopred_prob[i]) + |
| 269 count1 * vp9_cost_one(t_nopred_prob[i]); | 276 count1 * vp9_cost_one(t_nopred_prob[i]); |
| 270 } | 277 } |
| 271 } | 278 } |
| 272 | 279 |
| 273 // Now choose which coding method to use. | 280 // Now choose which coding method to use. |
| 274 if (t_pred_cost < no_pred_cost) { | 281 if (t_pred_cost < no_pred_cost) { |
| 275 seg->temporal_update = 1; | 282 seg->temporal_update = 1; |
| 276 vpx_memcpy(seg->tree_probs, t_pred_tree, sizeof(t_pred_tree)); | 283 vpx_memcpy(seg->tree_probs, t_pred_tree, sizeof(t_pred_tree)); |
| 277 vpx_memcpy(seg->pred_probs, t_nopred_prob, sizeof(t_nopred_prob)); | 284 vpx_memcpy(seg->pred_probs, t_nopred_prob, sizeof(t_nopred_prob)); |
| 278 } else { | 285 } else { |
| 279 seg->temporal_update = 0; | 286 seg->temporal_update = 0; |
| 280 vpx_memcpy(seg->tree_probs, no_pred_tree, sizeof(no_pred_tree)); | 287 vpx_memcpy(seg->tree_probs, no_pred_tree, sizeof(no_pred_tree)); |
| 281 } | 288 } |
| 282 } | 289 } |
| OLD | NEW |