OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } while (++i < DCT_MAX_VALUE); | 153 } while (++i < DCT_MAX_VALUE); |
154 | 154 |
155 vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE; | 155 vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE; |
156 vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; | 156 vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; |
157 } | 157 } |
158 | 158 |
159 struct tokenize_b_args { | 159 struct tokenize_b_args { |
160 VP9_COMP *cpi; | 160 VP9_COMP *cpi; |
161 MACROBLOCKD *xd; | 161 MACROBLOCKD *xd; |
162 TOKENEXTRA **tp; | 162 TOKENEXTRA **tp; |
163 TX_SIZE tx_size; | |
164 uint8_t *token_cache; | 163 uint8_t *token_cache; |
165 }; | 164 }; |
166 | 165 |
167 static void set_entropy_context_b(int plane, int block, BLOCK_SIZE plane_bsize, | 166 static void set_entropy_context_b(int plane, int block, BLOCK_SIZE plane_bsize, |
168 TX_SIZE tx_size, void *arg) { | 167 TX_SIZE tx_size, void *arg) { |
169 struct tokenize_b_args* const args = arg; | 168 struct tokenize_b_args* const args = arg; |
170 MACROBLOCKD *const xd = args->xd; | 169 MACROBLOCKD *const xd = args->xd; |
171 struct macroblock_plane *p = &args->cpi->mb.plane[plane]; | 170 struct macroblock_plane *p = &args->cpi->mb.plane[plane]; |
172 struct macroblockd_plane *pd = &xd->plane[plane]; | 171 struct macroblockd_plane *pd = &xd->plane[plane]; |
173 int aoff, loff; | 172 int aoff, loff; |
174 txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff); | 173 txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff); |
175 set_contexts(xd, pd, plane_bsize, tx_size, p->eobs[block] > 0, aoff, loff); | 174 vp9_set_contexts(xd, pd, plane_bsize, tx_size, p->eobs[block] > 0, |
| 175 aoff, loff); |
176 } | 176 } |
177 | 177 |
178 static INLINE void add_token(TOKENEXTRA **t, const vp9_prob *context_tree, | 178 static INLINE void add_token(TOKENEXTRA **t, const vp9_prob *context_tree, |
179 int16_t extra, uint8_t token, | 179 int16_t extra, uint8_t token, |
180 uint8_t skip_eob_node, | 180 uint8_t skip_eob_node, |
181 unsigned int *counts) { | 181 unsigned int *counts) { |
182 (*t)->token = token; | 182 (*t)->token = token; |
183 (*t)->extra = extra; | 183 (*t)->extra = extra; |
184 (*t)->context_tree = context_tree; | 184 (*t)->context_tree = context_tree; |
185 (*t)->skip_eob_node = skip_eob_node; | 185 (*t)->skip_eob_node = skip_eob_node; |
186 (*t)++; | 186 (*t)++; |
187 ++counts[token]; | 187 ++counts[token]; |
188 } | 188 } |
189 | 189 |
| 190 static INLINE void add_token_no_extra(TOKENEXTRA **t, |
| 191 const vp9_prob *context_tree, |
| 192 uint8_t token, |
| 193 uint8_t skip_eob_node, |
| 194 unsigned int *counts) { |
| 195 (*t)->token = token; |
| 196 (*t)->context_tree = context_tree; |
| 197 (*t)->skip_eob_node = skip_eob_node; |
| 198 (*t)++; |
| 199 ++counts[token]; |
| 200 } |
| 201 |
190 static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize, | 202 static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize, |
191 TX_SIZE tx_size, void *arg) { | 203 TX_SIZE tx_size, void *arg) { |
192 struct tokenize_b_args* const args = arg; | 204 struct tokenize_b_args* const args = arg; |
193 VP9_COMP *cpi = args->cpi; | 205 VP9_COMP *cpi = args->cpi; |
194 MACROBLOCKD *xd = args->xd; | 206 MACROBLOCKD *xd = args->xd; |
195 TOKENEXTRA **tp = args->tp; | 207 TOKENEXTRA **tp = args->tp; |
196 uint8_t *token_cache = args->token_cache; | 208 uint8_t *token_cache = args->token_cache; |
197 struct macroblock_plane *p = &cpi->mb.plane[plane]; | 209 struct macroblock_plane *p = &cpi->mb.plane[plane]; |
198 struct macroblockd_plane *pd = &xd->plane[plane]; | 210 struct macroblockd_plane *pd = &xd->plane[plane]; |
199 MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; | 211 MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
200 int pt; /* near block/prev token context index */ | 212 int pt; /* near block/prev token context index */ |
201 int c = 0; | 213 int c; |
202 TOKENEXTRA *t = *tp; /* store tokens starting here */ | 214 TOKENEXTRA *t = *tp; /* store tokens starting here */ |
203 int eob = p->eobs[block]; | 215 int eob = p->eobs[block]; |
204 const PLANE_TYPE type = pd->plane_type; | 216 const PLANE_TYPE type = pd->plane_type; |
205 const int16_t *qcoeff_ptr = BLOCK_OFFSET(p->qcoeff, block); | 217 const int16_t *qcoeff_ptr = BLOCK_OFFSET(p->qcoeff, block); |
206 const int segment_id = mbmi->segment_id; | 218 const int segment_id = mbmi->segment_id; |
207 const int16_t *scan, *nb; | 219 const int16_t *scan, *nb; |
208 const scan_order *so; | 220 const scan_order *so; |
209 vp9_coeff_count *const counts = cpi->coef_counts[tx_size]; | |
210 vp9_coeff_probs_model *const coef_probs = cpi->common.fc.coef_probs[tx_size]; | |
211 const int ref = is_inter_block(mbmi); | 221 const int ref = is_inter_block(mbmi); |
| 222 unsigned int (*const counts)[COEFF_CONTEXTS][ENTROPY_TOKENS] = |
| 223 cpi->coef_counts[tx_size][type][ref]; |
| 224 vp9_prob (*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] = |
| 225 cpi->common.fc.coef_probs[tx_size][type][ref]; |
| 226 unsigned int (*const eob_branch)[COEFF_CONTEXTS] = |
| 227 cpi->common.counts.eob_branch[tx_size][type][ref]; |
| 228 |
212 const uint8_t *const band = get_band_translate(tx_size); | 229 const uint8_t *const band = get_band_translate(tx_size); |
213 const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size); | 230 const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size); |
214 | 231 |
215 int aoff, loff; | 232 int aoff, loff; |
216 txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff); | 233 txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff); |
217 | 234 |
218 pt = get_entropy_context(tx_size, pd->above_context + aoff, | 235 pt = get_entropy_context(tx_size, pd->above_context + aoff, |
219 pd->left_context + loff); | 236 pd->left_context + loff); |
220 so = get_scan(xd, tx_size, type, block); | 237 so = get_scan(xd, tx_size, type, block); |
221 scan = so->scan; | 238 scan = so->scan; |
222 nb = so->neighbors; | 239 nb = so->neighbors; |
223 c = 0; | 240 c = 0; |
224 while (c < eob) { | 241 while (c < eob) { |
225 int v = 0; | 242 int v = 0; |
226 int skip_eob = 0; | 243 int skip_eob = 0; |
227 v = qcoeff_ptr[scan[c]]; | 244 v = qcoeff_ptr[scan[c]]; |
228 | 245 |
229 while (!v) { | 246 while (!v) { |
230 add_token(&t, coef_probs[type][ref][band[c]][pt], 0, ZERO_TOKEN, skip_eob, | 247 add_token_no_extra(&t, coef_probs[band[c]][pt], ZERO_TOKEN, skip_eob, |
231 counts[type][ref][band[c]][pt]); | 248 counts[band[c]][pt]); |
232 | 249 eob_branch[band[c]][pt] += !skip_eob; |
233 cpi->common.counts.eob_branch[tx_size][type][ref][band[c]][pt] += | |
234 !skip_eob; | |
235 | 250 |
236 skip_eob = 1; | 251 skip_eob = 1; |
237 token_cache[scan[c]] = 0; | 252 token_cache[scan[c]] = 0; |
238 ++c; | 253 ++c; |
239 pt = get_coef_context(nb, token_cache, c); | 254 pt = get_coef_context(nb, token_cache, c); |
240 v = qcoeff_ptr[scan[c]]; | 255 v = qcoeff_ptr[scan[c]]; |
241 } | 256 } |
242 add_token(&t, coef_probs[type][ref][band[c]][pt], | 257 |
| 258 add_token(&t, coef_probs[band[c]][pt], |
243 vp9_dct_value_tokens_ptr[v].extra, | 259 vp9_dct_value_tokens_ptr[v].extra, |
244 vp9_dct_value_tokens_ptr[v].token, skip_eob, | 260 vp9_dct_value_tokens_ptr[v].token, skip_eob, |
245 counts[type][ref][band[c]][pt]); | 261 counts[band[c]][pt]); |
246 | 262 eob_branch[band[c]][pt] += !skip_eob; |
247 cpi->common.counts.eob_branch[tx_size][type][ref][band[c]][pt] += !skip_eob; | |
248 | 263 |
249 token_cache[scan[c]] = | 264 token_cache[scan[c]] = |
250 vp9_pt_energy_class[vp9_dct_value_tokens_ptr[v].token]; | 265 vp9_pt_energy_class[vp9_dct_value_tokens_ptr[v].token]; |
251 ++c; | 266 ++c; |
252 pt = get_coef_context(nb, token_cache, c); | 267 pt = get_coef_context(nb, token_cache, c); |
253 } | 268 } |
254 if (c < seg_eob) { | 269 if (c < seg_eob) { |
255 add_token(&t, coef_probs[type][ref][band[c]][pt], 0, EOB_TOKEN, 0, | 270 add_token_no_extra(&t, coef_probs[band[c]][pt], EOB_TOKEN, 0, |
256 counts[type][ref][band[c]][pt]); | 271 counts[band[c]][pt]); |
257 ++cpi->common.counts.eob_branch[tx_size][type][ref][band[c]][pt]; | 272 ++eob_branch[band[c]][pt]; |
258 } | 273 } |
259 | 274 |
260 *tp = t; | 275 *tp = t; |
261 | 276 |
262 set_contexts(xd, pd, plane_bsize, tx_size, c > 0, aoff, loff); | 277 vp9_set_contexts(xd, pd, plane_bsize, tx_size, c > 0, aoff, loff); |
263 } | 278 } |
264 | 279 |
265 struct is_skippable_args { | 280 struct is_skippable_args { |
266 MACROBLOCK *x; | 281 MACROBLOCK *x; |
267 int *skippable; | 282 int *skippable; |
268 }; | 283 }; |
269 | 284 |
270 static void is_skippable(int plane, int block, | 285 static void is_skippable(int plane, int block, |
271 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, | 286 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, |
272 void *argv) { | 287 void *argv) { |
273 struct is_skippable_args *args = argv; | 288 struct is_skippable_args *args = argv; |
274 args->skippable[0] &= (!args->x->plane[plane].eobs[block]); | 289 args->skippable[0] &= (!args->x->plane[plane].eobs[block]); |
275 } | 290 } |
276 | 291 |
277 static int sb_is_skippable(MACROBLOCK *x, BLOCK_SIZE bsize) { | 292 static int sb_is_skippable(MACROBLOCK *x, BLOCK_SIZE bsize) { |
278 int result = 1; | 293 int result = 1; |
279 struct is_skippable_args args = {x, &result}; | 294 struct is_skippable_args args = {x, &result}; |
280 foreach_transformed_block(&x->e_mbd, bsize, is_skippable, &args); | 295 vp9_foreach_transformed_block(&x->e_mbd, bsize, is_skippable, &args); |
281 return result; | 296 return result; |
282 } | 297 } |
283 | 298 |
284 int vp9_is_skippable_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) { | 299 int vp9_is_skippable_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) { |
285 int result = 1; | 300 int result = 1; |
286 struct is_skippable_args args = {x, &result}; | 301 struct is_skippable_args args = {x, &result}; |
287 foreach_transformed_block_in_plane(&x->e_mbd, bsize, plane, is_skippable, | 302 vp9_foreach_transformed_block_in_plane(&x->e_mbd, bsize, plane, is_skippable, |
288 &args); | 303 &args); |
289 return result; | 304 return result; |
290 } | 305 } |
291 | 306 |
292 void vp9_tokenize_sb(VP9_COMP *cpi, TOKENEXTRA **t, int dry_run, | 307 void vp9_tokenize_sb(VP9_COMP *cpi, TOKENEXTRA **t, int dry_run, |
293 BLOCK_SIZE bsize) { | 308 BLOCK_SIZE bsize) { |
294 VP9_COMMON *const cm = &cpi->common; | 309 VP9_COMMON *const cm = &cpi->common; |
295 MACROBLOCKD *const xd = &cpi->mb.e_mbd; | 310 MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
296 MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; | 311 MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
297 TOKENEXTRA *t_backup = *t; | 312 TOKENEXTRA *t_backup = *t; |
298 const int ctx = vp9_get_skip_context(xd); | 313 const int ctx = vp9_get_skip_context(xd); |
299 const int skip_inc = !vp9_segfeature_active(&cm->seg, mbmi->segment_id, | 314 const int skip_inc = !vp9_segfeature_active(&cm->seg, mbmi->segment_id, |
300 SEG_LVL_SKIP); | 315 SEG_LVL_SKIP); |
301 struct tokenize_b_args arg = {cpi, xd, t, mbmi->tx_size, cpi->mb.token_cache}; | 316 struct tokenize_b_args arg = {cpi, xd, t, cpi->mb.token_cache}; |
302 if (mbmi->skip_coeff) { | 317 if (mbmi->skip) { |
303 if (!dry_run) | 318 if (!dry_run) |
304 cm->counts.mbskip[ctx][1] += skip_inc; | 319 cm->counts.skip[ctx][1] += skip_inc; |
305 reset_skip_context(xd, bsize); | 320 reset_skip_context(xd, bsize); |
306 if (dry_run) | 321 if (dry_run) |
307 *t = t_backup; | 322 *t = t_backup; |
308 return; | 323 return; |
309 } | 324 } |
310 | 325 |
311 if (!dry_run) { | 326 if (!dry_run) { |
312 cm->counts.mbskip[ctx][0] += skip_inc; | 327 cm->counts.skip[ctx][0] += skip_inc; |
313 foreach_transformed_block(xd, bsize, tokenize_b, &arg); | 328 vp9_foreach_transformed_block(xd, bsize, tokenize_b, &arg); |
314 } else { | 329 } else { |
315 foreach_transformed_block(xd, bsize, set_entropy_context_b, &arg); | 330 vp9_foreach_transformed_block(xd, bsize, set_entropy_context_b, &arg); |
316 *t = t_backup; | 331 *t = t_backup; |
317 } | 332 } |
318 } | 333 } |
319 | 334 |
320 void vp9_tokenize_initialize() { | 335 void vp9_tokenize_initialize() { |
321 fill_value_tokens(); | 336 fill_value_tokens(); |
322 } | 337 } |
OLD | NEW |