FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/intrax8.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 363 378 96.0%
Functions: 18 18 100.0%
Branches: 146 161 90.7%

Line Branch Exec 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 ((max_bits + table_bits - 1) / table_bits)
40
41 #define DC_VLC_BITS 9
42 #define AC_VLC_BITS 9
43 #define OR_VLC_BITS 7
44
45 #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
46 #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
47 #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 1350 static av_cold const VLCElem *x8_init_vlc(VLCInitState *state, int nb_bits,
54 int nb_codes, const uint8_t table[][2])
55 {
56 2700 return ff_vlc_init_tables_from_lengths(state, nb_bits, nb_codes, &table[0][1], 2,
57 1350 &table[0][0], 2, 1, 0, 0);
58 }
59
60 25 static av_cold void x8_vlc_init(void)
61 {
62 static VLCElem vlc_buf[VLC_BUFFER_SIZE];
63 25 VLCInitState state = VLC_INIT_STATE(vlc_buf);
64 int i;
65
66 // set ac tables
67
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 25 times.
75 for (int i = 0; i < 2; i++)
68
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 50 times.
150 for (int j = 0; j < 2; j++)
69
2/2
✓ Branch 0 taken 800 times.
✓ Branch 1 taken 100 times.
900 for (int k = 0; k < 8; k++)
70 800 j_ac_vlc[i][j][k] = x8_init_vlc(&state, AC_VLC_BITS, 77,
71 800 x8_ac_quant_table[i][j][k]);
72
73 // set dc tables
74
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 25 times.
75 for (int i = 0; i < 2; i++)
75
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 50 times.
450 for (int j = 0; j < 8; j++)
76 400 j_dc_vlc[i][j] = x8_init_vlc(&state, DC_VLC_BITS, 34,
77 400 x8_dc_quant_table[i][j]);
78
79 // set orient tables
80
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 25 times.
75 for (i = 0; i < 2; i++)
81 50 j_orient_vlc[0][i] = x8_init_vlc(&state, OR_VLC_BITS, 12,
82 50 x8_orient_highquant_table[i]);
83
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 25 times.
125 for (i = 0; i < 4; i++)
84 100 j_orient_vlc[1][i] = x8_init_vlc(&state, OR_VLC_BITS, 12,
85 100 x8_orient_lowquant_table[i]);
86 25 }
87
88 3 static void x8_reset_vlc_tables(IntraX8Context *w)
89 {
90 3 memset(w->j_dc_vlc_table, 0, sizeof(w->j_dc_vlc_table));
91 3 memset(w->j_ac_vlc_table, 0, sizeof(w->j_ac_vlc_table));
92 3 w->j_orient_vlc_table = NULL;
93 3 }
94
95 3909 static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
96 {
97 int table_index;
98
99 av_assert2(mode < 4);
100
101
2/2
✓ Branch 0 taken 3897 times.
✓ Branch 1 taken 12 times.
3909 if (w->j_ac_vlc_table[mode])
102 3897 return;
103
104 12 table_index = get_bits(w->gb, 3);
105 // 2 modes use same tables
106 12 w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index];
107 av_assert2(w->j_ac_vlc_table[mode]);
108 }
109
110 1304 static inline int x8_get_orient_vlc(IntraX8Context *w)
111 {
112
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1301 times.
1304 if (!w->j_orient_vlc_table) {
113
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 int table_index = get_bits(w->gb, 1 + (w->quant < 13));
114 3 w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index];
115 }
116
117 1304 return get_vlc2(w->gb, w->j_orient_vlc_table, OR_VLC_BITS, OR_VLC_MTD);
118 }
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 8932 static void x8_get_ac_rlf(IntraX8Context *const w, const int mode,
168 int *const run, int *const level, int *const final)
169 {
170 int i, e;
171
172 // x8_select_ac_table(w, mode);
173 8932 i = get_vlc2(w->gb, w->j_ac_vlc_table[mode], AC_VLC_BITS, AC_VLC_MTD);
174
175
2/2
✓ Branch 0 taken 7635 times.
✓ Branch 1 taken 1297 times.
8932 if (i < 46) { // [0-45]
176 int t, l;
177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7635 times.
7635 if (i < 0) {
178 *level =
179 *final = // prevent 'may be used uninitialized'
180 *run = 64; // this would cause error exit in the ac loop
181 return;
182 }
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 7635 *final =
192 7635 t = i > 22;
193 7635 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 7635 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 7635 t = 0x01030F >> (l << 3);
202
203 7635 *run = i & t;
204 7635 *level = l;
205
2/2
✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 240 times.
1297 } else if (i < 73) { // [46-72]
206 uint32_t sm;
207 uint32_t mask;
208
209 1057 i -= 46;
210 1057 sm = ac_decode_table[i];
211
212 1057 e = get_bits(w->gb, sm & 0xF);
213 1057 sm >>= 8; // 3 bits
214 1057 mask = sm & 0xff;
215 1057 sm >>= 8; // 1 bit
216
217 1057 *run = (sm & 0xff) + (e & mask); // 6 bits
218 1057 *level = (sm >> 8) + (e & ~mask); // 5 bits
219 1057 *final = i > (58 - 46);
220
2/2
✓ Branch 0 taken 234 times.
✓ Branch 1 taken 6 times.
240 } else if (i < 75) { // [73-74]
221 static const uint8_t crazy_mix_runlevel[32] = {
222 0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63,
223 0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83,
224 0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64,
225 0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84,
226 };
227
228 234 *final = !(i & 1);
229 234 e = get_bits(w->gb, 5); // get the extra bits
230 234 *run = crazy_mix_runlevel[e] >> 4;
231 234 *level = crazy_mix_runlevel[e] & 0x0F;
232 } else {
233 6 *level = get_bits(w->gb, 7 - 3 * (i & 1));
234 6 *run = get_bits(w->gb, 6);
235 6 *final = get_bits1(w->gb);
236 }
237 8932 return;
238 }
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 5400 static int x8_get_dc_rlf(IntraX8Context *const w, const int mode,
248 int *const level, int *const final)
249 {
250 int i, e, c;
251
252 av_assert2(mode < 3);
253
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5391 times.
5400 if (!w->j_dc_vlc_table[mode]) {
254 9 int table_index = get_bits(w->gb, 3);
255 // 4 modes, same table
256 9 w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index];
257 }
258
259 5400 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 5400 c = i > 16;
263 5400 *final = c;
264 5400 i -= 17 * c;
265
266
2/2
✓ Branch 0 taken 1320 times.
✓ Branch 1 taken 4080 times.
5400 if (i <= 0) {
267 1320 *level = 0;
268 1320 return -i;
269 }
270 4080 c = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[]
271 4080 c -= c > 1;
272
273 4080 e = get_bits(w->gb, c); // get the extra bits
274 4080 i = dc_index_offset[i] + (e >> 1);
275
276 4080 e = -(e & 1); // 0, 0xffffff
277 4080 *level = (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1)
278 4080 return 0;
279 }
280
281 // end of huffman
282
283 5400 static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
284 {
285 int range;
286 int sum;
287 int quant;
288
289 5400 w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad,
290 5400 w->frame->linesize[chroma > 0],
291 &range, &sum, w->edges);
292
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 3600 times.
5400 if (chroma) {
293 1800 w->orient = w->chroma_orient;
294 1800 quant = w->quant_dc_chroma;
295 } else {
296 3600 quant = w->quant;
297 }
298
299 5400 w->flat_dc = 0;
300
3/4
✓ Branch 0 taken 2014 times.
✓ Branch 1 taken 3386 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2014 times.
5400 if (range < quant || range < 3) {
301 3386 w->orient = 0;
302
303 // yep you read right, a +-1 idct error may break decoding!
304
2/2
✓ Branch 0 taken 1365 times.
✓ Branch 1 taken 2021 times.
3386 if (range < 3) {
305 1365 w->flat_dc = 1;
306 1365 sum += 9;
307 // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
308 1365 w->predicted_dc = sum * 6899 >> 17;
309 }
310 }
311
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 3600 times.
5400 if (chroma)
312 1800 return 0;
313
314 av_assert2(w->orient < 3);
315
2/2
✓ Branch 0 taken 2296 times.
✓ Branch 1 taken 1304 times.
3600 if (range < 2 * w->quant) {
316
2/2
✓ Branch 0 taken 2102 times.
✓ Branch 1 taken 194 times.
2296 if ((w->edges & 3) == 0) {
317
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2096 times.
2102 if (w->orient == 1)
318 6 w->orient = 11;
319
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2086 times.
2102 if (w->orient == 2)
320 16 w->orient = 10;
321 } else {
322 194 w->orient = 0;
323 }
324 2296 w->raw_orient = 0;
325 } else {
326 static const uint8_t prediction_table[3][12] = {
327 { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 },
328 { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 },
329 { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 },
330 };
331 1304 w->raw_orient = x8_get_orient_vlc(w);
332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1304 times.
1304 if (w->raw_orient < 0)
333 return -1;
334 av_assert2(w->raw_orient < 12);
335 av_assert2(w->orient < 3);
336 1304 w->orient=prediction_table[w->orient][w->raw_orient];
337 }
338 3600 return 0;
339 }
340
341 3600 static void x8_update_predictions(IntraX8Context *const w, const int orient,
342 const int est_run)
343 {
344
2/2
✓ Branch 0 taken 469 times.
✓ Branch 1 taken 3131 times.
3600 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 3600 }
350
351 900 static void x8_get_prediction_chroma(IntraX8Context *const w)
352 {
353 900 w->edges = 1 * !(w->mb_x >> 1);
354
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 840 times.
900 w->edges |= 2 * !(w->mb_y >> 1);
355
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 855 times.
900 w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd
356
357 900 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
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 798 times.
900 if (w->edges & 3) {
360 102 w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
361 102 return;
362 }
363 // block[x - 1][y | 1 - 1)]
364 798 w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2;
365 }
366
367 3600 static void x8_get_prediction(IntraX8Context *const w)
368 {
369 int a, b, c, i;
370
371 3600 w->edges = 1 * !w->mb_x;
372
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 3480 times.
3600 w->edges |= 2 * !w->mb_y;
373
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 3510 times.
3600 w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1));
374
375
4/5
✓ Branch 0 taken 3393 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
3600 switch (w->edges & 3) {
376 3393 case 0:
377 3393 break;
378 87 case 1:
379 // take the one from the above block[0][y - 1]
380 87 w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2;
381 87 w->orient = 1;
382 87 return;
383 117 case 2:
384 // take the one from the previous block[x - 1][0]
385 117 w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2;
386 117 w->orient = 2;
387 117 return;
388 3 case 3:
389 3 w->est_run = 16;
390 3 w->orient = 0;
391 3 return;
392 }
393 // no edge cases
394 3393 b = w->prediction_table[2 * w->mb_x + !(w->mb_y & 1)]; // block[x ][y - 1]
395 3393 a = w->prediction_table[2 * w->mb_x - 2 + (w->mb_y & 1)]; // block[x - 1][y ]
396 3393 c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1]
397
398 3393 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
2/2
✓ Branch 0 taken 2565 times.
✓ Branch 1 taken 828 times.
3393 if ((w->mb_x & w->mb_y) != 0)
403 2565 w->est_run = FFMIN(c, w->est_run);
404 3393 w->est_run >>= 2;
405
406 3393 a &= 3;
407 3393 b &= 3;
408 3393 c &= 3;
409
410 3393 i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
411
2/2
✓ Branch 0 taken 3373 times.
✓ Branch 1 taken 20 times.
3393 if (i != 3)
412 3373 w->orient = i;
413 else
414
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
20 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 }
435
436 2761 static void x8_ac_compensation(IntraX8Context *const w, const int direction,
437 const int dc_level)
438 {
439 int t;
440 #define B(x,y) w->block[0][w->idct_permutation[(x) + (y) * 8]]
441 #define T(x) ((x) * dc_level + 0x8000) >> 16;
442
3/4
✓ Branch 0 taken 1946 times.
✓ Branch 1 taken 312 times.
✓ Branch 2 taken 503 times.
✗ Branch 3 not taken.
2761 switch (direction) {
443 1946 case 0:
444 1946 t = T(3811); // h
445 1946 B(1, 0) -= t;
446 1946 B(0, 1) -= t;
447
448 1946 t = T(487); // e
449 1946 B(2, 0) -= t;
450 1946 B(0, 2) -= t;
451
452 1946 t = T(506); // f
453 1946 B(3, 0) -= t;
454 1946 B(0, 3) -= t;
455
456 1946 t = T(135); // c
457 1946 B(4, 0) -= t;
458 1946 B(0, 4) -= t;
459 1946 B(2, 1) += t;
460 1946 B(1, 2) += t;
461 1946 B(3, 1) += t;
462 1946 B(1, 3) += t;
463
464 1946 t = T(173); // d
465 1946 B(5, 0) -= t;
466 1946 B(0, 5) -= t;
467
468 1946 t = T(61); // b
469 1946 B(6, 0) -= t;
470 1946 B(0, 6) -= t;
471 1946 B(5, 1) += t;
472 1946 B(1, 5) += t;
473
474 1946 t = T(42); // a
475 1946 B(7, 0) -= t;
476 1946 B(0, 7) -= t;
477 1946 B(4, 1) += t;
478 1946 B(1, 4) += t;
479 1946 B(4, 4) += t;
480
481 1946 t = T(1084); // g
482 1946 B(1, 1) += t;
483 1946 break;
484 312 case 1:
485 312 B(0, 1) -= T(6269);
486 312 B(0, 3) -= T(708);
487 312 B(0, 5) -= T(172);
488 312 B(0, 7) -= T(73);
489 312 break;
490 503 case 2:
491 503 B(1, 0) -= T(6269);
492 503 B(3, 0) -= T(708);
493 503 B(5, 0) -= T(172);
494 503 B(7, 0) -= T(73);
495 503 break;
496 }
497 #undef B
498 #undef T
499 2761 }
500
501 1365 static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
502 const ptrdiff_t linesize)
503 {
504 int k;
505
2/2
✓ Branch 0 taken 10920 times.
✓ Branch 1 taken 1365 times.
12285 for (k = 0; k < 8; k++) {
506 10920 memset(dst, pix, 8);
507 10920 dst += linesize;
508 }
509 1365 }
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 5400 static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
523 {
524 uint8_t *scantable;
525 int final, run, level;
526 int ac_mode, dc_mode, est_run, dc_level;
527 int pos, n;
528 int zeros_only;
529 int use_quant_matrix;
530 int sign;
531
532 av_assert2(w->orient < 12);
533 5400 w->bdsp.clear_block(w->block[0]);
534
535
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 3600 times.
5400 if (chroma)
536 1800 dc_mode = 2;
537 else
538 3600 dc_mode = !!w->est_run; // 0, 1
539
540
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5400 times.
5400 if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
541 return -1;
542 5400 n = 0;
543 5400 zeros_only = 0;
544
2/2
✓ Branch 0 taken 1693 times.
✓ Branch 1 taken 3707 times.
5400 if (!final) { // decode ac
545 1693 use_quant_matrix = w->use_quant_matrix;
546
2/2
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 1325 times.
1693 if (chroma) {
547 368 ac_mode = 1;
548 368 est_run = 64; // not used
549 } else {
550
2/2
✓ Branch 0 taken 905 times.
✓ Branch 1 taken 420 times.
1325 if (w->raw_orient < 3)
551 905 use_quant_matrix = 0;
552
553
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 1201 times.
1325 if (w->raw_orient > 4) {
554 124 ac_mode = 0;
555 124 est_run = 64;
556 } else {
557
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 661 times.
1201 if (w->est_run > 1) {
558 540 ac_mode = 2;
559 540 est_run = w->est_run;
560 } else {
561 661 ac_mode = 3;
562 661 est_run = 64;
563 }
564 }
565 }
566 1693 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 1693 scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3];
570 1693 pos = 0;
571 do {
572 8932 n++;
573
2/2
✓ Branch 0 taken 2216 times.
✓ Branch 1 taken 6716 times.
8932 if (n >= est_run) {
574 2216 ac_mode = 3;
575 2216 x8_select_ac_table(w, 3);
576 }
577
578 8932 x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
579
580 8932 pos += run + 1;
581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8932 times.
8932 if (pos > 63) {
582 // this also handles vlc error in x8_get_ac_rlf
583 return -1;
584 }
585 8932 level = (level + 1) * w->dquant;
586 8932 level += w->qsum;
587
588 8932 sign = -get_bits1(w->gb);
589 8932 level = (level ^ sign) - sign;
590
591
2/2
✓ Branch 0 taken 4784 times.
✓ Branch 1 taken 4148 times.
8932 if (use_quant_matrix)
592 4784 level = (level * quant_table[pos]) >> 8;
593
594 8932 w->block[0][scantable[pos]] = level;
595
2/2
✓ Branch 0 taken 7239 times.
✓ Branch 1 taken 1693 times.
8932 } while (!final);
596 } else { // DC only
597
4/4
✓ Branch 0 taken 1321 times.
✓ Branch 1 taken 2386 times.
✓ Branch 2 taken 1189 times.
✓ Branch 3 taken 132 times.
3707 if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1]
598 1189 int32_t divide_quant = !chroma ? w->divide_quant_dc_luma
599
2/2
✓ Branch 0 taken 529 times.
✓ Branch 1 taken 660 times.
1189 : w->divide_quant_dc_chroma;
600 1189 int32_t dc_quant = !chroma ? w->quant
601
2/2
✓ Branch 0 taken 529 times.
✓ Branch 1 taken 660 times.
1189 : w->quant_dc_chroma;
602
603 // original intent dc_level += predicted_dc/quant;
604 // but it got lost somewhere in the rounding
605 1189 dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
606
607 1189 dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
608 w->dest[chroma],
609 1189 w->frame->linesize[!!chroma]);
610
611 1189 goto block_placed;
612 }
613 2518 zeros_only = dc_level == 0;
614 }
615
2/2
✓ Branch 0 taken 3071 times.
✓ Branch 1 taken 1140 times.
4211 if (!chroma)
616 3071 w->block[0][0] = dc_level * w->quant;
617 else
618 1140 w->block[0][0] = dc_level * w->quant_dc_chroma;
619
620 // there is !zero_only check in the original, but dc_level check is enough
621
4/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 1428 times.
✓ Branch 2 taken 2780 times.
✓ Branch 3 taken 3 times.
4211 if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) {
622 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 2780 direction = (0x6A017C >> (w->orient * 2)) & 3;
626
2/2
✓ Branch 0 taken 2761 times.
✓ Branch 1 taken 19 times.
2780 if (direction != 3) {
627 2761 x8_ac_compensation(w, direction, w->block[0][0]);
628 }
629 }
630
631
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 4035 times.
4211 if (w->flat_dc) {
632 176 dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
633 176 w->frame->linesize[!!chroma]);
634 } else {
635 4035 w->dsp.spatial_compensation[w->orient](w->scratchpad,
636 w->dest[chroma],
637 4035 w->frame->linesize[!!chroma]);
638 }
639
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 3825 times.
4211 if (!zeros_only)
640 3825 w->wdsp.idct_add(w->dest[chroma],
641 3825 w->frame->linesize[!!chroma],
642 3825 w->block[0]);
643
644 386 block_placed:
645
2/2
✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 1800 times.
5400 if (!chroma)
646 3600 x8_update_predictions(w, w->orient, n);
647
648
1/2
✓ Branch 0 taken 5400 times.
✗ Branch 1 not taken.
5400 if (w->loopfilter) {
649 5400 uint8_t *ptr = w->dest[chroma];
650 5400 ptrdiff_t linesize = w->frame->linesize[!!chroma];
651
652
6/6
✓ Branch 0 taken 5160 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 386 times.
✓ Branch 3 taken 4774 times.
✓ Branch 4 taken 62 times.
✓ Branch 5 taken 324 times.
5400 if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))
653 4836 w->dsp.h_loop_filter(ptr, linesize, w->quant);
654
655
6/6
✓ Branch 0 taken 5220 times.
✓ Branch 1 taken 180 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 4837 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 371 times.
5400 if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
656 4849 w->dsp.v_loop_filter(ptr, linesize, w->quant);
657 }
658 5400 return 0;
659 }
660
661 // FIXME maybe merge with ff_*
662 90 static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
663 {
664 // not parent codec linesize as this would be wrong for field pics
665 // not that IntraX8 has interlacing support ;)
666 90 const ptrdiff_t linesize = frame->linesize[0];
667 90 const ptrdiff_t uvlinesize = frame->linesize[1];
668
669 90 w->dest[0] = frame->data[0];
670 90 w->dest[1] = frame->data[1];
671 90 w->dest[2] = frame->data[2];
672
673 90 w->dest[0] += w->mb_y * linesize << 3;
674 // chroma blocks are on add rows
675 90 w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2;
676 90 w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2;
677 90 }
678
679 46 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 {
684 static AVOnce init_static_once = AV_ONCE_INIT;
685
686 46 w->avctx = avctx;
687 46 w->mb_width = mb_width;
688 46 w->mb_height = mb_height;
689 46 w->block = block;
690
691 // two rows, 2 blocks per cannon mb
692 46 w->prediction_table = av_mallocz(w->mb_width * 2 * 2);
693
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (!w->prediction_table)
694 return AVERROR(ENOMEM);
695
696 46 ff_wmv2dsp_init(&w->wdsp);
697
698 46 ff_init_scantable_permutation(w->idct_permutation,
699 46 w->wdsp.idct_perm);
700
701 46 ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0],
702 46 w->idct_permutation);
703 46 ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2],
704 46 w->idct_permutation);
705 46 ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3],
706 46 w->idct_permutation);
707
708 46 ff_intrax8dsp_init(&w->dsp);
709 46 ff_blockdsp_init(&w->bdsp);
710
711 46 ff_thread_once(&init_static_once, x8_vlc_init);
712
713 46 return 0;
714 }
715
716 46 av_cold void ff_intrax8_common_end(IntraX8Context *w)
717 {
718 46 av_freep(&w->prediction_table);
719 46 }
720
721 3 int ff_intrax8_decode_picture(IntraX8Context *w, MPVPicture *pict,
722 GetBitContext *gb, int *mb_x, int *mb_y,
723 int dquant, int quant_offset,
724 int loopfilter, int lowdelay)
725 {
726 int mb_xy;
727
728 3 w->gb = gb;
729 3 w->dquant = dquant;
730 3 w->quant = dquant >> 1;
731 3 w->qsum = quant_offset;
732 3 w->frame = pict->f;
733 3 w->loopfilter = loopfilter;
734 3 w->use_quant_matrix = get_bits1(w->gb);
735
736 3 w->mb_x = *mb_x;
737 3 w->mb_y = *mb_y;
738
739 3 w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (w->quant < 5) {
741 w->quant_dc_chroma = w->quant;
742 w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
743 } else {
744 3 w->quant_dc_chroma = w->quant + ((w->quant + 3) >> 3);
745 3 w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
746 }
747 3 x8_reset_vlc_tables(w);
748
749
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 3 times.
93 for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) {
750 90 x8_init_block_index(w, w->frame);
751 90 mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
752
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
90 if (get_bits_left(gb) < 1)
753 goto error;
754
2/2
✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 90 times.
3690 for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
755 3600 x8_get_prediction(w);
756
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3600 times.
3600 if (x8_setup_spatial_predictor(w, 0))
757 goto error;
758
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3600 times.
3600 if (x8_decode_intra_mb(w, 0))
759 goto error;
760
761
2/2
✓ Branch 0 taken 900 times.
✓ Branch 1 taken 2700 times.
3600 if (w->mb_x & w->mb_y & 1) {
762 900 x8_get_prediction_chroma(w);
763
764 /* when setting up chroma, no vlc is read,
765 * so no error condition can be reached */
766 900 x8_setup_spatial_predictor(w, 1);
767
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 900 times.
900 if (x8_decode_intra_mb(w, 1))
768 goto error;
769
770 900 x8_setup_spatial_predictor(w, 2);
771
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 900 times.
900 if (x8_decode_intra_mb(w, 2))
772 goto error;
773
774 900 w->dest[1] += 8;
775 900 w->dest[2] += 8;
776
777 900 pict->qscale_table[mb_xy] = w->quant;
778 900 mb_xy++;
779 }
780 3600 w->dest[0] += 8;
781 }
782
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 45 times.
90 if (w->mb_y & 1)
783 45 ff_draw_horiz_band(w->avctx, w->frame, w->frame,
784 45 (w->mb_y - 1) * 8, 16,
785 PICT_FRAME, 0, lowdelay);
786 }
787
788 3 error:
789 3 *mb_x = w->mb_x;
790 3 *mb_y = w->mb_y;
791
792 3 return 0;
793 }
794