FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/intrax8.c
Date: 2024-06-18 05:56:57
Exec Total Coverage
Lines: 369 384 96.1%
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
484 1946 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
485 1946 break;
486 312 case 1:
487 312 B(0, 1) -= T(6269);
488 312 B(0, 3) -= T(708);
489 312 B(0, 5) -= T(172);
490 312 B(0, 7) -= T(73);
491
492 312 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
493 312 break;
494 503 case 2:
495 503 B(1, 0) -= T(6269);
496 503 B(3, 0) -= T(708);
497 503 B(5, 0) -= T(172);
498 503 B(7, 0) -= T(73);
499
500 503 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7);
501 503 break;
502 }
503 #undef B
504 #undef T
505 2761 }
506
507 1365 static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
508 const ptrdiff_t linesize)
509 {
510 int k;
511
2/2
✓ Branch 0 taken 10920 times.
✓ Branch 1 taken 1365 times.
12285 for (k = 0; k < 8; k++) {
512 10920 memset(dst, pix, 8);
513 10920 dst += linesize;
514 }
515 1365 }
516
517 static const int16_t quant_table[64] = {
518 256, 256, 256, 256, 256, 256, 259, 262,
519 265, 269, 272, 275, 278, 282, 285, 288,
520 292, 295, 299, 303, 306, 310, 314, 317,
521 321, 325, 329, 333, 337, 341, 345, 349,
522 353, 358, 362, 366, 371, 375, 379, 384,
523 389, 393, 398, 403, 408, 413, 417, 422,
524 428, 433, 438, 443, 448, 454, 459, 465,
525 470, 476, 482, 488, 493, 499, 505, 511,
526 };
527
528 5400 static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
529 {
530 uint8_t *scantable;
531 int final, run, level;
532 int ac_mode, dc_mode, est_run, dc_level;
533 int pos, n;
534 int zeros_only;
535 int use_quant_matrix;
536 int sign;
537
538 av_assert2(w->orient < 12);
539 5400 w->bdsp.clear_block(w->block[0]);
540
541
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 3600 times.
5400 if (chroma)
542 1800 dc_mode = 2;
543 else
544 3600 dc_mode = !!w->est_run; // 0, 1
545
546
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5400 times.
5400 if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
547 return -1;
548 5400 n = 0;
549 5400 zeros_only = 0;
550
2/2
✓ Branch 0 taken 1693 times.
✓ Branch 1 taken 3707 times.
5400 if (!final) { // decode ac
551 1693 use_quant_matrix = w->use_quant_matrix;
552
2/2
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 1325 times.
1693 if (chroma) {
553 368 ac_mode = 1;
554 368 est_run = 64; // not used
555 } else {
556
2/2
✓ Branch 0 taken 905 times.
✓ Branch 1 taken 420 times.
1325 if (w->raw_orient < 3)
557 905 use_quant_matrix = 0;
558
559
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 1201 times.
1325 if (w->raw_orient > 4) {
560 124 ac_mode = 0;
561 124 est_run = 64;
562 } else {
563
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 661 times.
1201 if (w->est_run > 1) {
564 540 ac_mode = 2;
565 540 est_run = w->est_run;
566 } else {
567 661 ac_mode = 3;
568 661 est_run = 64;
569 }
570 }
571 }
572 1693 x8_select_ac_table(w, ac_mode);
573 /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <-
574 * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */
575 1693 scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3];
576 1693 pos = 0;
577 do {
578 8932 n++;
579
2/2
✓ Branch 0 taken 2216 times.
✓ Branch 1 taken 6716 times.
8932 if (n >= est_run) {
580 2216 ac_mode = 3;
581 2216 x8_select_ac_table(w, 3);
582 }
583
584 8932 x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
585
586 8932 pos += run + 1;
587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8932 times.
8932 if (pos > 63) {
588 // this also handles vlc error in x8_get_ac_rlf
589 return -1;
590 }
591 8932 level = (level + 1) * w->dquant;
592 8932 level += w->qsum;
593
594 8932 sign = -get_bits1(w->gb);
595 8932 level = (level ^ sign) - sign;
596
597
2/2
✓ Branch 0 taken 4784 times.
✓ Branch 1 taken 4148 times.
8932 if (use_quant_matrix)
598 4784 level = (level * quant_table[pos]) >> 8;
599
600 8932 w->block[0][scantable[pos]] = level;
601
2/2
✓ Branch 0 taken 7239 times.
✓ Branch 1 taken 1693 times.
8932 } while (!final);
602
603 1693 w->block_last_index[0] = pos;
604 } else { // DC only
605 3707 w->block_last_index[0] = 0;
606
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]
607 1189 int32_t divide_quant = !chroma ? w->divide_quant_dc_luma
608
2/2
✓ Branch 0 taken 529 times.
✓ Branch 1 taken 660 times.
1189 : w->divide_quant_dc_chroma;
609 1189 int32_t dc_quant = !chroma ? w->quant
610
2/2
✓ Branch 0 taken 529 times.
✓ Branch 1 taken 660 times.
1189 : w->quant_dc_chroma;
611
612 // original intent dc_level += predicted_dc/quant;
613 // but it got lost somewhere in the rounding
614 1189 dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
615
616 1189 dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
617 w->dest[chroma],
618 1189 w->frame->linesize[!!chroma]);
619
620 1189 goto block_placed;
621 }
622 2518 zeros_only = dc_level == 0;
623 }
624
2/2
✓ Branch 0 taken 3071 times.
✓ Branch 1 taken 1140 times.
4211 if (!chroma)
625 3071 w->block[0][0] = dc_level * w->quant;
626 else
627 1140 w->block[0][0] = dc_level * w->quant_dc_chroma;
628
629 // there is !zero_only check in the original, but dc_level check is enough
630
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) {
631 int direction;
632 /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <-
633 * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */
634 2780 direction = (0x6A017C >> (w->orient * 2)) & 3;
635
2/2
✓ Branch 0 taken 2761 times.
✓ Branch 1 taken 19 times.
2780 if (direction != 3) {
636 // modify block_last[]
637 2761 x8_ac_compensation(w, direction, w->block[0][0]);
638 }
639 }
640
641
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 4035 times.
4211 if (w->flat_dc) {
642 176 dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
643 176 w->frame->linesize[!!chroma]);
644 } else {
645 4035 w->dsp.spatial_compensation[w->orient](w->scratchpad,
646 w->dest[chroma],
647 4035 w->frame->linesize[!!chroma]);
648 }
649
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 3825 times.
4211 if (!zeros_only)
650 3825 w->wdsp.idct_add(w->dest[chroma],
651 3825 w->frame->linesize[!!chroma],
652 3825 w->block[0]);
653
654 386 block_placed:
655
2/2
✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 1800 times.
5400 if (!chroma)
656 3600 x8_update_predictions(w, w->orient, n);
657
658
1/2
✓ Branch 0 taken 5400 times.
✗ Branch 1 not taken.
5400 if (w->loopfilter) {
659 5400 uint8_t *ptr = w->dest[chroma];
660 5400 ptrdiff_t linesize = w->frame->linesize[!!chroma];
661
662
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)))
663 4836 w->dsp.h_loop_filter(ptr, linesize, w->quant);
664
665
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)))
666 4849 w->dsp.v_loop_filter(ptr, linesize, w->quant);
667 }
668 5400 return 0;
669 }
670
671 // FIXME maybe merge with ff_*
672 90 static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
673 {
674 // not parent codec linesize as this would be wrong for field pics
675 // not that IntraX8 has interlacing support ;)
676 90 const ptrdiff_t linesize = frame->linesize[0];
677 90 const ptrdiff_t uvlinesize = frame->linesize[1];
678
679 90 w->dest[0] = frame->data[0];
680 90 w->dest[1] = frame->data[1];
681 90 w->dest[2] = frame->data[2];
682
683 90 w->dest[0] += w->mb_y * linesize << 3;
684 // chroma blocks are on add rows
685 90 w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2;
686 90 w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2;
687 90 }
688
689 46 av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
690 IntraX8Context *w,
691 int16_t (*block)[64],
692 int block_last_index[12],
693 int mb_width, int mb_height)
694 {
695 static AVOnce init_static_once = AV_ONCE_INIT;
696
697 46 w->avctx = avctx;
698 46 w->mb_width = mb_width;
699 46 w->mb_height = mb_height;
700 46 w->block = block;
701 46 w->block_last_index = block_last_index;
702
703 // two rows, 2 blocks per cannon mb
704 46 w->prediction_table = av_mallocz(w->mb_width * 2 * 2);
705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (!w->prediction_table)
706 return AVERROR(ENOMEM);
707
708 46 ff_wmv2dsp_init(&w->wdsp);
709
710 46 ff_init_scantable_permutation(w->idct_permutation,
711 46 w->wdsp.idct_perm);
712
713 46 ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0],
714 46 w->idct_permutation);
715 46 ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2],
716 46 w->idct_permutation);
717 46 ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3],
718 46 w->idct_permutation);
719
720 46 ff_intrax8dsp_init(&w->dsp);
721 46 ff_blockdsp_init(&w->bdsp);
722
723 46 ff_thread_once(&init_static_once, x8_vlc_init);
724
725 46 return 0;
726 }
727
728 46 av_cold void ff_intrax8_common_end(IntraX8Context *w)
729 {
730 46 av_freep(&w->prediction_table);
731 46 }
732
733 3 int ff_intrax8_decode_picture(IntraX8Context *w, MPVPicture *pict,
734 GetBitContext *gb, int *mb_x, int *mb_y,
735 int dquant, int quant_offset,
736 int loopfilter, int lowdelay)
737 {
738 int mb_xy;
739
740 3 w->gb = gb;
741 3 w->dquant = dquant;
742 3 w->quant = dquant >> 1;
743 3 w->qsum = quant_offset;
744 3 w->frame = pict->f;
745 3 w->loopfilter = loopfilter;
746 3 w->use_quant_matrix = get_bits1(w->gb);
747
748 3 w->mb_x = *mb_x;
749 3 w->mb_y = *mb_y;
750
751 3 w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (w->quant < 5) {
753 w->quant_dc_chroma = w->quant;
754 w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
755 } else {
756 3 w->quant_dc_chroma = w->quant + ((w->quant + 3) >> 3);
757 3 w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
758 }
759 3 x8_reset_vlc_tables(w);
760
761
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++) {
762 90 x8_init_block_index(w, w->frame);
763 90 mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
764
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
90 if (get_bits_left(gb) < 1)
765 goto error;
766
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++) {
767 3600 x8_get_prediction(w);
768
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3600 times.
3600 if (x8_setup_spatial_predictor(w, 0))
769 goto error;
770
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3600 times.
3600 if (x8_decode_intra_mb(w, 0))
771 goto error;
772
773
2/2
✓ Branch 0 taken 900 times.
✓ Branch 1 taken 2700 times.
3600 if (w->mb_x & w->mb_y & 1) {
774 900 x8_get_prediction_chroma(w);
775
776 /* when setting up chroma, no vlc is read,
777 * so no error condition can be reached */
778 900 x8_setup_spatial_predictor(w, 1);
779
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 900 times.
900 if (x8_decode_intra_mb(w, 1))
780 goto error;
781
782 900 x8_setup_spatial_predictor(w, 2);
783
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 900 times.
900 if (x8_decode_intra_mb(w, 2))
784 goto error;
785
786 900 w->dest[1] += 8;
787 900 w->dest[2] += 8;
788
789 900 pict->qscale_table[mb_xy] = w->quant;
790 900 mb_xy++;
791 }
792 3600 w->dest[0] += 8;
793 }
794
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 45 times.
90 if (w->mb_y & 1)
795 45 ff_draw_horiz_band(w->avctx, w->frame, w->frame,
796 45 (w->mb_y - 1) * 8, 16,
797 PICT_FRAME, 0, lowdelay);
798 }
799
800 3 error:
801 3 *mb_x = w->mb_x;
802 3 *mb_y = w->mb_y;
803
804 3 return 0;
805 }
806