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 |