/src/libvpx/vp8/decoder/detokenize.c
Line | Count | Source |
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 "vp8/common/blockd.h" |
12 | | #include "onyxd_int.h" |
13 | | #include "vpx_mem/vpx_mem.h" |
14 | | #include "vpx_ports/compiler_attributes.h" |
15 | | #include "vpx_ports/mem.h" |
16 | | #include "detokenize.h" |
17 | | |
18 | 9.64M | void vp8_reset_mb_tokens_context(MACROBLOCKD *x) { |
19 | 9.64M | ENTROPY_CONTEXT *a_ctx = ((ENTROPY_CONTEXT *)x->above_context); |
20 | 9.64M | ENTROPY_CONTEXT *l_ctx = ((ENTROPY_CONTEXT *)x->left_context); |
21 | | |
22 | 9.64M | memset(a_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); |
23 | 9.64M | memset(l_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); |
24 | | |
25 | | /* Clear entropy contexts for Y2 blocks */ |
26 | 9.64M | if (!x->mode_info_context->mbmi.is_4x4) { |
27 | 9.17M | a_ctx[8] = l_ctx[8] = 0; |
28 | 9.17M | } |
29 | 9.64M | } |
30 | | |
31 | | /* |
32 | | ------------------------------------------------------------------------------ |
33 | | Residual decoding (Paragraph 13.2 / 13.3) |
34 | | */ |
35 | | static const uint8_t kBands[16 + 1] = { |
36 | | 0, 1, 2, 3, 6, 4, 5, 6, 6, |
37 | | 6, 6, 6, 6, 6, 6, 7, 0 /* extra entry as sentinel */ |
38 | | }; |
39 | | |
40 | | static const uint8_t kCat3[] = { 173, 148, 140, 0 }; |
41 | | static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; |
42 | | static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; |
43 | | static const uint8_t kCat6[] = { 254, 254, 243, 230, 196, 177, |
44 | | 153, 140, 133, 130, 129, 0 }; |
45 | | static const uint8_t *const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; |
46 | | static const uint8_t kZigzag[16] = { 0, 1, 4, 8, 5, 2, 3, 6, |
47 | | 9, 12, 13, 10, 7, 11, 14, 15 }; |
48 | | |
49 | 143M | #define VP8GetBit vp8dx_decode_bool |
50 | | #define NUM_PROBAS 11 |
51 | | #define NUM_CTX 3 |
52 | | |
53 | | /* for const-casting */ |
54 | | typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; |
55 | | |
56 | | // With corrupt / fuzzed streams the calculation of br->value may overflow. See |
57 | | // b/148271109. |
58 | | static VPX_NO_UNSIGNED_OVERFLOW_CHECK int GetSigned(BOOL_DECODER *br, |
59 | 19.0M | int value_to_sign) { |
60 | 19.0M | int split = (br->range + 1) >> 1; |
61 | 19.0M | VP8_BD_VALUE bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); |
62 | 19.0M | int v; |
63 | | |
64 | 19.0M | if (br->count < 0) vp8dx_bool_decoder_fill(br); |
65 | | |
66 | 19.0M | if (br->value < bigsplit) { |
67 | 9.54M | br->range = split; |
68 | 9.54M | v = value_to_sign; |
69 | 9.54M | } else { |
70 | 9.51M | br->range = br->range - split; |
71 | 9.51M | br->value = br->value - bigsplit; |
72 | 9.51M | v = -value_to_sign; |
73 | 9.51M | } |
74 | 19.0M | br->range += br->range; |
75 | 19.0M | br->value += br->value; |
76 | 19.0M | br->count--; |
77 | | |
78 | 19.0M | return v; |
79 | 19.0M | } |
80 | | /* |
81 | | Returns the position of the last non-zero coeff plus one |
82 | | (and 0 if there's no coeff at all) |
83 | | */ |
84 | | static int GetCoeffs(BOOL_DECODER *br, ProbaArray prob, int ctx, int n, |
85 | 64.5M | int16_t *out) { |
86 | 64.5M | const uint8_t *p = prob[n][ctx]; |
87 | 64.5M | if (!VP8GetBit(br, p[0])) { /* first EOB is more a 'CBP' bit. */ |
88 | 52.8M | return 0; |
89 | 52.8M | } |
90 | 31.2M | while (1) { |
91 | 31.2M | ++n; |
92 | 31.2M | if (!VP8GetBit(br, p[1])) { |
93 | 12.2M | p = prob[kBands[n]][0]; |
94 | 19.0M | } else { /* non zero coeff */ |
95 | 19.0M | int v, j; |
96 | 19.0M | if (!VP8GetBit(br, p[2])) { |
97 | 15.7M | p = prob[kBands[n]][1]; |
98 | 15.7M | v = 1; |
99 | 15.7M | } else { |
100 | 3.27M | if (!VP8GetBit(br, p[3])) { |
101 | 2.85M | if (!VP8GetBit(br, p[4])) { |
102 | 2.01M | v = 2; |
103 | 2.01M | } else { |
104 | 836k | v = 3 + VP8GetBit(br, p[5]); |
105 | 836k | } |
106 | 2.85M | } else { |
107 | 414k | if (!VP8GetBit(br, p[6])) { |
108 | 252k | if (!VP8GetBit(br, p[7])) { |
109 | 178k | v = 5 + VP8GetBit(br, 159); |
110 | 178k | } else { |
111 | 74.3k | v = 7 + 2 * VP8GetBit(br, 165); |
112 | 74.3k | v += VP8GetBit(br, 145); |
113 | 74.3k | } |
114 | 252k | } else { |
115 | 161k | const uint8_t *tab; |
116 | 161k | const int bit1 = VP8GetBit(br, p[8]); |
117 | 161k | const int bit0 = VP8GetBit(br, p[9 + bit1]); |
118 | 161k | const int cat = 2 * bit1 + bit0; |
119 | 161k | v = 0; |
120 | 1.78M | for (tab = kCat3456[cat]; *tab; ++tab) { |
121 | 1.62M | v += v + VP8GetBit(br, *tab); |
122 | 1.62M | } |
123 | 161k | v += 3 + (8 << cat); |
124 | 161k | } |
125 | 414k | } |
126 | 3.27M | p = prob[kBands[n]][2]; |
127 | 3.27M | } |
128 | 19.0M | j = kZigzag[n - 1]; |
129 | | |
130 | 19.0M | out[j] = GetSigned(br, v); |
131 | | |
132 | 19.0M | if (n == 16 || !VP8GetBit(br, p[0])) { /* EOB */ |
133 | 11.6M | return n; |
134 | 11.6M | } |
135 | 19.0M | } |
136 | 19.6M | if (n == 16) { |
137 | 55.1k | return 16; |
138 | 55.1k | } |
139 | 19.6M | } |
140 | 11.6M | } |
141 | | |
142 | 2.62M | int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x) { |
143 | 2.62M | BOOL_DECODER *bc = x->current_bc; |
144 | 2.62M | const FRAME_CONTEXT *const fc = &dx->common.fc; |
145 | 2.62M | char *eobs = x->eobs; |
146 | | |
147 | 2.62M | int i; |
148 | 2.62M | int nonzeros; |
149 | 2.62M | int eobtotal = 0; |
150 | | |
151 | 2.62M | short *qcoeff_ptr; |
152 | 2.62M | ProbaArray coef_probs; |
153 | 2.62M | ENTROPY_CONTEXT *a_ctx = ((ENTROPY_CONTEXT *)x->above_context); |
154 | 2.62M | ENTROPY_CONTEXT *l_ctx = ((ENTROPY_CONTEXT *)x->left_context); |
155 | 2.62M | ENTROPY_CONTEXT *a; |
156 | 2.62M | ENTROPY_CONTEXT *l; |
157 | 2.62M | int skip_dc = 0; |
158 | | |
159 | 2.62M | qcoeff_ptr = &x->qcoeff[0]; |
160 | | |
161 | 2.62M | if (!x->mode_info_context->mbmi.is_4x4) { |
162 | 1.53M | a = a_ctx + 8; |
163 | 1.53M | l = l_ctx + 8; |
164 | | |
165 | 1.53M | coef_probs = fc->coef_probs[1]; |
166 | | |
167 | 1.53M | nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr + 24 * 16); |
168 | 1.53M | *a = *l = (nonzeros > 0); |
169 | | |
170 | 1.53M | eobs[24] = nonzeros; |
171 | 1.53M | eobtotal += nonzeros - 16; |
172 | | |
173 | 1.53M | coef_probs = fc->coef_probs[0]; |
174 | 1.53M | skip_dc = 1; |
175 | 1.53M | } else { |
176 | 1.09M | coef_probs = fc->coef_probs[3]; |
177 | 1.09M | skip_dc = 0; |
178 | 1.09M | } |
179 | | |
180 | 44.6M | for (i = 0; i < 16; ++i) { |
181 | 42.0M | a = a_ctx + (i & 3); |
182 | 42.0M | l = l_ctx + ((i & 0xc) >> 2); |
183 | | |
184 | 42.0M | nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), skip_dc, qcoeff_ptr); |
185 | 42.0M | *a = *l = (nonzeros > 0); |
186 | | |
187 | 42.0M | nonzeros += skip_dc; |
188 | 42.0M | eobs[i] = nonzeros; |
189 | 42.0M | eobtotal += nonzeros; |
190 | 42.0M | qcoeff_ptr += 16; |
191 | 42.0M | } |
192 | | |
193 | 2.62M | coef_probs = fc->coef_probs[2]; |
194 | | |
195 | 2.62M | a_ctx += 4; |
196 | 2.62M | l_ctx += 4; |
197 | 23.6M | for (i = 16; i < 24; ++i) { |
198 | 21.0M | a = a_ctx + ((i > 19) << 1) + (i & 1); |
199 | 21.0M | l = l_ctx + ((i > 19) << 1) + ((i & 3) > 1); |
200 | | |
201 | 21.0M | nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr); |
202 | 21.0M | *a = *l = (nonzeros > 0); |
203 | | |
204 | 21.0M | eobs[i] = nonzeros; |
205 | 21.0M | eobtotal += nonzeros; |
206 | 21.0M | qcoeff_ptr += 16; |
207 | 21.0M | } |
208 | | |
209 | 2.62M | return eobtotal; |
210 | 2.62M | } |