Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(547)

Side by Side Diff: source/libvpx/vp9/encoder/vp9_tokenize.c

Issue 11555023: libvpx: Add VP9 decoder. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2010 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
12 #include <math.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <assert.h>
16 #include "vp9/encoder/vp9_onyx_int.h"
17 #include "vp9/encoder/vp9_tokenize.h"
18 #include "vpx_mem/vpx_mem.h"
19
20 #include "vp9/common/vp9_pred_common.h"
21 #include "vp9/common/vp9_seg_common.h"
22 #include "vp9/common/vp9_entropy.h"
23
24 /* Global event counters used for accumulating statistics across several
25 compressions, then generating vp9_context.c = initial stats. */
26
27 #ifdef ENTROPY_STATS
28 INT64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTRO PY_TOKENS];
29 INT64 hybrid_context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MA X_ENTROPY_TOKENS];
30
31 INT64 context_counters_8x8[BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [M AX_ENTROPY_TOKENS];
32 INT64 hybrid_context_counters_8x8[BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTE XTS] [MAX_ENTROPY_TOKENS];
33
34 INT64 context_counters_16x16[BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_CONTEXTS ] [MAX_ENTROPY_TOKENS];
35 INT64 hybrid_context_counters_16x16[BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_C ONTEXTS] [MAX_ENTROPY_TOKENS];
36
37 extern unsigned int tree_update_hist[BLOCK_TYPES][COEF_BANDS]
38 [PREV_COEF_CONTEXTS][ENTROPY_NODES][2];
39 extern unsigned int hybrid_tree_update_hist[BLOCK_TYPES][COEF_BANDS]
40 [PREV_COEF_CONTEXTS][ENTROPY_NODES][2];
41 extern unsigned int tree_update_hist_8x8[BLOCK_TYPES_8X8][COEF_BANDS]
42 [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2];
43 extern unsigned int hybrid_tree_update_hist_8x8[BLOCK_TYPES_8X8][COEF_BANDS]
44 [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2];
45 extern unsigned int tree_update_hist_16x16[BLOCK_TYPES_16X16][COEF_BANDS]
46 [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2];
47 extern unsigned int hybrid_tree_update_hist_16x16[BLOCK_TYPES_16X16][COEF_BANDS]
48 [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2];
49 #endif /* ENTROPY_STATS */
50
51 static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
52 const TOKENVALUE *vp9_dct_value_tokens_ptr;
53 static int dct_value_cost[DCT_MAX_VALUE * 2];
54 const int *vp9_dct_value_cost_ptr;
55
56 static void fill_value_tokens() {
57
58 TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE;
59 vp9_extra_bit_struct *const e = vp9_extra_bits;
60
61 int i = -DCT_MAX_VALUE;
62 int sign = 1;
63
64 do {
65 if (!i)
66 sign = 0;
67
68 {
69 const int a = sign ? -i : i;
70 int eb = sign;
71
72 if (a > 4) {
73 int j = 4;
74
75 while (++j < 11 && e[j].base_val <= a) {}
76
77 t[i].Token = --j;
78 eb |= (a - e[j].base_val) << 1;
79 } else
80 t[i].Token = a;
81
82 t[i].Extra = eb;
83 }
84
85 // initialize the cost for extra bits for all possible coefficient value.
86 {
87 int cost = 0;
88 vp9_extra_bit_struct *p = vp9_extra_bits + t[i].Token;
89
90 if (p->base_val) {
91 const int extra = t[i].Extra;
92 const int Length = p->Len;
93
94 if (Length)
95 cost += treed_cost(p->tree, p->prob, extra >> 1, Length);
96
97 cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */
98 dct_value_cost[i + DCT_MAX_VALUE] = cost;
99 }
100
101 }
102
103 } while (++i < DCT_MAX_VALUE);
104
105 vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
106 vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
107 }
108
109 static void tokenize_b(VP9_COMP *cpi,
110 MACROBLOCKD *xd,
111 const BLOCKD * const b,
112 TOKENEXTRA **tp,
113 PLANE_TYPE type,
114 ENTROPY_CONTEXT *a,
115 ENTROPY_CONTEXT *l,
116 TX_SIZE tx_size,
117 int dry_run) {
118 int pt; /* near block/prev token context index */
119 int c = (type == PLANE_TYPE_Y_NO_DC) ? 1 : 0;
120 const int eob = b->eob; /* one beyond last nonzero coeff */
121 TOKENEXTRA *t = *tp; /* store tokens starting here */
122 const short *qcoeff_ptr = b->qcoeff;
123 int seg_eob;
124 int segment_id = xd->mode_info_context->mbmi.segment_id;
125 const int *bands, *scan;
126 unsigned int (*counts)[COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
127 vp9_prob (*probs)[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
128 const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
129 get_tx_type(xd, b) : DCT_DCT;
130
131 VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
132 switch (tx_size) {
133 default:
134 case TX_4X4:
135 seg_eob = 16;
136 bands = vp9_coef_bands;
137 scan = vp9_default_zig_zag1d;
138 if (tx_type != DCT_DCT) {
139 counts = cpi->hybrid_coef_counts;
140 probs = cpi->common.fc.hybrid_coef_probs;
141 if (tx_type == ADST_DCT) {
142 scan = vp9_row_scan;
143 } else if (tx_type == DCT_ADST) {
144 scan = vp9_col_scan;
145 }
146 } else {
147 counts = cpi->coef_counts;
148 probs = cpi->common.fc.coef_probs;
149 }
150 break;
151 case TX_8X8:
152 if (type == PLANE_TYPE_Y2) {
153 seg_eob = 4;
154 bands = vp9_coef_bands;
155 scan = vp9_default_zig_zag1d;
156 } else {
157 seg_eob = 64;
158 bands = vp9_coef_bands_8x8;
159 scan = vp9_default_zig_zag1d_8x8;
160 }
161 if (tx_type != DCT_DCT) {
162 counts = cpi->hybrid_coef_counts_8x8;
163 probs = cpi->common.fc.hybrid_coef_probs_8x8;
164 } else {
165 counts = cpi->coef_counts_8x8;
166 probs = cpi->common.fc.coef_probs_8x8;
167 }
168 break;
169 case TX_16X16:
170 seg_eob = 256;
171 bands = vp9_coef_bands_16x16;
172 scan = vp9_default_zig_zag1d_16x16;
173 if (tx_type != DCT_DCT) {
174 counts = cpi->hybrid_coef_counts_16x16;
175 probs = cpi->common.fc.hybrid_coef_probs_16x16;
176 } else {
177 counts = cpi->coef_counts_16x16;
178 probs = cpi->common.fc.coef_probs_16x16;
179 }
180 break;
181 }
182
183 if (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB))
184 seg_eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB);
185
186 do {
187 const int band = bands[c];
188 int token;
189
190 if (c < eob) {
191 const int rc = scan[c];
192 const int v = qcoeff_ptr[rc];
193
194 assert(-DCT_MAX_VALUE <= v && v < DCT_MAX_VALUE);
195
196 t->Extra = vp9_dct_value_tokens_ptr[v].Extra;
197 token = vp9_dct_value_tokens_ptr[v].Token;
198 } else {
199 token = DCT_EOB_TOKEN;
200 }
201
202 t->Token = token;
203 t->context_tree = probs[type][band][pt];
204 t->skip_eob_node = (pt == 0) && ((band > 0 && type != PLANE_TYPE_Y_NO_DC) ||
205 (band > 1 && type == PLANE_TYPE_Y_NO_DC));
206 assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
207 if (!dry_run) {
208 ++counts[type][band][pt][token];
209 }
210 pt = vp9_prev_token_class[token];
211 ++t;
212 } while (c < eob && ++c < seg_eob);
213
214 *tp = t;
215 *a = *l = (c > !type); /* 0 <-> all coeff data is zero */
216 }
217
218 int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
219 int skip = 1;
220 int i = 0;
221
222 if (has_2nd_order) {
223 for (i = 0; i < 16; i++)
224 skip &= (xd->block[i].eob < 2);
225 skip &= (!xd->block[24].eob);
226 } else {
227 for (i = 0; i < 16; i++)
228 skip &= (!xd->block[i].eob);
229 }
230 return skip;
231 }
232
233 int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) {
234 int skip = 1;
235 int i;
236
237 for (i = 16; i < 24; i++)
238 skip &= (!xd->block[i].eob);
239 return skip;
240 }
241
242 static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
243 return (vp9_mby_is_skippable_4x4(xd, has_2nd_order) &
244 vp9_mbuv_is_skippable_4x4(xd));
245 }
246
247 int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
248 int skip = 1;
249 int i = 0;
250
251 if (has_2nd_order) {
252 for (i = 0; i < 16; i += 4)
253 skip &= (xd->block[i].eob < 2);
254 skip &= (!xd->block[24].eob);
255 } else {
256 for (i = 0; i < 16; i += 4)
257 skip &= (!xd->block[i].eob);
258 }
259 return skip;
260 }
261
262 int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) {
263 return (!xd->block[16].eob) & (!xd->block[20].eob);
264 }
265
266 static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
267 return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
268 vp9_mbuv_is_skippable_8x8(xd));
269 }
270
271 static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) {
272 return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
273 vp9_mbuv_is_skippable_4x4(xd));
274 }
275
276 int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) {
277 int skip = 1;
278 skip &= !xd->block[0].eob;
279 return skip;
280 }
281
282 static int mb_is_skippable_16x16(MACROBLOCKD *xd) {
283 return (vp9_mby_is_skippable_16x16(xd) & vp9_mbuv_is_skippable_8x8(xd));
284 }
285
286 void vp9_tokenize_mb(VP9_COMP *cpi,
287 MACROBLOCKD *xd,
288 TOKENEXTRA **t,
289 int dry_run) {
290 PLANE_TYPE plane_type;
291 int has_2nd_order;
292 int b;
293 int tx_size = xd->mode_info_context->mbmi.txfm_size;
294 int mb_skip_context = vp9_get_pred_context(&cpi->common, xd, PRED_MBSKIP);
295 TOKENEXTRA *t_backup = *t;
296 ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *) xd->above_context;
297 ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *) xd->left_context;
298
299 // If the MB is going to be skipped because of a segment level flag
300 // exclude this from the skip count stats used to calculate the
301 // transmitted skip probability;
302 int skip_inc;
303 int segment_id = xd->mode_info_context->mbmi.segment_id;
304
305 if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
306 (vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) != 0)) {
307 skip_inc = 1;
308 } else
309 skip_inc = 0;
310
311 has_2nd_order = get_2nd_order_usage(xd);
312
313 switch (tx_size) {
314 case TX_16X16:
315 xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd);
316 break;
317 case TX_8X8:
318 if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
319 xd->mode_info_context->mbmi.mode == SPLITMV)
320 xd->mode_info_context->mbmi.mb_skip_coeff =
321 mb_is_skippable_8x8_4x4uv(xd, 0);
322 else
323 xd->mode_info_context->mbmi.mb_skip_coeff =
324 mb_is_skippable_8x8(xd, has_2nd_order);
325 break;
326
327 default:
328 xd->mode_info_context->mbmi.mb_skip_coeff =
329 mb_is_skippable_4x4(xd, has_2nd_order);
330 break;
331 }
332
333 if (xd->mode_info_context->mbmi.mb_skip_coeff) {
334 if (!dry_run)
335 cpi->skip_true_count[mb_skip_context] += skip_inc;
336 if (!cpi->common.mb_no_coeff_skip) {
337 vp9_stuff_mb(cpi, xd, t, dry_run);
338 } else {
339 vp9_fix_contexts(xd);
340 }
341 if (dry_run)
342 *t = t_backup;
343 return;
344 }
345
346 if (!dry_run)
347 cpi->skip_false_count[mb_skip_context] += skip_inc;
348
349 if (has_2nd_order) {
350 if (tx_size == TX_8X8) {
351 tokenize_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2,
352 A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24],
353 TX_8X8, dry_run);
354 } else {
355 tokenize_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2,
356 A + vp9_block2above[24], L + vp9_block2left[24],
357 TX_4X4, dry_run);
358 }
359
360 plane_type = PLANE_TYPE_Y_NO_DC;
361 } else {
362 xd->above_context->y2 = 1;
363 xd->left_context->y2 = 1;
364 plane_type = PLANE_TYPE_Y_WITH_DC;
365 }
366
367 if (tx_size == TX_16X16) {
368 tokenize_b(cpi, xd, xd->block, t, PLANE_TYPE_Y_WITH_DC,
369 A, L, TX_16X16, dry_run);
370 A[1] = A[2] = A[3] = A[0];
371 L[1] = L[2] = L[3] = L[0];
372
373 for (b = 16; b < 24; b += 4) {
374 tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
375 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b],
376 TX_8X8, dry_run);
377 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
378 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]];
379 }
380 A[8] = 0;
381 L[8] = 0;
382 } else if (tx_size == TX_8X8) {
383 for (b = 0; b < 16; b += 4) {
384 tokenize_b(cpi, xd, xd->block + b, t, plane_type,
385 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b],
386 TX_8X8, dry_run);
387 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
388 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]];
389 }
390 if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
391 xd->mode_info_context->mbmi.mode == SPLITMV) {
392 for (b = 16; b < 24; b++) {
393 tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
394 A + vp9_block2above[b], L + vp9_block2left[b],
395 TX_4X4, dry_run);
396 }
397 } else {
398 for (b = 16; b < 24; b += 4) {
399 tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
400 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b],
401 TX_8X8, dry_run);
402 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
403 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]];
404 }
405 }
406 } else {
407 for (b = 0; b < 16; b++) {
408 tokenize_b(cpi, xd, xd->block + b, t, plane_type,
409 A + vp9_block2above[b], L + vp9_block2left[b],
410 TX_4X4, dry_run);
411 }
412
413 for (b = 16; b < 24; b++) {
414 tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
415 A + vp9_block2above[b], L + vp9_block2left[b],
416 TX_4X4, dry_run);
417 }
418 }
419 if (dry_run)
420 *t = t_backup;
421 }
422
423
424 #ifdef ENTROPY_STATS
425 void init_context_counters(void) {
426 FILE *f = fopen("context.bin", "rb");
427 if (!f) {
428 vpx_memset(context_counters, 0, sizeof(context_counters));
429 vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
430 vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16));
431 } else {
432 fread(context_counters, sizeof(context_counters), 1, f);
433 fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
434 fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
435 fclose(f);
436 }
437
438 f = fopen("treeupdate.bin", "rb");
439 if (!f) {
440 vpx_memset(tree_update_hist, 0, sizeof(tree_update_hist));
441 vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8));
442 vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16));
443 } else {
444 fread(tree_update_hist, sizeof(tree_update_hist), 1, f);
445 fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f);
446 fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f);
447 fclose(f);
448 }
449 }
450
451 void print_context_counters() {
452 int type, band, pt, t;
453 FILE *f = fopen("vp9_context.c", "w");
454
455 fprintf(f, "#include \"vp9_entropy.h\"\n");
456 fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");
457 fprintf(f, "static const unsigned int\n"
458 "vp9_default_coef_counts[BLOCK_TYPES]\n"
459 " [COEF_BANDS]\n"
460 " [PREV_COEF_CONTEXTS]\n"
461 " [MAX_ENTROPY_TOKENS]={\n");
462
463 # define Comma( X) (X? ",":"")
464 type = 0;
465 do {
466 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type);
467 band = 0;
468 do {
469 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band);
470 pt = 0;
471 do {
472 fprintf(f, "%s\n {", Comma(pt));
473
474 t = 0;
475 do {
476 const INT64 x = context_counters [type] [band] [pt] [t];
477 const int y = (int) x;
478 assert(x == (INT64) y); /* no overflow handling yet */
479 fprintf(f, "%s %d", Comma(t), y);
480 } while (++t < MAX_ENTROPY_TOKENS);
481 fprintf(f, "}");
482 } while (++pt < PREV_COEF_CONTEXTS);
483 fprintf(f, "\n }");
484 } while (++band < COEF_BANDS);
485 fprintf(f, "\n }");
486 } while (++type < BLOCK_TYPES);
487 fprintf(f, "\n};\n");
488
489 fprintf(f, "static const unsigned int\nvp9_default_coef_counts_8x8"
490 "[BLOCK_TYPES_8X8] [COEF_BANDS]"
491 "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {");
492 type = 0;
493 do {
494 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type);
495 band = 0;
496 do {
497 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band);
498 pt = 0;
499 do {
500 fprintf(f, "%s\n {", Comma(pt));
501 t = 0;
502 do {
503 const INT64 x = context_counters_8x8 [type] [band] [pt] [t];
504 const int y = (int) x;
505
506 assert(x == (INT64) y); /* no overflow handling yet */
507 fprintf(f, "%s %d", Comma(t), y);
508
509 } while (++t < MAX_ENTROPY_TOKENS);
510
511 fprintf(f, "}");
512 } while (++pt < PREV_COEF_CONTEXTS);
513
514 fprintf(f, "\n }");
515
516 } while (++band < COEF_BANDS);
517
518 fprintf(f, "\n }");
519 } while (++type < BLOCK_TYPES_8X8);
520 fprintf(f, "\n};\n");
521
522 fprintf(f, "static const unsigned int\nvp9_default_coef_counts_16x16"
523 "[BLOCK_TYPES_16X16] [COEF_BANDS]"
524 "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {");
525 type = 0;
526 do {
527 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type);
528 band = 0;
529 do {
530 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band);
531 pt = 0;
532 do {
533 fprintf(f, "%s\n {", Comma(pt));
534 t = 0;
535 do {
536 const INT64 x = context_counters_16x16 [type] [band] [pt] [t];
537 const int y = (int) x;
538
539 assert(x == (INT64) y); /* no overflow handling yet */
540 fprintf(f, "%s %d", Comma(t), y);
541
542 } while (++t < MAX_ENTROPY_TOKENS);
543
544 fprintf(f, "}");
545 } while (++pt < PREV_COEF_CONTEXTS);
546
547 fprintf(f, "\n }");
548
549 } while (++band < COEF_BANDS);
550
551 fprintf(f, "\n }");
552 } while (++type < BLOCK_TYPES_16X16);
553 fprintf(f, "\n};\n");
554
555 fprintf(f, "static const vp9_prob\n"
556 "vp9_default_coef_probs[BLOCK_TYPES] [COEF_BANDS] \n"
557 "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {");
558 type = 0;
559 do {
560 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type);
561 band = 0;
562 do {
563 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band);
564 pt = 0;
565 do {
566 unsigned int branch_ct [ENTROPY_NODES] [2];
567 unsigned int coef_counts[MAX_ENTROPY_TOKENS];
568 vp9_prob coef_probs[ENTROPY_NODES];
569 for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
570 coef_counts[t] = context_counters [type] [band] [pt] [t];
571 vp9_tree_probs_from_distribution(
572 MAX_ENTROPY_TOKENS, vp9_coef_encodings, vp9_coef_tree,
573 coef_probs, branch_ct, coef_counts, 256, 1);
574 fprintf(f, "%s\n {", Comma(pt));
575
576 t = 0;
577 do {
578 fprintf(f, "%s %d", Comma(t), coef_probs[t]);
579
580 } while (++t < ENTROPY_NODES);
581
582 fprintf(f, "}");
583 } while (++pt < PREV_COEF_CONTEXTS);
584 fprintf(f, "\n }");
585 } while (++band < COEF_BANDS);
586 fprintf(f, "\n }");
587 } while (++type < BLOCK_TYPES);
588 fprintf(f, "\n};\n");
589
590 fprintf(f, "static const vp9_prob\n"
591 "vp9_default_coef_probs_8x8[BLOCK_TYPES_8X8] [COEF_BANDS]\n"
592 "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {");
593 type = 0;
594 do {
595 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type);
596 band = 0;
597 do {
598 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band);
599 pt = 0;
600 do {
601 unsigned int branch_ct [ENTROPY_NODES] [2];
602 unsigned int coef_counts[MAX_ENTROPY_TOKENS];
603 vp9_prob coef_probs[ENTROPY_NODES];
604 for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
605 coef_counts[t] = context_counters_8x8[type] [band] [pt] [t];
606 vp9_tree_probs_from_distribution(
607 MAX_ENTROPY_TOKENS, vp9_coef_encodings, vp9_coef_tree,
608 coef_probs, branch_ct, coef_counts, 256, 1);
609 fprintf(f, "%s\n {", Comma(pt));
610
611 t = 0;
612 do {
613 fprintf(f, "%s %d", Comma(t), coef_probs[t]);
614 } while (++t < ENTROPY_NODES);
615 fprintf(f, "}");
616 } while (++pt < PREV_COEF_CONTEXTS);
617 fprintf(f, "\n }");
618 } while (++band < COEF_BANDS);
619 fprintf(f, "\n }");
620 } while (++type < BLOCK_TYPES_8X8);
621 fprintf(f, "\n};\n");
622
623 fprintf(f, "static const vp9_prob\n"
624 "vp9_default_coef_probs_16x16[BLOCK_TYPES_16X16] [COEF_BANDS]\n"
625 "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {");
626 type = 0;
627 do {
628 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type);
629 band = 0;
630 do {
631 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band);
632 pt = 0;
633 do {
634 unsigned int branch_ct [ENTROPY_NODES] [2];
635 unsigned int coef_counts[MAX_ENTROPY_TOKENS];
636 vp9_prob coef_probs[ENTROPY_NODES];
637 for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
638 coef_counts[t] = context_counters_16x16[type] [band] [pt] [t];
639 vp9_tree_probs_from_distribution(
640 MAX_ENTROPY_TOKENS, vp9_coef_encodings, vp9_coef_tree,
641 coef_probs, branch_ct, coef_counts, 256, 1);
642 fprintf(f, "%s\n {", Comma(pt));
643
644 t = 0;
645 do {
646 fprintf(f, "%s %d", Comma(t), coef_probs[t]);
647 } while (++t < ENTROPY_NODES);
648 fprintf(f, "}");
649 } while (++pt < PREV_COEF_CONTEXTS);
650 fprintf(f, "\n }");
651 } while (++band < COEF_BANDS);
652 fprintf(f, "\n }");
653 } while (++type < BLOCK_TYPES_16X16);
654 fprintf(f, "\n};\n");
655
656 fclose(f);
657
658 f = fopen("context.bin", "wb");
659 fwrite(context_counters, sizeof(context_counters), 1, f);
660 fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
661 fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
662 fclose(f);
663 }
664 #endif
665
666 void vp9_tokenize_initialize() {
667 fill_value_tokens();
668 }
669
670 static __inline void stuff_b(VP9_COMP *cpi,
671 MACROBLOCKD *xd,
672 const BLOCKD * const b,
673 TOKENEXTRA **tp,
674 PLANE_TYPE type,
675 ENTROPY_CONTEXT *a,
676 ENTROPY_CONTEXT *l,
677 TX_SIZE tx_size,
678 int dry_run) {
679 const int *bands;
680 unsigned int (*counts)[COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
681 vp9_prob (*probs)[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
682 int pt, band;
683 TOKENEXTRA *t = *tp;
684 const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
685 get_tx_type(xd, b) : DCT_DCT;
686 VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
687
688 switch (tx_size) {
689 default:
690 case TX_4X4:
691 bands = vp9_coef_bands;
692 if (tx_type != DCT_DCT) {
693 counts = cpi->hybrid_coef_counts;
694 probs = cpi->common.fc.hybrid_coef_probs;
695 } else {
696 counts = cpi->coef_counts;
697 probs = cpi->common.fc.coef_probs;
698 }
699 break;
700 case TX_8X8:
701 bands = vp9_coef_bands_8x8;
702 if (tx_type != DCT_DCT) {
703 counts = cpi->hybrid_coef_counts_8x8;
704 probs = cpi->common.fc.hybrid_coef_probs_8x8;
705 } else {
706 counts = cpi->coef_counts_8x8;
707 probs = cpi->common.fc.coef_probs_8x8;
708 }
709 break;
710 case TX_16X16:
711 bands = vp9_coef_bands_16x16;
712 if (tx_type != DCT_DCT) {
713 counts = cpi->hybrid_coef_counts_16x16;
714 probs = cpi->common.fc.hybrid_coef_probs_16x16;
715 } else {
716 counts = cpi->coef_counts_16x16;
717 probs = cpi->common.fc.coef_probs_16x16;
718 }
719 break;
720 }
721 band = bands[(type == PLANE_TYPE_Y_NO_DC) ? 1 : 0];
722 t->Token = DCT_EOB_TOKEN;
723 t->context_tree = probs[type][band][pt];
724 t->skip_eob_node = 0;
725 ++t;
726 *tp = t;
727 *a = *l = 0;
728 if (!dry_run) {
729 ++counts[type][band][pt][DCT_EOB_TOKEN];
730 }
731 }
732
733 static void stuff_mb_8x8(VP9_COMP *cpi, MACROBLOCKD *xd,
734 TOKENEXTRA **t, int dry_run) {
735 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
736 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
737 PLANE_TYPE plane_type;
738 int b;
739 int has_2nd_order = get_2nd_order_usage(xd);
740
741 if (has_2nd_order) {
742 stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2,
743 A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24],
744 TX_8X8, dry_run);
745 plane_type = PLANE_TYPE_Y_NO_DC;
746 } else {
747 xd->above_context->y2 = 1;
748 xd->left_context->y2 = 1;
749 plane_type = PLANE_TYPE_Y_WITH_DC;
750 }
751
752 for (b = 0; b < 16; b += 4) {
753 stuff_b(cpi, xd, xd->block + b, t, plane_type, A + vp9_block2above_8x8[b],
754 L + vp9_block2left_8x8[b], TX_8X8, dry_run);
755 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
756 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]];
757 }
758
759 for (b = 16; b < 24; b += 4) {
760 stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
761 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b],
762 TX_8X8, dry_run);
763 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
764 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]];
765 }
766 }
767
768 static void stuff_mb_16x16(VP9_COMP *cpi, MACROBLOCKD *xd,
769 TOKENEXTRA **t, int dry_run) {
770 ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)xd->above_context;
771 ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)xd->left_context;
772 int b;
773
774 stuff_b(cpi, xd, xd->block, t, PLANE_TYPE_Y_WITH_DC, A, L, TX_16X16, dry_run);
775 A[1] = A[2] = A[3] = A[0];
776 L[1] = L[2] = L[3] = L[0];
777 for (b = 16; b < 24; b += 4) {
778 stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, A + vp9_block2above[b],
779 L + vp9_block2above_8x8[b], TX_8X8, dry_run);
780 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
781 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]];
782 }
783 vpx_memset(&A[8], 0, sizeof(A[8]));
784 vpx_memset(&L[8], 0, sizeof(L[8]));
785 }
786
787 static void stuff_mb_4x4(VP9_COMP *cpi, MACROBLOCKD *xd,
788 TOKENEXTRA **t, int dry_run) {
789 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
790 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
791 int b;
792 PLANE_TYPE plane_type;
793 int has_2nd_order = (xd->mode_info_context->mbmi.mode != B_PRED &&
794 xd->mode_info_context->mbmi.mode != I8X8_PRED &&
795 xd->mode_info_context->mbmi.mode != SPLITMV);
796 if (has_2nd_order && get_tx_type(xd, &xd->block[0]) != DCT_DCT)
797 has_2nd_order = 0;
798
799 if (has_2nd_order) {
800 stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2, A + vp9_block2above[24],
801 L + vp9_block2left[24], TX_4X4, dry_run);
802 plane_type = PLANE_TYPE_Y_NO_DC;
803 } else {
804 xd->above_context->y2 = 1;
805 xd->left_context->y2 = 1;
806 plane_type = PLANE_TYPE_Y_WITH_DC;
807 }
808
809 for (b = 0; b < 16; b++)
810 stuff_b(cpi, xd, xd->block + b, t, plane_type, A + vp9_block2above[b],
811 L + vp9_block2left[b], TX_4X4, dry_run);
812
813 for (b = 16; b < 24; b++)
814 stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, A + vp9_block2above[b],
815 L + vp9_block2left[b], TX_4X4, dry_run);
816 }
817
818 static void stuff_mb_8x8_4x4uv(VP9_COMP *cpi, MACROBLOCKD *xd,
819 TOKENEXTRA **t, int dry_run) {
820 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
821 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
822 PLANE_TYPE plane_type;
823 int b;
824
825 int has_2nd_order = get_2nd_order_usage(xd);
826 if (has_2nd_order) {
827 stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2,
828 A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24],
829 TX_8X8, dry_run);
830 plane_type = PLANE_TYPE_Y_NO_DC;
831 } else {
832 plane_type = PLANE_TYPE_Y_WITH_DC;
833 }
834
835 for (b = 0; b < 16; b += 4) {
836 stuff_b(cpi, xd, xd->block + b, t, plane_type,
837 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b],
838 TX_8X8, dry_run);
839 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
840 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]];
841 }
842
843 for (b = 16; b < 24; b++)
844 stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, A + vp9_block2above[b],
845 L + vp9_block2left[b], TX_4X4, dry_run);
846 xd->above_context->y2 = 1;
847 xd->left_context->y2 = 1;
848 }
849
850 void vp9_stuff_mb(VP9_COMP *cpi, MACROBLOCKD *xd, TOKENEXTRA **t, int dry_run) {
851 TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
852 TOKENEXTRA * const t_backup = *t;
853
854 if (tx_size == TX_16X16) {
855 stuff_mb_16x16(cpi, xd, t, dry_run);
856 } else if (tx_size == TX_8X8) {
857 if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
858 xd->mode_info_context->mbmi.mode == SPLITMV) {
859 stuff_mb_8x8_4x4uv(cpi, xd, t, dry_run);
860 } else {
861 stuff_mb_8x8(cpi, xd, t, dry_run);
862 }
863 } else {
864 stuff_mb_4x4(cpi, xd, t, dry_run);
865 }
866
867 if (dry_run) {
868 *t = t_backup;
869 }
870 }
871
872 void vp9_fix_contexts(MACROBLOCKD *xd) {
873 /* Clear entropy contexts for blocks */
874 if ((xd->mode_info_context->mbmi.mode != B_PRED
875 && xd->mode_info_context->mbmi.mode != I8X8_PRED
876 && xd->mode_info_context->mbmi.mode != SPLITMV)
877 || xd->mode_info_context->mbmi.txfm_size == TX_16X16
878 ) {
879 vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
880 vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
881 } else {
882 vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
883 vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
884 xd->above_context->y2 = 1;
885 xd->left_context->y2 = 1;
886 }
887 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698