FFmpeg coverage


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