/src/ffmpeg/libavcodec/intrax8.c
Line | Count | Source |
1 | | /* |
2 | | * This file is part of FFmpeg. |
3 | | * |
4 | | * FFmpeg is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU Lesser General Public |
6 | | * License as published by the Free Software Foundation; either |
7 | | * version 2.1 of the License, or (at your option) any later version. |
8 | | * |
9 | | * FFmpeg is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | | * Lesser General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Lesser General Public |
15 | | * License along with FFmpeg; if not, write to the Free Software |
16 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | | */ |
18 | | |
19 | | /** |
20 | | * @file |
21 | | * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1 |
22 | | */ |
23 | | |
24 | | #include "libavutil/avassert.h" |
25 | | #include "libavutil/mem.h" |
26 | | #include "libavutil/thread.h" |
27 | | #include "avcodec.h" |
28 | | #include "get_bits.h" |
29 | | #include "idctdsp.h" |
30 | | #include "msmpeg4_vc1_data.h" |
31 | | #include "intrax8huf.h" |
32 | | #include "intrax8.h" |
33 | | #include "intrax8dsp.h" |
34 | | #include "mpegutils.h" |
35 | | |
36 | | #define VLC_BUFFER_SIZE 28150 |
37 | | |
38 | | #define MAX_TABLE_DEPTH(table_bits, max_bits) \ |
39 | 26.4M | ((max_bits + table_bits - 1) / table_bits) |
40 | | |
41 | 10.3M | #define DC_VLC_BITS 9 |
42 | 12.6M | #define AC_VLC_BITS 9 |
43 | 3.39M | #define OR_VLC_BITS 7 |
44 | | |
45 | 10.3M | #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS) |
46 | 12.6M | #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS) |
47 | 3.39M | #define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS) |
48 | | |
49 | | static const VLCElem *j_ac_vlc[2][2][8]; // [quant < 13], [intra / inter], [select] |
50 | | static const VLCElem *j_dc_vlc[2][8]; // [quant], [select] |
51 | | static const VLCElem *j_orient_vlc[2][4]; // [quant], [select] |
52 | | |
53 | | static av_cold const VLCElem *x8_init_vlc(VLCInitState *state, int nb_bits, |
54 | | int nb_codes, const uint8_t table[][2]) |
55 | 324 | { |
56 | 324 | return ff_vlc_init_tables_from_lengths(state, nb_bits, nb_codes, &table[0][1], 2, |
57 | 324 | &table[0][0], 2, 1, 0, 0); |
58 | 324 | } |
59 | | |
60 | | static av_cold void x8_vlc_init(void) |
61 | 6 | { |
62 | 6 | static VLCElem vlc_buf[VLC_BUFFER_SIZE]; |
63 | 6 | VLCInitState state = VLC_INIT_STATE(vlc_buf); |
64 | 6 | int i; |
65 | | |
66 | | // set ac tables |
67 | 18 | for (int i = 0; i < 2; i++) |
68 | 36 | for (int j = 0; j < 2; j++) |
69 | 216 | for (int k = 0; k < 8; k++) |
70 | 192 | j_ac_vlc[i][j][k] = x8_init_vlc(&state, AC_VLC_BITS, 77, |
71 | 192 | x8_ac_quant_table[i][j][k]); |
72 | | |
73 | | // set dc tables |
74 | 18 | for (int i = 0; i < 2; i++) |
75 | 108 | for (int j = 0; j < 8; j++) |
76 | 96 | j_dc_vlc[i][j] = x8_init_vlc(&state, DC_VLC_BITS, 34, |
77 | 96 | x8_dc_quant_table[i][j]); |
78 | | |
79 | | // set orient tables |
80 | 18 | for (i = 0; i < 2; i++) |
81 | 12 | j_orient_vlc[0][i] = x8_init_vlc(&state, OR_VLC_BITS, 12, |
82 | 12 | x8_orient_highquant_table[i]); |
83 | 30 | for (i = 0; i < 4; i++) |
84 | 24 | j_orient_vlc[1][i] = x8_init_vlc(&state, OR_VLC_BITS, 12, |
85 | 24 | x8_orient_lowquant_table[i]); |
86 | 6 | } |
87 | | |
88 | | static void x8_reset_vlc_tables(IntraX8Context *w) |
89 | 105k | { |
90 | 105k | memset(w->j_dc_vlc_table, 0, sizeof(w->j_dc_vlc_table)); |
91 | 105k | memset(w->j_ac_vlc_table, 0, sizeof(w->j_ac_vlc_table)); |
92 | 105k | w->j_orient_vlc_table = NULL; |
93 | 105k | } |
94 | | |
95 | | static inline void x8_select_ac_table(IntraX8Context *const w, int mode) |
96 | 5.73M | { |
97 | 5.73M | int table_index; |
98 | | |
99 | 5.73M | av_assert2(mode < 4); |
100 | | |
101 | 5.73M | if (w->j_ac_vlc_table[mode]) |
102 | 5.55M | return; |
103 | | |
104 | 181k | table_index = get_bits(w->gb, 3); |
105 | | // 2 modes use same tables |
106 | 181k | w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index]; |
107 | 181k | av_assert2(w->j_ac_vlc_table[mode]); |
108 | 181k | } |
109 | | |
110 | | static inline int x8_get_orient_vlc(IntraX8Context *w) |
111 | 3.39M | { |
112 | 3.39M | if (!w->j_orient_vlc_table) { |
113 | 34.8k | int table_index = get_bits(w->gb, 1 + (w->quant < 13)); |
114 | 34.8k | w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index]; |
115 | 34.8k | } |
116 | | |
117 | 3.39M | return get_vlc2(w->gb, w->j_orient_vlc_table, OR_VLC_BITS, OR_VLC_MTD); |
118 | 3.39M | } |
119 | | |
120 | | #define extra_bits(eb) (eb) // 3 bits |
121 | | #define extra_run (0xFF << 8) // 1 bit |
122 | | #define extra_level (0x00 << 8) // 1 bit |
123 | | #define run_offset(r) ((r) << 16) // 6 bits |
124 | | #define level_offset(l) ((l) << 24) // 5 bits |
125 | | static const uint32_t ac_decode_table[] = { |
126 | | /* 46 */ extra_bits(3) | extra_run | run_offset(16) | level_offset(0), |
127 | | /* 47 */ extra_bits(3) | extra_run | run_offset(24) | level_offset(0), |
128 | | /* 48 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1), |
129 | | /* 49 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1), |
130 | | |
131 | | /* 50 */ extra_bits(5) | extra_run | run_offset(32) | level_offset(0), |
132 | | /* 51 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1), |
133 | | |
134 | | /* 52 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4), |
135 | | /* 53 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(8), |
136 | | /* 54 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(12), |
137 | | /* 55 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(16), |
138 | | /* 56 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(24), |
139 | | |
140 | | /* 57 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3), |
141 | | /* 58 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7), |
142 | | |
143 | | /* 59 */ extra_bits(2) | extra_run | run_offset(16) | level_offset(0), |
144 | | /* 60 */ extra_bits(2) | extra_run | run_offset(20) | level_offset(0), |
145 | | /* 61 */ extra_bits(2) | extra_run | run_offset(24) | level_offset(0), |
146 | | /* 62 */ extra_bits(2) | extra_run | run_offset(28) | level_offset(0), |
147 | | /* 63 */ extra_bits(4) | extra_run | run_offset(32) | level_offset(0), |
148 | | /* 64 */ extra_bits(4) | extra_run | run_offset(48) | level_offset(0), |
149 | | |
150 | | /* 65 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1), |
151 | | /* 66 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1), |
152 | | /* 67 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1), |
153 | | |
154 | | /* 68 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4), |
155 | | /* 69 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(8), |
156 | | /* 70 */ extra_bits(4) | extra_level | run_offset(0) | level_offset(16), |
157 | | |
158 | | /* 71 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3), |
159 | | /* 72 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7), |
160 | | }; |
161 | | #undef extra_bits |
162 | | #undef extra_run |
163 | | #undef extra_level |
164 | | #undef run_offset |
165 | | #undef level_offset |
166 | | |
167 | | static void x8_get_ac_rlf(IntraX8Context *const w, const int mode, |
168 | | int *const run, int *const level, int *const final) |
169 | 12.6M | { |
170 | 12.6M | int i, e; |
171 | | |
172 | | // x8_select_ac_table(w, mode); |
173 | 12.6M | i = get_vlc2(w->gb, w->j_ac_vlc_table[mode], AC_VLC_BITS, AC_VLC_MTD); |
174 | | |
175 | 12.6M | if (i < 46) { // [0-45] |
176 | 12.1M | int t, l; |
177 | 12.1M | if (i < 0) { |
178 | 0 | *level = |
179 | 0 | *final = // prevent 'may be used uninitialized' |
180 | 0 | *run = 64; // this would cause error exit in the ac loop |
181 | 0 | return; |
182 | 0 | } |
183 | | |
184 | | /* |
185 | | * i == 0-15 r = 0-15 l = 0; r = i & %01111 |
186 | | * i == 16-19 r = 0-3 l = 1; r = i & %00011 |
187 | | * i == 20-21 r = 0-1 l = 2; r = i & %00001 |
188 | | * i == 22 r = 0 l = 3; r = i & %00000 |
189 | | */ |
190 | | |
191 | 12.1M | *final = |
192 | 12.1M | t = i > 22; |
193 | 12.1M | i -= 23 * t; |
194 | | |
195 | | /* l = lut_l[i / 2] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3 }[i >> 1]; |
196 | | * 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 */ |
197 | 12.1M | l = (0xE50000 >> (i & 0x1E)) & 3; // 0x1E or ~1 or (i >> 1 << 1) |
198 | | |
199 | | /* t = lut_mask[l] = { 0x0f, 0x03, 0x01, 0x00 }[l]; |
200 | | * as i < 256 the higher bits do not matter */ |
201 | 12.1M | t = 0x01030F >> (l << 3); |
202 | | |
203 | 12.1M | *run = i & t; |
204 | 12.1M | *level = l; |
205 | 12.1M | } else if (i < 73) { // [46-72] |
206 | 357k | uint32_t sm; |
207 | 357k | uint32_t mask; |
208 | | |
209 | 357k | i -= 46; |
210 | 357k | sm = ac_decode_table[i]; |
211 | | |
212 | 357k | e = get_bits(w->gb, sm & 0xF); |
213 | 357k | sm >>= 8; // 3 bits |
214 | 357k | mask = sm & 0xff; |
215 | 357k | sm >>= 8; // 1 bit |
216 | | |
217 | 357k | *run = (sm & 0xff) + (e & mask); // 6 bits |
218 | 357k | *level = (sm >> 8) + (e & ~mask); // 5 bits |
219 | 357k | *final = i > (58 - 46); |
220 | 357k | } else if (i < 75) { // [73-74] |
221 | 109k | static const uint8_t crazy_mix_runlevel[32] = { |
222 | 109k | 0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63, |
223 | 109k | 0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83, |
224 | 109k | 0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64, |
225 | 109k | 0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84, |
226 | 109k | }; |
227 | | |
228 | 109k | *final = !(i & 1); |
229 | 109k | e = get_bits(w->gb, 5); // get the extra bits |
230 | 109k | *run = crazy_mix_runlevel[e] >> 4; |
231 | 109k | *level = crazy_mix_runlevel[e] & 0x0F; |
232 | 109k | } else { |
233 | 14.7k | *level = get_bits(w->gb, 7 - 3 * (i & 1)); |
234 | 14.7k | *run = get_bits(w->gb, 6); |
235 | 14.7k | *final = get_bits1(w->gb); |
236 | 14.7k | } |
237 | 12.6M | return; |
238 | 12.6M | } |
239 | | |
240 | | /* static const uint8_t dc_extra_sbits[] = { |
241 | | * 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, |
242 | | * }; */ |
243 | | static const uint8_t dc_index_offset[] = { |
244 | | 0, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, |
245 | | }; |
246 | | |
247 | | static int x8_get_dc_rlf(IntraX8Context *const w, const int mode, |
248 | | int *const level, int *const final) |
249 | 10.3M | { |
250 | 10.3M | int i, e, c; |
251 | | |
252 | 10.3M | av_assert2(mode < 3); |
253 | 10.3M | if (!w->j_dc_vlc_table[mode]) { |
254 | 206k | int table_index = get_bits(w->gb, 3); |
255 | | // 4 modes, same table |
256 | 206k | w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index]; |
257 | 206k | } |
258 | | |
259 | 10.3M | i = get_vlc2(w->gb, w->j_dc_vlc_table[mode], DC_VLC_BITS, DC_VLC_MTD); |
260 | | |
261 | | /* (i >= 17) { i -= 17; final =1; } */ |
262 | 10.3M | c = i > 16; |
263 | 10.3M | *final = c; |
264 | 10.3M | i -= 17 * c; |
265 | | |
266 | 10.3M | if (i <= 0) { |
267 | 2.91M | *level = 0; |
268 | 2.91M | return -i; |
269 | 2.91M | } |
270 | 7.48M | c = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[] |
271 | 7.48M | c -= c > 1; |
272 | | |
273 | 7.48M | e = get_bits(w->gb, c); // get the extra bits |
274 | 7.48M | i = dc_index_offset[i] + (e >> 1); |
275 | | |
276 | 7.48M | e = -(e & 1); // 0, 0xffffff |
277 | 7.48M | *level = (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1) |
278 | 7.48M | return 0; |
279 | 10.3M | } |
280 | | |
281 | | // end of huffman |
282 | | |
283 | | static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma) |
284 | 10.3M | { |
285 | 10.3M | int range; |
286 | 10.3M | int sum; |
287 | 10.3M | int quant; |
288 | | |
289 | 10.3M | w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad, |
290 | 10.3M | w->frame->linesize[chroma > 0], |
291 | 10.3M | &range, &sum, w->edges); |
292 | 10.3M | if (chroma) { |
293 | 3.22M | w->orient = w->chroma_orient; |
294 | 3.22M | quant = w->quant_dc_chroma; |
295 | 7.17M | } else { |
296 | 7.17M | quant = w->quant; |
297 | 7.17M | } |
298 | | |
299 | 10.3M | w->flat_dc = 0; |
300 | 10.3M | if (range < quant || range < 3) { |
301 | 4.74M | w->orient = 0; |
302 | | |
303 | | // yep you read right, a +-1 idct error may break decoding! |
304 | 4.74M | if (range < 3) { |
305 | 2.27M | w->flat_dc = 1; |
306 | 2.27M | sum += 9; |
307 | | // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899 |
308 | 2.27M | w->predicted_dc = sum * 6899 >> 17; |
309 | 2.27M | } |
310 | 4.74M | } |
311 | 10.3M | if (chroma) |
312 | 3.22M | return 0; |
313 | | |
314 | 7.17M | av_assert2(w->orient < 3); |
315 | 7.17M | if (range < 2 * w->quant) { |
316 | 3.78M | if ((w->edges & 3) == 0) { |
317 | 2.71M | if (w->orient == 1) |
318 | 28.0k | w->orient = 11; |
319 | 2.71M | if (w->orient == 2) |
320 | 49.2k | w->orient = 10; |
321 | 2.71M | } else { |
322 | 1.07M | w->orient = 0; |
323 | 1.07M | } |
324 | 3.78M | w->raw_orient = 0; |
325 | 3.78M | } else { |
326 | 3.39M | static const uint8_t prediction_table[3][12] = { |
327 | 3.39M | { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 }, |
328 | 3.39M | { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 }, |
329 | 3.39M | { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 }, |
330 | 3.39M | }; |
331 | 3.39M | w->raw_orient = x8_get_orient_vlc(w); |
332 | 3.39M | if (w->raw_orient < 0) |
333 | 0 | return -1; |
334 | 3.39M | av_assert2(w->raw_orient < 12); |
335 | 3.39M | av_assert2(w->orient < 3); |
336 | 3.39M | w->orient=prediction_table[w->orient][w->raw_orient]; |
337 | 3.39M | } |
338 | 7.17M | return 0; |
339 | 7.17M | } |
340 | | |
341 | | static void x8_update_predictions(IntraX8Context *const w, const int orient, |
342 | | const int est_run) |
343 | 7.10M | { |
344 | 7.10M | w->prediction_table[w->mb_x * 2 + (w->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8); |
345 | | /* |
346 | | * y = 2n + 0 -> // 0 2 4 |
347 | | * y = 2n + 1 -> // 1 3 5 |
348 | | */ |
349 | 7.10M | } |
350 | | |
351 | | static void x8_get_prediction_chroma(IntraX8Context *const w) |
352 | 1.61M | { |
353 | 1.61M | w->edges = 1 * !(w->mb_x >> 1); |
354 | 1.61M | w->edges |= 2 * !(w->mb_y >> 1); |
355 | 1.61M | w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd |
356 | | |
357 | 1.61M | w->raw_orient = 0; |
358 | | // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC |
359 | 1.61M | if (w->edges & 3) { |
360 | 281k | w->chroma_orient = 4 << ((0xCC >> w->edges) & 1); |
361 | 281k | return; |
362 | 281k | } |
363 | | // block[x - 1][y | 1 - 1)] |
364 | 1.33M | w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2; |
365 | 1.33M | } |
366 | | |
367 | | static void x8_get_prediction(IntraX8Context *const w) |
368 | 7.17M | { |
369 | 7.17M | int a, b, c, i; |
370 | | |
371 | 7.17M | w->edges = 1 * !w->mb_x; |
372 | 7.17M | w->edges |= 2 * !w->mb_y; |
373 | 7.17M | w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); |
374 | | |
375 | 7.17M | switch (w->edges & 3) { |
376 | 5.98M | case 0: |
377 | 5.98M | break; |
378 | 179k | case 1: |
379 | | // take the one from the above block[0][y - 1] |
380 | 179k | w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2; |
381 | 179k | w->orient = 1; |
382 | 179k | return; |
383 | 910k | case 2: |
384 | | // take the one from the previous block[x - 1][0] |
385 | 910k | w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2; |
386 | 910k | w->orient = 2; |
387 | 910k | return; |
388 | 104k | case 3: |
389 | 104k | w->est_run = 16; |
390 | 104k | w->orient = 0; |
391 | 104k | return; |
392 | 7.17M | } |
393 | | // no edge cases |
394 | 5.98M | b = w->prediction_table[2 * w->mb_x + !(w->mb_y & 1)]; // block[x ][y - 1] |
395 | 5.98M | a = w->prediction_table[2 * w->mb_x - 2 + (w->mb_y & 1)]; // block[x - 1][y ] |
396 | 5.98M | c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1] |
397 | | |
398 | 5.98M | w->est_run = FFMIN(b, a); |
399 | | /* This condition has nothing to do with w->edges, even if it looks |
400 | | * similar it would trigger if e.g. x = 3; y = 2; |
401 | | * I guess somebody wrote something wrong and it became standard. */ |
402 | 5.98M | if ((w->mb_x & w->mb_y) != 0) |
403 | 4.78M | w->est_run = FFMIN(c, w->est_run); |
404 | 5.98M | w->est_run >>= 2; |
405 | | |
406 | 5.98M | a &= 3; |
407 | 5.98M | b &= 3; |
408 | 5.98M | c &= 3; |
409 | | |
410 | 5.98M | i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3; |
411 | 5.98M | if (i != 3) |
412 | 5.92M | w->orient = i; |
413 | 59.1k | else |
414 | 59.1k | w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3; |
415 | | /* |
416 | | * lut1[b][a] = { |
417 | | * ->{ 0, 1, 0, pad }, |
418 | | * { 0, 1, X, pad }, |
419 | | * { 2, 2, 2, pad } |
420 | | * } |
421 | | * pad 2 2 2; |
422 | | * pad X 1 0; |
423 | | * pad 0 1 0 <- |
424 | | * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4 |
425 | | * |
426 | | * lut2[q>12][c] = { |
427 | | * ->{ 0, 2, 1, pad}, |
428 | | * { 2, 2, 2, pad} |
429 | | * } |
430 | | * pad 2 2 2; |
431 | | * pad 1 2 0 <- |
432 | | * -> 11 10'10 10 '11 01'10 00 => 0xEAD8 |
433 | | */ |
434 | 5.98M | } |
435 | | |
436 | | static void x8_ac_compensation(IntraX8Context *const w, const int direction, |
437 | | const int dc_level) |
438 | 4.97M | { |
439 | 4.97M | int t; |
440 | 88.4M | #define B(x,y) w->block[w->idsp.idct_permutation[(x) + (y) * 8]] |
441 | 33.5M | #define T(x) ((x) * dc_level + 0x8000) >> 16; |
442 | 4.97M | switch (direction) { |
443 | 3.42M | case 0: |
444 | 3.42M | t = T(3811); // h |
445 | 3.42M | B(1, 0) -= t; |
446 | 3.42M | B(0, 1) -= t; |
447 | | |
448 | 3.42M | t = T(487); // e |
449 | 3.42M | B(2, 0) -= t; |
450 | 3.42M | B(0, 2) -= t; |
451 | | |
452 | 3.42M | t = T(506); // f |
453 | 3.42M | B(3, 0) -= t; |
454 | 3.42M | B(0, 3) -= t; |
455 | | |
456 | 3.42M | t = T(135); // c |
457 | 3.42M | B(4, 0) -= t; |
458 | 3.42M | B(0, 4) -= t; |
459 | 3.42M | B(2, 1) += t; |
460 | 3.42M | B(1, 2) += t; |
461 | 3.42M | B(3, 1) += t; |
462 | 3.42M | B(1, 3) += t; |
463 | | |
464 | 3.42M | t = T(173); // d |
465 | 3.42M | B(5, 0) -= t; |
466 | 3.42M | B(0, 5) -= t; |
467 | | |
468 | 3.42M | t = T(61); // b |
469 | 3.42M | B(6, 0) -= t; |
470 | 3.42M | B(0, 6) -= t; |
471 | 3.42M | B(5, 1) += t; |
472 | 3.42M | B(1, 5) += t; |
473 | | |
474 | 3.42M | t = T(42); // a |
475 | 3.42M | B(7, 0) -= t; |
476 | 3.42M | B(0, 7) -= t; |
477 | 3.42M | B(4, 1) += t; |
478 | 3.42M | B(1, 4) += t; |
479 | 3.42M | B(4, 4) += t; |
480 | | |
481 | 3.42M | t = T(1084); // g |
482 | 3.42M | B(1, 1) += t; |
483 | 3.42M | break; |
484 | 594k | case 1: |
485 | 594k | B(0, 1) -= T(6269); |
486 | 594k | B(0, 3) -= T(708); |
487 | 594k | B(0, 5) -= T(172); |
488 | 594k | B(0, 7) -= T(73); |
489 | 594k | break; |
490 | 951k | case 2: |
491 | 951k | B(1, 0) -= T(6269); |
492 | 951k | B(3, 0) -= T(708); |
493 | 951k | B(5, 0) -= T(172); |
494 | 951k | B(7, 0) -= T(73); |
495 | 951k | break; |
496 | 4.97M | } |
497 | 4.97M | #undef B |
498 | 4.97M | #undef T |
499 | 4.97M | } |
500 | | |
501 | | static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst, |
502 | | const ptrdiff_t linesize) |
503 | 2.21M | { |
504 | 2.21M | int k; |
505 | 19.9M | for (k = 0; k < 8; k++) { |
506 | 17.6M | memset(dst, pix, 8); |
507 | 17.6M | dst += linesize; |
508 | 17.6M | } |
509 | 2.21M | } |
510 | | |
511 | | static const int16_t quant_table[64] = { |
512 | | 256, 256, 256, 256, 256, 256, 259, 262, |
513 | | 265, 269, 272, 275, 278, 282, 285, 288, |
514 | | 292, 295, 299, 303, 306, 310, 314, 317, |
515 | | 321, 325, 329, 333, 337, 341, 345, 349, |
516 | | 353, 358, 362, 366, 371, 375, 379, 384, |
517 | | 389, 393, 398, 403, 408, 413, 417, 422, |
518 | | 428, 433, 438, 443, 448, 454, 459, 465, |
519 | | 470, 476, 482, 488, 493, 499, 505, 511, |
520 | | }; |
521 | | |
522 | | static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma) |
523 | 10.3M | { |
524 | 10.3M | uint8_t *scantable; |
525 | 10.3M | int final, run, level; |
526 | 10.3M | int ac_mode, dc_mode, est_run, dc_level; |
527 | 10.3M | int pos, n; |
528 | 10.3M | int zeros_only; |
529 | 10.3M | int use_quant_matrix; |
530 | 10.3M | int sign; |
531 | | |
532 | 10.3M | av_assert2(w->orient < 12); |
533 | 10.3M | w->bdsp.clear_block(w->block); |
534 | | |
535 | 10.3M | if (chroma) |
536 | 3.22M | dc_mode = 2; |
537 | 7.17M | else |
538 | 7.17M | dc_mode = !!w->est_run; // 0, 1 |
539 | | |
540 | 10.3M | if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) |
541 | 0 | return -1; |
542 | 10.3M | n = 0; |
543 | 10.3M | zeros_only = 0; |
544 | 10.3M | if (!final) { // decode ac |
545 | 3.55M | use_quant_matrix = w->use_quant_matrix; |
546 | 3.55M | if (chroma) { |
547 | 1.11M | ac_mode = 1; |
548 | 1.11M | est_run = 64; // not used |
549 | 2.43M | } else { |
550 | 2.43M | if (w->raw_orient < 3) |
551 | 2.05M | use_quant_matrix = 0; |
552 | | |
553 | 2.43M | if (w->raw_orient > 4) { |
554 | 149k | ac_mode = 0; |
555 | 149k | est_run = 64; |
556 | 2.28M | } else { |
557 | 2.28M | if (w->est_run > 1) { |
558 | 226k | ac_mode = 2; |
559 | 226k | est_run = w->est_run; |
560 | 2.05M | } else { |
561 | 2.05M | ac_mode = 3; |
562 | 2.05M | est_run = 64; |
563 | 2.05M | } |
564 | 2.28M | } |
565 | 2.43M | } |
566 | 3.55M | x8_select_ac_table(w, ac_mode); |
567 | | /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <- |
568 | | * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */ |
569 | 3.55M | scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3]; |
570 | 3.55M | pos = 0; |
571 | 12.6M | do { |
572 | 12.6M | n++; |
573 | 12.6M | if (n >= est_run) { |
574 | 2.18M | ac_mode = 3; |
575 | 2.18M | x8_select_ac_table(w, 3); |
576 | 2.18M | } |
577 | | |
578 | 12.6M | x8_get_ac_rlf(w, ac_mode, &run, &level, &final); |
579 | | |
580 | 12.6M | pos += run + 1; |
581 | 12.6M | if (pos > 63) { |
582 | | // this also handles vlc error in x8_get_ac_rlf |
583 | 85.7k | return -1; |
584 | 85.7k | } |
585 | 12.5M | level = (level + 1) * w->dquant; |
586 | 12.5M | level += w->qsum; |
587 | | |
588 | 12.5M | sign = -get_bits1(w->gb); |
589 | 12.5M | level = (level ^ sign) - sign; |
590 | | |
591 | 12.5M | if (use_quant_matrix) |
592 | 2.54M | level = (level * quant_table[pos]) >> 8; |
593 | | |
594 | 12.5M | w->block[scantable[pos]] = level; |
595 | 12.5M | } while (!final); |
596 | 6.84M | } else { // DC only |
597 | 6.84M | if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1] |
598 | 1.46M | int32_t divide_quant = !chroma ? w->divide_quant_dc_luma |
599 | 1.46M | : w->divide_quant_dc_chroma; |
600 | 1.46M | int32_t dc_quant = !chroma ? w->quant |
601 | 1.46M | : w->quant_dc_chroma; |
602 | | |
603 | | // original intent dc_level += predicted_dc/quant; |
604 | | // but it got lost somewhere in the rounding |
605 | 1.46M | dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13; |
606 | | |
607 | 1.46M | dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3), |
608 | 1.46M | w->dest[chroma], |
609 | 1.46M | w->frame->linesize[!!chroma]); |
610 | | |
611 | 1.46M | goto block_placed; |
612 | 1.46M | } |
613 | 5.38M | zeros_only = dc_level == 0; |
614 | 5.38M | } |
615 | 8.85M | if (!chroma) |
616 | 6.05M | w->block[0] = dc_level * w->quant; |
617 | 2.80M | else |
618 | 2.80M | w->block[0] = dc_level * w->quant_dc_chroma; |
619 | | |
620 | | // there is !zero_only check in the original, but dc_level check is enough |
621 | 8.85M | if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) { |
622 | 5.04M | int direction; |
623 | | /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <- |
624 | | * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */ |
625 | 5.04M | direction = (0x6A017C >> (w->orient * 2)) & 3; |
626 | 5.04M | if (direction != 3) { |
627 | 4.97M | x8_ac_compensation(w, direction, w->block[0]); |
628 | 4.97M | } |
629 | 5.04M | } |
630 | | |
631 | 8.85M | if (w->flat_dc) { |
632 | 748k | dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma], |
633 | 748k | w->frame->linesize[!!chroma]); |
634 | 8.10M | } else { |
635 | 8.10M | w->dsp.spatial_compensation[w->orient](w->scratchpad, |
636 | 8.10M | w->dest[chroma], |
637 | 8.10M | w->frame->linesize[!!chroma]); |
638 | 8.10M | } |
639 | 8.85M | if (!zeros_only) |
640 | 7.26M | w->idsp.idct_add(w->dest[chroma], |
641 | 7.26M | w->frame->linesize[!!chroma], |
642 | 7.26M | w->block); |
643 | | |
644 | 10.3M | block_placed: |
645 | 10.3M | if (!chroma) |
646 | 7.10M | x8_update_predictions(w, w->orient, n); |
647 | | |
648 | 10.3M | if (w->loopfilter) { |
649 | 9.82M | uint8_t *ptr = w->dest[chroma]; |
650 | 9.82M | ptrdiff_t linesize = w->frame->linesize[!!chroma]; |
651 | | |
652 | 9.82M | if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4))) |
653 | 7.57M | w->dsp.h_loop_filter(ptr, linesize, w->quant); |
654 | | |
655 | 9.82M | if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8))) |
656 | 8.22M | w->dsp.v_loop_filter(ptr, linesize, w->quant); |
657 | 9.82M | } |
658 | 10.3M | return 0; |
659 | 8.85M | } |
660 | | |
661 | | // FIXME maybe merge with ff_* |
662 | | static void x8_init_block_index(IntraX8Context *w, AVFrame *frame) |
663 | 286k | { |
664 | | // not parent codec linesize as this would be wrong for field pics |
665 | | // not that IntraX8 has interlacing support ;) |
666 | 286k | const ptrdiff_t linesize = frame->linesize[0]; |
667 | 286k | const ptrdiff_t uvlinesize = frame->linesize[1]; |
668 | | |
669 | 286k | w->dest[0] = frame->data[0]; |
670 | 286k | w->dest[1] = frame->data[1]; |
671 | 286k | w->dest[2] = frame->data[2]; |
672 | | |
673 | 286k | w->dest[0] += w->mb_y * linesize << 3; |
674 | | // chroma blocks are on add rows |
675 | 286k | w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2; |
676 | 286k | w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2; |
677 | 286k | } |
678 | | |
679 | | av_cold int ff_intrax8_common_init(AVCodecContext *avctx, |
680 | | IntraX8Context *w, |
681 | | int16_t block[64], |
682 | | int mb_width, int mb_height) |
683 | 64.3k | { |
684 | 64.3k | static AVOnce init_static_once = AV_ONCE_INIT; |
685 | | |
686 | 64.3k | w->avctx = avctx; |
687 | 64.3k | w->mb_width = mb_width; |
688 | 64.3k | w->mb_height = mb_height; |
689 | 64.3k | w->block = block; |
690 | | |
691 | | // two rows, 2 blocks per cannon mb |
692 | 64.3k | w->prediction_table = av_mallocz(w->mb_width * 2 * 2); |
693 | 64.3k | if (!w->prediction_table) |
694 | 0 | return AVERROR(ENOMEM); |
695 | | |
696 | 64.3k | ff_wmv2dsp_init(&w->idsp); |
697 | | |
698 | 64.3k | ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0], |
699 | 64.3k | w->idsp.idct_permutation); |
700 | 64.3k | ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2], |
701 | 64.3k | w->idsp.idct_permutation); |
702 | 64.3k | ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3], |
703 | 64.3k | w->idsp.idct_permutation); |
704 | | |
705 | 64.3k | ff_intrax8dsp_init(&w->dsp); |
706 | 64.3k | ff_blockdsp_init(&w->bdsp); |
707 | | |
708 | 64.3k | ff_thread_once(&init_static_once, x8_vlc_init); |
709 | | |
710 | 64.3k | return 0; |
711 | 64.3k | } |
712 | | |
713 | | av_cold void ff_intrax8_common_end(IntraX8Context *w) |
714 | 65.4k | { |
715 | 65.4k | av_freep(&w->prediction_table); |
716 | 65.4k | } |
717 | | |
718 | | int ff_intrax8_decode_picture(IntraX8Context *w, MPVPicture *pict, |
719 | | GetBitContext *gb, int *mb_x, int *mb_y, |
720 | | int dquant, int quant_offset, |
721 | | int loopfilter, int lowdelay) |
722 | 105k | { |
723 | 105k | int mb_xy; |
724 | | |
725 | 105k | w->gb = gb; |
726 | 105k | w->dquant = dquant; |
727 | 105k | w->quant = dquant >> 1; |
728 | 105k | w->qsum = quant_offset; |
729 | 105k | w->frame = pict->f; |
730 | 105k | w->loopfilter = loopfilter; |
731 | 105k | w->use_quant_matrix = get_bits1(w->gb); |
732 | | |
733 | 105k | w->mb_x = *mb_x; |
734 | 105k | w->mb_y = *mb_y; |
735 | | |
736 | 105k | w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant; |
737 | 105k | if (w->quant < 5) { |
738 | 22.7k | w->quant_dc_chroma = w->quant; |
739 | 22.7k | w->divide_quant_dc_chroma = w->divide_quant_dc_luma; |
740 | 82.3k | } else { |
741 | 82.3k | w->quant_dc_chroma = w->quant + ((w->quant + 3) >> 3); |
742 | 82.3k | w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma; |
743 | 82.3k | } |
744 | 105k | x8_reset_vlc_tables(w); |
745 | | |
746 | 303k | for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) { |
747 | 286k | x8_init_block_index(w, w->frame); |
748 | 286k | mb_xy = (w->mb_y >> 1) * (w->mb_width + 1); |
749 | 286k | if (get_bits_left(gb) < 1) |
750 | 2.70k | goto error; |
751 | 7.37M | for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) { |
752 | 7.17M | x8_get_prediction(w); |
753 | 7.17M | if (x8_setup_spatial_predictor(w, 0)) |
754 | 0 | goto error; |
755 | 7.17M | if (x8_decode_intra_mb(w, 0)) |
756 | 74.1k | goto error; |
757 | | |
758 | 7.10M | if (w->mb_x & w->mb_y & 1) { |
759 | 1.61M | x8_get_prediction_chroma(w); |
760 | | |
761 | | /* when setting up chroma, no vlc is read, |
762 | | * so no error condition can be reached */ |
763 | 1.61M | x8_setup_spatial_predictor(w, 1); |
764 | 1.61M | if (x8_decode_intra_mb(w, 1)) |
765 | 5.01k | goto error; |
766 | | |
767 | 1.60M | x8_setup_spatial_predictor(w, 2); |
768 | 1.60M | if (x8_decode_intra_mb(w, 2)) |
769 | 6.62k | goto error; |
770 | | |
771 | 1.60M | w->dest[1] += 8; |
772 | 1.60M | w->dest[2] += 8; |
773 | | |
774 | 1.60M | pict->qscale_table[mb_xy] = w->quant; |
775 | 1.60M | mb_xy++; |
776 | 1.60M | } |
777 | 7.09M | w->dest[0] += 8; |
778 | 7.09M | } |
779 | 197k | if (w->mb_y & 1) |
780 | 87.0k | ff_draw_horiz_band(w->avctx, w->frame, w->frame, |
781 | 87.0k | (w->mb_y - 1) * 8, 16, |
782 | 87.0k | PICT_FRAME, 0, lowdelay); |
783 | 197k | } |
784 | | |
785 | 105k | error: |
786 | 105k | *mb_x = w->mb_x; |
787 | 105k | *mb_y = w->mb_y; |
788 | | |
789 | 105k | return 0; |
790 | 105k | } |