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 |