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 #include <math.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <assert.h>
15 #include "onyx_int.h"
16 #include "tokenize.h"
17 #include "vpx_mem/vpx_mem.h"
18
19 /* Global event counters used for accumulating statistics across several
20 compressions, then generating context.c = initial stats. */
21
22 void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
23 void vp8_fix_contexts(MACROBLOCKD *x);
24
25 #include "dct_value_tokens.h"
26 #include "dct_value_cost.h"
27
28 const TOKENVALUE *const vp8_dct_value_tokens_ptr =
29 dct_value_tokens + DCT_MAX_VALUE;
30 const short *const vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
31
32 #if 0
33 int skip_true_count = 0;
34 int skip_false_count = 0;
35 #endif
36
37 /* function used to generate dct_value_tokens and dct_value_cost tables */
38 /*
39 static void fill_value_tokens()
40 {
41
42 TOKENVALUE *t = dct_value_tokens + DCT_MAX_VALUE;
43 const vp8_extra_bit_struct *e = vp8_extra_bits;
44
45 int i = -DCT_MAX_VALUE;
46 int sign = 1;
47
48 do
49 {
50 if (!i)
51 sign = 0;
52
53 {
54 const int a = sign ? -i : i;
55 int eb = sign;
56
57 if (a > 4)
58 {
59 int j = 4;
60
61 while (++j < 11 && e[j].base_val <= a) {}
62
63 t[i].Token = --j;
64 eb |= (a - e[j].base_val) << 1;
65 }
66 else
67 t[i].Token = a;
68
69 t[i].Extra = eb;
70 }
71
72 // initialize the cost for extra bits for all possible coefficient
73 value.
74 {
75 int cost = 0;
76 const vp8_extra_bit_struct *p = vp8_extra_bits + t[i].Token;
77
78 if (p->base_val)
79 {
80 const int extra = t[i].Extra;
81 const int Length = p->Len;
82
83 if (Length)
84 cost += vp8_treed_cost(p->tree, p->prob, extra >> 1,
85 Length);
86
87 cost += vp8_cost_bit(vp8_prob_half, extra & 1); // sign
88 dct_value_cost[i + DCT_MAX_VALUE] = cost;
89 }
90
91 }
92
93 }
94 while (++i < DCT_MAX_VALUE);
95
96 vp8_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
97 vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
98 }
99 */
100
tokenize2nd_order_b(MACROBLOCK * x,TOKENEXTRA ** tp,VP8_COMP * cpi)101 static void tokenize2nd_order_b(MACROBLOCK *x, TOKENEXTRA **tp, VP8_COMP *cpi) {
102 MACROBLOCKD *xd = &x->e_mbd;
103 int pt; /* near block/prev token context index */
104 int c; /* start at DC */
105 TOKENEXTRA *t = *tp; /* store tokens starting here */
106 const BLOCKD *b;
107 const short *qcoeff_ptr;
108 ENTROPY_CONTEXT *a;
109 ENTROPY_CONTEXT *l;
110 int band, rc, v, token;
111 int eob;
112
113 b = xd->block + 24;
114 qcoeff_ptr = b->qcoeff;
115 a = (ENTROPY_CONTEXT *)xd->above_context + 8;
116 l = (ENTROPY_CONTEXT *)xd->left_context + 8;
117 eob = xd->eobs[24];
118 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
119
120 if (!eob) {
121 /* c = band for this case */
122 t->Token = DCT_EOB_TOKEN;
123 t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
124 t->skip_eob_node = 0;
125
126 ++x->coef_counts[1][0][pt][DCT_EOB_TOKEN];
127 t++;
128 *tp = t;
129 *a = *l = 0;
130 return;
131 }
132
133 v = qcoeff_ptr[0];
134 t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
135 token = vp8_dct_value_tokens_ptr[v].Token;
136 t->Token = token;
137
138 t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
139 t->skip_eob_node = 0;
140 ++x->coef_counts[1][0][pt][token];
141 pt = vp8_prev_token_class[token];
142 t++;
143 c = 1;
144
145 for (; c < eob; ++c) {
146 rc = vp8_default_zig_zag1d[c];
147 band = vp8_coef_bands[c];
148 v = qcoeff_ptr[rc];
149
150 t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
151 token = vp8_dct_value_tokens_ptr[v].Token;
152
153 t->Token = token;
154 t->context_tree = cpi->common.fc.coef_probs[1][band][pt];
155
156 t->skip_eob_node = ((pt == 0));
157
158 ++x->coef_counts[1][band][pt][token];
159
160 pt = vp8_prev_token_class[token];
161 t++;
162 }
163 if (c < 16) {
164 band = vp8_coef_bands[c];
165 t->Token = DCT_EOB_TOKEN;
166 t->context_tree = cpi->common.fc.coef_probs[1][band][pt];
167
168 t->skip_eob_node = 0;
169
170 ++x->coef_counts[1][band][pt][DCT_EOB_TOKEN];
171
172 t++;
173 }
174
175 *tp = t;
176 *a = *l = 1;
177 }
178
tokenize1st_order_b(MACROBLOCK * x,TOKENEXTRA ** tp,int type,VP8_COMP * cpi)179 static void tokenize1st_order_b(
180 MACROBLOCK *x, TOKENEXTRA **tp,
181 int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
182 VP8_COMP *cpi) {
183 MACROBLOCKD *xd = &x->e_mbd;
184 unsigned int block;
185 const BLOCKD *b;
186 int pt; /* near block/prev token context index */
187 int c;
188 int token;
189 TOKENEXTRA *t = *tp; /* store tokens starting here */
190 const short *qcoeff_ptr;
191 ENTROPY_CONTEXT *a;
192 ENTROPY_CONTEXT *l;
193 int band, rc, v;
194 int tmp1, tmp2;
195
196 b = xd->block;
197 /* Luma */
198 for (block = 0; block < 16; block++, b++) {
199 const int eob = *b->eob;
200 tmp1 = vp8_block2above[block];
201 tmp2 = vp8_block2left[block];
202 qcoeff_ptr = b->qcoeff;
203 a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
204 l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
205
206 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
207
208 c = type ? 0 : 1;
209
210 if (c >= eob) {
211 /* c = band for this case */
212 t->Token = DCT_EOB_TOKEN;
213 t->context_tree = cpi->common.fc.coef_probs[type][c][pt];
214 t->skip_eob_node = 0;
215
216 ++x->coef_counts[type][c][pt][DCT_EOB_TOKEN];
217 t++;
218 *tp = t;
219 *a = *l = 0;
220 continue;
221 }
222
223 v = qcoeff_ptr[c];
224
225 t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
226 token = vp8_dct_value_tokens_ptr[v].Token;
227 t->Token = token;
228
229 t->context_tree = cpi->common.fc.coef_probs[type][c][pt];
230 t->skip_eob_node = 0;
231 ++x->coef_counts[type][c][pt][token];
232 pt = vp8_prev_token_class[token];
233 t++;
234 c++;
235
236 assert(eob <= 16);
237 for (; c < eob; ++c) {
238 rc = vp8_default_zig_zag1d[c];
239 band = vp8_coef_bands[c];
240 v = qcoeff_ptr[rc];
241
242 t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
243 token = vp8_dct_value_tokens_ptr[v].Token;
244
245 t->Token = token;
246 t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
247
248 t->skip_eob_node = (pt == 0);
249 ++x->coef_counts[type][band][pt][token];
250
251 pt = vp8_prev_token_class[token];
252 t++;
253 }
254 if (c < 16) {
255 band = vp8_coef_bands[c];
256 t->Token = DCT_EOB_TOKEN;
257 t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
258
259 t->skip_eob_node = 0;
260 ++x->coef_counts[type][band][pt][DCT_EOB_TOKEN];
261
262 t++;
263 }
264 *tp = t;
265 *a = *l = 1;
266 }
267
268 /* Chroma */
269 for (block = 16; block < 24; block++, b++) {
270 const int eob = *b->eob;
271 tmp1 = vp8_block2above[block];
272 tmp2 = vp8_block2left[block];
273 qcoeff_ptr = b->qcoeff;
274 a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
275 l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
276
277 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
278
279 if (!eob) {
280 /* c = band for this case */
281 t->Token = DCT_EOB_TOKEN;
282 t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
283 t->skip_eob_node = 0;
284
285 ++x->coef_counts[2][0][pt][DCT_EOB_TOKEN];
286 t++;
287 *tp = t;
288 *a = *l = 0;
289 continue;
290 }
291
292 v = qcoeff_ptr[0];
293
294 t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
295 token = vp8_dct_value_tokens_ptr[v].Token;
296 t->Token = token;
297
298 t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
299 t->skip_eob_node = 0;
300 ++x->coef_counts[2][0][pt][token];
301 pt = vp8_prev_token_class[token];
302 t++;
303 c = 1;
304
305 assert(eob <= 16);
306 for (; c < eob; ++c) {
307 rc = vp8_default_zig_zag1d[c];
308 band = vp8_coef_bands[c];
309 v = qcoeff_ptr[rc];
310
311 t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
312 token = vp8_dct_value_tokens_ptr[v].Token;
313
314 t->Token = token;
315 t->context_tree = cpi->common.fc.coef_probs[2][band][pt];
316
317 t->skip_eob_node = (pt == 0);
318
319 ++x->coef_counts[2][band][pt][token];
320
321 pt = vp8_prev_token_class[token];
322 t++;
323 }
324 if (c < 16) {
325 band = vp8_coef_bands[c];
326 t->Token = DCT_EOB_TOKEN;
327 t->context_tree = cpi->common.fc.coef_probs[2][band][pt];
328
329 t->skip_eob_node = 0;
330
331 ++x->coef_counts[2][band][pt][DCT_EOB_TOKEN];
332
333 t++;
334 }
335 *tp = t;
336 *a = *l = 1;
337 }
338 }
339
mb_is_skippable(MACROBLOCKD * x,int has_y2_block)340 static int mb_is_skippable(MACROBLOCKD *x, int has_y2_block) {
341 int skip = 1;
342 int i = 0;
343
344 if (has_y2_block) {
345 for (i = 0; i < 16; ++i) skip &= (x->eobs[i] < 2);
346 }
347
348 for (; i < 24 + has_y2_block; ++i) skip &= (!x->eobs[i]);
349
350 return skip;
351 }
352
vp8_tokenize_mb(VP8_COMP * cpi,MACROBLOCK * x,TOKENEXTRA ** t)353 void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) {
354 MACROBLOCKD *xd = &x->e_mbd;
355 int plane_type;
356 int has_y2_block;
357
358 has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED &&
359 xd->mode_info_context->mbmi.mode != SPLITMV);
360
361 xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable(xd, has_y2_block);
362 if (xd->mode_info_context->mbmi.mb_skip_coeff) {
363 if (!cpi->common.mb_no_coeff_skip) {
364 vp8_stuff_mb(cpi, x, t);
365 } else {
366 vp8_fix_contexts(xd);
367 x->skip_true_count++;
368 }
369
370 return;
371 }
372
373 plane_type = 3;
374 if (has_y2_block) {
375 tokenize2nd_order_b(x, t, cpi);
376 plane_type = 0;
377 }
378
379 tokenize1st_order_b(x, t, plane_type, cpi);
380 }
381
stuff2nd_order_b(TOKENEXTRA ** tp,ENTROPY_CONTEXT * a,ENTROPY_CONTEXT * l,VP8_COMP * cpi,MACROBLOCK * x)382 static void stuff2nd_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
383 ENTROPY_CONTEXT *l, VP8_COMP *cpi, MACROBLOCK *x) {
384 int pt; /* near block/prev token context index */
385 TOKENEXTRA *t = *tp; /* store tokens starting here */
386 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
387
388 t->Token = DCT_EOB_TOKEN;
389 t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
390 t->skip_eob_node = 0;
391 ++x->coef_counts[1][0][pt][DCT_EOB_TOKEN];
392 ++t;
393
394 *tp = t;
395 pt = 0;
396 *a = *l = pt;
397 }
398
stuff1st_order_b(TOKENEXTRA ** tp,ENTROPY_CONTEXT * a,ENTROPY_CONTEXT * l,int type,VP8_COMP * cpi,MACROBLOCK * x)399 static void stuff1st_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
400 ENTROPY_CONTEXT *l, int type, VP8_COMP *cpi,
401 MACROBLOCK *x) {
402 int pt; /* near block/prev token context index */
403 int band;
404 TOKENEXTRA *t = *tp; /* store tokens starting here */
405 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
406 band = type ? 0 : 1;
407 t->Token = DCT_EOB_TOKEN;
408 t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
409 t->skip_eob_node = 0;
410 ++x->coef_counts[type][band][pt][DCT_EOB_TOKEN];
411 ++t;
412 *tp = t;
413 pt = 0; /* 0 <-> all coeff data is zero */
414 *a = *l = pt;
415 }
416
stuff1st_order_buv(TOKENEXTRA ** tp,ENTROPY_CONTEXT * a,ENTROPY_CONTEXT * l,VP8_COMP * cpi,MACROBLOCK * x)417 static void stuff1st_order_buv(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
418 ENTROPY_CONTEXT *l, VP8_COMP *cpi,
419 MACROBLOCK *x) {
420 int pt; /* near block/prev token context index */
421 TOKENEXTRA *t = *tp; /* store tokens starting here */
422 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
423
424 t->Token = DCT_EOB_TOKEN;
425 t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
426 t->skip_eob_node = 0;
427 ++x->coef_counts[2][0][pt][DCT_EOB_TOKEN];
428 ++t;
429 *tp = t;
430 pt = 0; /* 0 <-> all coeff data is zero */
431 *a = *l = pt;
432 }
433
vp8_stuff_mb(VP8_COMP * cpi,MACROBLOCK * x,TOKENEXTRA ** t)434 void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) {
435 MACROBLOCKD *xd = &x->e_mbd;
436 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
437 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
438 int plane_type;
439 int b;
440 plane_type = 3;
441 if ((xd->mode_info_context->mbmi.mode != B_PRED &&
442 xd->mode_info_context->mbmi.mode != SPLITMV)) {
443 stuff2nd_order_b(t, A + vp8_block2above[24], L + vp8_block2left[24], cpi,
444 x);
445 plane_type = 0;
446 }
447
448 for (b = 0; b < 16; ++b) {
449 stuff1st_order_b(t, A + vp8_block2above[b], L + vp8_block2left[b],
450 plane_type, cpi, x);
451 }
452
453 for (b = 16; b < 24; ++b) {
454 stuff1st_order_buv(t, A + vp8_block2above[b], L + vp8_block2left[b], cpi,
455 x);
456 }
457 }
vp8_fix_contexts(MACROBLOCKD * x)458 void vp8_fix_contexts(MACROBLOCKD *x) {
459 /* Clear entropy contexts for Y2 blocks */
460 if (x->mode_info_context->mbmi.mode != B_PRED &&
461 x->mode_info_context->mbmi.mode != SPLITMV) {
462 memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
463 memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
464 } else {
465 memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
466 memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
467 }
468 }
469