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