FFmpeg coverage


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