Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Microsoft Screen 4 (aka Microsoft Expression Encoder Screen) decoder | ||
3 | * Copyright (c) 2012 Konstantin Shishkov | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * @file | ||
24 | * Microsoft Screen 4 (aka Microsoft Titanium Screen 2, | ||
25 | * aka Microsoft Expression Encoder Screen) decoder | ||
26 | */ | ||
27 | |||
28 | #include "libavutil/mem.h" | ||
29 | #include "libavutil/thread.h" | ||
30 | #include "libavutil/imgutils.h" | ||
31 | |||
32 | #include "avcodec.h" | ||
33 | #include "bytestream.h" | ||
34 | #include "codec_internal.h" | ||
35 | #include "decode.h" | ||
36 | #include "get_bits.h" | ||
37 | #include "jpegtables.h" | ||
38 | #include "mss34dsp.h" | ||
39 | #include "unary.h" | ||
40 | |||
41 | #define HEADER_SIZE 8 | ||
42 | |||
43 | enum FrameType { | ||
44 | INTRA_FRAME = 0, | ||
45 | INTER_FRAME, | ||
46 | SKIP_FRAME | ||
47 | }; | ||
48 | |||
49 | enum BlockType { | ||
50 | SKIP_BLOCK = 0, | ||
51 | DCT_BLOCK, | ||
52 | IMAGE_BLOCK, | ||
53 | }; | ||
54 | |||
55 | enum CachePos { | ||
56 | LEFT = 0, | ||
57 | TOP_LEFT, | ||
58 | TOP, | ||
59 | }; | ||
60 | |||
61 | static const uint8_t mss4_dc_vlc_lens[2][16] = { | ||
62 | { 0, 1, 5, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
63 | { 0, 3, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0 } | ||
64 | }; | ||
65 | |||
66 | static const uint8_t vec_len_syms[2][4] = { | ||
67 | { 4, 2, 3, 1 }, | ||
68 | { 4, 1, 2, 3 } | ||
69 | }; | ||
70 | |||
71 | static const uint8_t mss4_vec_entry_vlc_lens[2][16] = { | ||
72 | { 0, 2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
73 | { 0, 1, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } | ||
74 | }; | ||
75 | |||
76 | static const uint8_t mss4_vec_entry_vlc_syms[2][9] = { | ||
77 | { 0, 7, 6, 5, 8, 4, 3, 1, 2 }, | ||
78 | { 0, 2, 3, 4, 5, 6, 7, 1, 8 } | ||
79 | }; | ||
80 | |||
81 | #define MAX_ENTRIES 162 | ||
82 | |||
83 | typedef struct MSS4Context { | ||
84 | AVFrame *pic; | ||
85 | |||
86 | int block[64]; | ||
87 | uint8_t imgbuf[3][16 * 16]; | ||
88 | |||
89 | int quality; | ||
90 | uint16_t quant_mat[2][64]; | ||
91 | |||
92 | int *prev_dc[3]; | ||
93 | ptrdiff_t dc_stride[3]; | ||
94 | int dc_cache[4][4]; | ||
95 | |||
96 | int prev_vec[3][4]; | ||
97 | } MSS4Context; | ||
98 | |||
99 | static VLC dc_vlc[2], ac_vlc[2]; | ||
100 | static VLC vec_entry_vlc[2]; | ||
101 | |||
102 | 12 | static av_cold void mss4_init_vlc(VLC *vlc, unsigned *offset, | |
103 | const uint8_t *lens, const uint8_t *syms) | ||
104 | { | ||
105 | static VLCElem vlc_buf[2146]; | ||
106 | uint8_t bits[MAX_ENTRIES]; | ||
107 | int i, j; | ||
108 | 12 | int idx = 0; | |
109 | |||
110 |
2/2✓ Branch 0 taken 192 times.
✓ Branch 1 taken 12 times.
|
204 | for (i = 0; i < 16; i++) { |
111 |
2/2✓ Branch 0 taken 732 times.
✓ Branch 1 taken 192 times.
|
924 | for (j = 0; j < lens[i]; j++) { |
112 | 732 | bits[idx] = i + 1; | |
113 | 732 | idx++; | |
114 | } | ||
115 | } | ||
116 | |||
117 | 12 | vlc->table = &vlc_buf[*offset]; | |
118 | 12 | vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset; | |
119 | 12 | ff_vlc_init_from_lengths(vlc, FFMIN(bits[idx - 1], 9), idx, | |
120 | bits, 1, syms, 1, 1, | ||
121 | 0, VLC_INIT_STATIC_OVERLONG, NULL); | ||
122 | 12 | *offset += vlc->table_size; | |
123 | 12 | } | |
124 | |||
125 | 2 | static av_cold void mss4_init_vlcs(void) | |
126 | { | ||
127 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | for (unsigned i = 0, offset = 0; i < 2; i++) { |
128 | 4 | mss4_init_vlc(&dc_vlc[i], &offset, mss4_dc_vlc_lens[i], NULL); | |
129 |
4/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | mss4_init_vlc(&ac_vlc[i], &offset, |
130 | i ? ff_mjpeg_bits_ac_chrominance + 1 | ||
131 | : ff_mjpeg_bits_ac_luminance + 1, | ||
132 | i ? ff_mjpeg_val_ac_chrominance | ||
133 | : ff_mjpeg_val_ac_luminance); | ||
134 | 4 | mss4_init_vlc(&vec_entry_vlc[i], &offset, mss4_vec_entry_vlc_lens[i], | |
135 | 4 | mss4_vec_entry_vlc_syms[i]); | |
136 | } | ||
137 | 2 | } | |
138 | |||
139 | /* This function returns values in the range | ||
140 | * (-range + 1; -range/2] U [range/2; range - 1) | ||
141 | * i.e. | ||
142 | * nbits = 0 -> 0 | ||
143 | * nbits = 1 -> -1, 1 | ||
144 | * nbits = 2 -> -3, -2, 2, 3 | ||
145 | */ | ||
146 | 315916 | static av_always_inline int get_coeff_bits(GetBitContext *gb, int nbits) | |
147 | { | ||
148 | int val; | ||
149 | |||
150 |
2/2✓ Branch 0 taken 133329 times.
✓ Branch 1 taken 182587 times.
|
315916 | if (!nbits) |
151 | 133329 | return 0; | |
152 | |||
153 | 182587 | val = get_bits(gb, nbits); | |
154 |
2/2✓ Branch 0 taken 98069 times.
✓ Branch 1 taken 84518 times.
|
182587 | if (val < (1 << (nbits - 1))) |
155 | 98069 | val -= (1 << nbits) - 1; | |
156 | |||
157 | 182587 | return val; | |
158 | } | ||
159 | |||
160 | 180586 | static inline int get_coeff(GetBitContext *gb, const VLC *vlc, | |
161 | int nb_bits, int max_depth) | ||
162 | { | ||
163 | 180586 | int val = get_vlc2(gb, vlc->table, nb_bits, max_depth); | |
164 | |||
165 | 180586 | return get_coeff_bits(gb, val); | |
166 | } | ||
167 | |||
168 | 85284 | static int mss4_decode_dct(GetBitContext *gb, VLC *dc_vlc, VLC *ac_vlc, | |
169 | int *block, int *dc_cache, | ||
170 | int bx, int by, uint16_t *quant_mat) | ||
171 | { | ||
172 | 85284 | int skip, val, pos = 1, zz_pos, dc; | |
173 | |||
174 | 85284 | memset(block, 0, sizeof(*block) * 64); | |
175 | |||
176 | 85284 | dc = get_coeff(gb, dc_vlc, dc_vlc->bits, 2); | |
177 | // DC prediction is the same as in MSS3 | ||
178 |
2/2✓ Branch 0 taken 84904 times.
✓ Branch 1 taken 380 times.
|
85284 | if (by) { |
179 |
2/2✓ Branch 0 taken 83868 times.
✓ Branch 1 taken 1036 times.
|
84904 | if (bx) { |
180 | int l, tl, t; | ||
181 | |||
182 | 83868 | l = dc_cache[LEFT]; | |
183 | 83868 | tl = dc_cache[TOP_LEFT]; | |
184 | 83868 | t = dc_cache[TOP]; | |
185 | |||
186 |
2/2✓ Branch 0 taken 80876 times.
✓ Branch 1 taken 2992 times.
|
83868 | if (FFABS(t - tl) <= FFABS(l - tl)) |
187 | 80876 | dc += l; | |
188 | else | ||
189 | 2992 | dc += t; | |
190 | } else { | ||
191 | 1036 | dc += dc_cache[TOP]; | |
192 | } | ||
193 |
1/2✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
|
380 | } else if (bx) { |
194 | 380 | dc += dc_cache[LEFT]; | |
195 | } | ||
196 | 85284 | dc_cache[LEFT] = dc; | |
197 | 85284 | block[0] = dc * quant_mat[0]; | |
198 | |||
199 |
2/2✓ Branch 0 taken 219785 times.
✓ Branch 1 taken 897 times.
|
220682 | while (pos < 64) { |
200 | 219785 | val = get_vlc2(gb, ac_vlc->table, 9, 2); | |
201 |
2/2✓ Branch 0 taken 84387 times.
✓ Branch 1 taken 135398 times.
|
219785 | if (!val) |
202 | 84387 | return 0; | |
203 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 135398 times.
|
135398 | if (val == -1) |
204 | ✗ | return -1; | |
205 |
2/2✓ Branch 0 taken 68 times.
✓ Branch 1 taken 135330 times.
|
135398 | if (val == 0xF0) { |
206 | 68 | pos += 16; | |
207 | 68 | continue; | |
208 | } | ||
209 | 135330 | skip = val >> 4; | |
210 | 135330 | val = get_coeff_bits(gb, val & 0xF); | |
211 | 135330 | pos += skip; | |
212 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 135330 times.
|
135330 | if (pos >= 64) |
213 | ✗ | return -1; | |
214 | |||
215 | 135330 | zz_pos = ff_zigzag_direct[pos]; | |
216 | 135330 | block[zz_pos] = val * quant_mat[zz_pos]; | |
217 | 135330 | pos++; | |
218 | } | ||
219 | |||
220 |
1/2✓ Branch 0 taken 897 times.
✗ Branch 1 not taken.
|
897 | return pos == 64 ? 0 : -1; |
221 | } | ||
222 | |||
223 | 14214 | static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb, | |
224 | uint8_t *dst[3], int mb_x, int mb_y) | ||
225 | { | ||
226 | int i, j, k, ret; | ||
227 | 14214 | uint8_t *out = dst[0]; | |
228 | |||
229 |
2/2✓ Branch 0 taken 28428 times.
✓ Branch 1 taken 14214 times.
|
42642 | for (j = 0; j < 2; j++) { |
230 |
2/2✓ Branch 0 taken 56856 times.
✓ Branch 1 taken 28428 times.
|
85284 | for (i = 0; i < 2; i++) { |
231 | 56856 | int xpos = mb_x * 2 + i; | |
232 | 56856 | c->dc_cache[j][TOP_LEFT] = c->dc_cache[j][TOP]; | |
233 | 56856 | c->dc_cache[j][TOP] = c->prev_dc[0][mb_x * 2 + i]; | |
234 | 56856 | ret = mss4_decode_dct(gb, &dc_vlc[0], &ac_vlc[0], c->block, | |
235 | 56856 | c->dc_cache[j], | |
236 | 56856 | xpos, mb_y * 2 + j, c->quant_mat[0]); | |
237 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56856 times.
|
56856 | if (ret) |
238 | ✗ | return ret; | |
239 | 56856 | c->prev_dc[0][mb_x * 2 + i] = c->dc_cache[j][LEFT]; | |
240 | |||
241 | 56856 | ff_mss34_dct_put(out + xpos * 8, c->pic->linesize[0], | |
242 | 56856 | c->block); | |
243 | } | ||
244 | 28428 | out += 8 * c->pic->linesize[0]; | |
245 | } | ||
246 | |||
247 |
2/2✓ Branch 0 taken 28428 times.
✓ Branch 1 taken 14214 times.
|
42642 | for (i = 1; i < 3; i++) { |
248 | 28428 | c->dc_cache[i + 1][TOP_LEFT] = c->dc_cache[i + 1][TOP]; | |
249 | 28428 | c->dc_cache[i + 1][TOP] = c->prev_dc[i][mb_x]; | |
250 | 28428 | ret = mss4_decode_dct(gb, &dc_vlc[1], &ac_vlc[1], | |
251 | 28428 | c->block, c->dc_cache[i + 1], mb_x, mb_y, | |
252 | 28428 | c->quant_mat[1]); | |
253 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28428 times.
|
28428 | if (ret) |
254 | ✗ | return ret; | |
255 | 28428 | c->prev_dc[i][mb_x] = c->dc_cache[i + 1][LEFT]; | |
256 | |||
257 | 28428 | ff_mss34_dct_put(c->imgbuf[i], 8, c->block); | |
258 | 28428 | out = dst[i] + mb_x * 16; | |
259 | // Since the DCT block is coded as YUV420 and the whole frame as YUV444, | ||
260 | // we need to scale chroma. | ||
261 |
2/2✓ Branch 0 taken 454848 times.
✓ Branch 1 taken 28428 times.
|
483276 | for (j = 0; j < 16; j++) { |
262 |
2/2✓ Branch 0 taken 3638784 times.
✓ Branch 1 taken 454848 times.
|
4093632 | for (k = 0; k < 8; k++) |
263 | 3638784 | AV_WN16A(out + k * 2, c->imgbuf[i][k + (j & ~1) * 4] * 0x101); | |
264 | 454848 | out += c->pic->linesize[i]; | |
265 | } | ||
266 | } | ||
267 | |||
268 | 14214 | return 0; | |
269 | } | ||
270 | |||
271 | 281245 | static void read_vec_pos(GetBitContext *gb, int *vec_pos, int *sel_flag, | |
272 | int *sel_len, int *prev) | ||
273 | { | ||
274 | 281245 | int i, y_flag = 0; | |
275 | |||
276 |
2/2✓ Branch 0 taken 843735 times.
✓ Branch 1 taken 281245 times.
|
1124980 | for (i = 2; i >= 0; i--) { |
277 |
2/2✓ Branch 0 taken 192630 times.
✓ Branch 1 taken 651105 times.
|
843735 | if (!sel_flag[i]) { |
278 | 192630 | vec_pos[i] = 0; | |
279 | 192630 | continue; | |
280 | } | ||
281 |
6/6✓ Branch 0 taken 281245 times.
✓ Branch 1 taken 369860 times.
✓ Branch 2 taken 169880 times.
✓ Branch 3 taken 111365 times.
✓ Branch 5 taken 442701 times.
✓ Branch 6 taken 97039 times.
|
651105 | if ((!i && !y_flag) || get_bits1(gb)) { |
282 |
2/2✓ Branch 0 taken 549560 times.
✓ Branch 1 taken 4506 times.
|
554066 | if (sel_len[i] > 0) { |
283 | 549560 | int pval = prev[i]; | |
284 | 549560 | vec_pos[i] = get_bits(gb, sel_len[i]); | |
285 |
2/2✓ Branch 0 taken 297455 times.
✓ Branch 1 taken 252105 times.
|
549560 | if (vec_pos[i] >= pval) |
286 | 297455 | vec_pos[i]++; | |
287 | } else { | ||
288 | 4506 | vec_pos[i] = !prev[i]; | |
289 | } | ||
290 | 554066 | y_flag = 1; | |
291 | } else { | ||
292 | 97039 | vec_pos[i] = prev[i]; | |
293 | } | ||
294 | } | ||
295 | 281245 | } | |
296 | |||
297 | 8739072 | static int get_value_cached(GetBitContext *gb, int vec_pos, uint8_t *vec, | |
298 | int vec_size, int component, int shift, int *prev) | ||
299 | { | ||
300 |
2/2✓ Branch 0 taken 8442194 times.
✓ Branch 1 taken 296878 times.
|
8739072 | if (vec_pos < vec_size) |
301 | 8442194 | return vec[vec_pos]; | |
302 |
2/2✓ Branch 1 taken 46525 times.
✓ Branch 2 taken 250353 times.
|
296878 | if (!get_bits1(gb)) |
303 | 46525 | return prev[component]; | |
304 | 250353 | prev[component] = get_bits(gb, 8 - shift) << shift; | |
305 | 250353 | return prev[component]; | |
306 | } | ||
307 | |||
308 | #define MKVAL(vals) ((vals)[0] | ((vals)[1] << 3) | ((vals)[2] << 6)) | ||
309 | |||
310 | /* Image mode - the hardest to comprehend MSS4 coding mode. | ||
311 | * | ||
312 | * In this mode all three 16x16 blocks are coded together with a method | ||
313 | * remotely similar to the methods employed in MSS1-MSS3. | ||
314 | * The idea is that every component has a vector of 1-4 most common symbols | ||
315 | * and an escape mode for reading new value from the bitstream. Decoding | ||
316 | * consists of retrieving pixel values from the vector or reading new ones | ||
317 | * from the bitstream; depending on flags read from the bitstream, these vector | ||
318 | * positions can be updated or reused from the state of the previous line | ||
319 | * or previous pixel. | ||
320 | */ | ||
321 | 11379 | static int mss4_decode_image_block(MSS4Context *ctx, GetBitContext *gb, | |
322 | uint8_t *picdst[3], int mb_x, int mb_y) | ||
323 | { | ||
324 | uint8_t vec[3][4]; | ||
325 | int vec_len[3]; | ||
326 | int sel_len[3], sel_flag[3]; | ||
327 | int i, j, k, mode, split; | ||
328 | 11379 | int prev_vec1 = 0, prev_split = 0; | |
329 | 11379 | int vals[3] = { 0 }; | |
330 | 11379 | int prev_pix[3] = { 0 }; | |
331 | 11379 | int prev_mode[16] = { 0 }; | |
332 | uint8_t *dst[3]; | ||
333 | |||
334 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11379 times.
|
11379 | const int val_shift = ctx->quality == 100 ? 0 : 2; |
335 | |||
336 |
2/2✓ Branch 0 taken 34137 times.
✓ Branch 1 taken 11379 times.
|
45516 | for (i = 0; i < 3; i++) |
337 | 34137 | dst[i] = ctx->imgbuf[i]; | |
338 | |||
339 |
2/2✓ Branch 0 taken 34137 times.
✓ Branch 1 taken 11379 times.
|
45516 | for (i = 0; i < 3; i++) { |
340 | 34137 | vec_len[i] = vec_len_syms[!!i][get_unary(gb, 0, 3)]; | |
341 |
2/2✓ Branch 0 taken 95302 times.
✓ Branch 1 taken 34137 times.
|
129439 | for (j = 0; j < vec_len[i]; j++) { |
342 | 95302 | vec[i][j] = get_coeff(gb, &vec_entry_vlc[!!i], 5, 1); | |
343 | 95302 | vec[i][j] += ctx->prev_vec[i][j]; | |
344 | 95302 | ctx->prev_vec[i][j] = vec[i][j]; | |
345 | } | ||
346 | 34137 | sel_flag[i] = vec_len[i] > 1; | |
347 | 34137 | sel_len[i] = vec_len[i] > 2 ? vec_len[i] - 2 : 0; | |
348 | } | ||
349 | |||
350 |
2/2✓ Branch 0 taken 182064 times.
✓ Branch 1 taken 11379 times.
|
193443 | for (j = 0; j < 16; j++) { |
351 |
2/2✓ Branch 1 taken 56004 times.
✓ Branch 2 taken 126060 times.
|
182064 | if (get_bits1(gb)) { |
352 | 56004 | split = 0; | |
353 |
2/2✓ Branch 1 taken 35860 times.
✓ Branch 2 taken 20144 times.
|
56004 | if (get_bits1(gb)) { |
354 | 35860 | prev_mode[0] = 0; | |
355 | 35860 | vals[0] = vals[1] = vals[2] = 0; | |
356 | 35860 | mode = 2; | |
357 | } else { | ||
358 | 20144 | mode = get_bits1(gb); | |
359 |
2/2✓ Branch 0 taken 3817 times.
✓ Branch 1 taken 16327 times.
|
20144 | if (mode) |
360 | 3817 | split = get_bits(gb, 4); | |
361 | } | ||
362 |
2/2✓ Branch 0 taken 896064 times.
✓ Branch 1 taken 56004 times.
|
952068 | for (i = 0; i < 16; i++) { |
363 |
2/2✓ Branch 0 taken 322304 times.
✓ Branch 1 taken 573760 times.
|
896064 | if (mode <= 1) { |
364 | 322304 | vals[0] = prev_mode[i] & 7; | |
365 | 322304 | vals[1] = (prev_mode[i] >> 3) & 7; | |
366 | 322304 | vals[2] = prev_mode[i] >> 6; | |
367 |
4/4✓ Branch 0 taken 61072 times.
✓ Branch 1 taken 261232 times.
✓ Branch 2 taken 3817 times.
✓ Branch 3 taken 57255 times.
|
322304 | if (mode == 1 && i == split) { |
368 | 3817 | read_vec_pos(gb, vals, sel_flag, sel_len, vals); | |
369 | } | ||
370 |
1/2✓ Branch 0 taken 573760 times.
✗ Branch 1 not taken.
|
573760 | } else if (mode == 2) { |
371 |
2/2✓ Branch 1 taken 261389 times.
✓ Branch 2 taken 312371 times.
|
573760 | if (get_bits1(gb)) |
372 | 261389 | read_vec_pos(gb, vals, sel_flag, sel_len, vals); | |
373 | } | ||
374 |
2/2✓ Branch 0 taken 2688192 times.
✓ Branch 1 taken 896064 times.
|
3584256 | for (k = 0; k < 3; k++) |
375 | 2688192 | *dst[k]++ = get_value_cached(gb, vals[k], vec[k], | |
376 | vec_len[k], k, | ||
377 | val_shift, prev_pix); | ||
378 | 896064 | prev_mode[i] = MKVAL(vals); | |
379 | } | ||
380 | } else { | ||
381 |
2/2✓ Branch 1 taken 21425 times.
✓ Branch 2 taken 104635 times.
|
126060 | if (get_bits1(gb)) { |
382 | 21425 | split = get_bits(gb, 4); | |
383 |
2/2✓ Branch 0 taken 15525 times.
✓ Branch 1 taken 5900 times.
|
21425 | if (split >= prev_split) |
384 | 15525 | split++; | |
385 | 21425 | prev_split = split; | |
386 | } else { | ||
387 | 104635 | split = prev_split; | |
388 | } | ||
389 |
2/2✓ Branch 0 taken 109261 times.
✓ Branch 1 taken 16799 times.
|
126060 | if (split) { |
390 | 109261 | vals[0] = prev_mode[0] & 7; | |
391 | 109261 | vals[1] = (prev_mode[0] >> 3) & 7; | |
392 | 109261 | vals[2] = prev_mode[0] >> 6; | |
393 |
2/2✓ Branch 0 taken 327783 times.
✓ Branch 1 taken 109261 times.
|
437044 | for (i = 0; i < 3; i++) { |
394 |
2/2✓ Branch 0 taken 5114922 times.
✓ Branch 1 taken 327783 times.
|
5442705 | for (k = 0; k < split; k++) { |
395 | 5114922 | *dst[i]++ = get_value_cached(gb, vals[i], vec[i], | |
396 | vec_len[i], i, val_shift, | ||
397 | prev_pix); | ||
398 | 5114922 | prev_mode[k] = MKVAL(vals); | |
399 | } | ||
400 | } | ||
401 | } | ||
402 | |||
403 |
2/2✓ Branch 0 taken 22314 times.
✓ Branch 1 taken 103746 times.
|
126060 | if (split != 16) { |
404 | 22314 | vals[0] = prev_vec1 & 7; | |
405 | 22314 | vals[1] = (prev_vec1 >> 3) & 7; | |
406 | 22314 | vals[2] = prev_vec1 >> 6; | |
407 |
2/2✓ Branch 1 taken 16039 times.
✓ Branch 2 taken 6275 times.
|
22314 | if (get_bits1(gb)) { |
408 | 16039 | read_vec_pos(gb, vals, sel_flag, sel_len, vals); | |
409 | 16039 | prev_vec1 = MKVAL(vals); | |
410 | } | ||
411 |
2/2✓ Branch 0 taken 66942 times.
✓ Branch 1 taken 22314 times.
|
89256 | for (i = 0; i < 3; i++) { |
412 |
2/2✓ Branch 0 taken 935958 times.
✓ Branch 1 taken 66942 times.
|
1002900 | for (k = 0; k < 16 - split; k++) { |
413 | 935958 | *dst[i]++ = get_value_cached(gb, vals[i], vec[i], | |
414 | vec_len[i], i, val_shift, | ||
415 | prev_pix); | ||
416 | 935958 | prev_mode[split + k] = MKVAL(vals); | |
417 | } | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | |||
423 |
2/2✓ Branch 0 taken 34137 times.
✓ Branch 1 taken 11379 times.
|
45516 | for (i = 0; i < 3; i++) |
424 |
2/2✓ Branch 0 taken 546192 times.
✓ Branch 1 taken 34137 times.
|
580329 | for (j = 0; j < 16; j++) |
425 | 546192 | memcpy(picdst[i] + mb_x * 16 + j * ctx->pic->linesize[i], | |
426 | 546192 | ctx->imgbuf[i] + j * 16, 16); | |
427 | |||
428 | 11379 | return 0; | |
429 | } | ||
430 | |||
431 | 175050 | static inline void mss4_update_dc_cache(MSS4Context *c, int mb_x) | |
432 | { | ||
433 | int i; | ||
434 | |||
435 | 175050 | c->dc_cache[0][TOP] = c->prev_dc[0][mb_x * 2 + 1]; | |
436 | 175050 | c->dc_cache[0][LEFT] = 0; | |
437 | 175050 | c->dc_cache[1][TOP] = 0; | |
438 | 175050 | c->dc_cache[1][LEFT] = 0; | |
439 | |||
440 |
2/2✓ Branch 0 taken 350100 times.
✓ Branch 1 taken 175050 times.
|
525150 | for (i = 0; i < 2; i++) |
441 | 350100 | c->prev_dc[0][mb_x * 2 + i] = 0; | |
442 | |||
443 |
2/2✓ Branch 0 taken 350100 times.
✓ Branch 1 taken 175050 times.
|
525150 | for (i = 1; i < 3; i++) { |
444 | 350100 | c->dc_cache[i + 1][TOP] = c->prev_dc[i][mb_x]; | |
445 | 350100 | c->dc_cache[i + 1][LEFT] = 0; | |
446 | 350100 | c->prev_dc[i][mb_x] = 0; | |
447 | } | ||
448 | 175050 | } | |
449 | |||
450 | 145 | static int mss4_decode_frame(AVCodecContext *avctx, AVFrame *rframe, | |
451 | int *got_frame, AVPacket *avpkt) | ||
452 | { | ||
453 | 145 | const uint8_t *buf = avpkt->data; | |
454 | 145 | int buf_size = avpkt->size; | |
455 | 145 | MSS4Context *c = avctx->priv_data; | |
456 | GetBitContext gb; | ||
457 | GetByteContext bc; | ||
458 | uint8_t *dst[3]; | ||
459 | int width, height, quality, frame_type; | ||
460 | int x, y, i, mb_width, mb_height, blk_type; | ||
461 | int ret; | ||
462 | |||
463 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 145 times.
|
145 | if (buf_size < HEADER_SIZE) { |
464 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
465 | "Frame should have at least %d bytes, got %d instead\n", | ||
466 | HEADER_SIZE, buf_size); | ||
467 | ✗ | return AVERROR_INVALIDDATA; | |
468 | } | ||
469 | |||
470 | 145 | bytestream2_init(&bc, buf, buf_size); | |
471 | 145 | width = bytestream2_get_be16(&bc); | |
472 | 145 | height = bytestream2_get_be16(&bc); | |
473 | 145 | bytestream2_skip(&bc, 2); | |
474 | 145 | quality = bytestream2_get_byte(&bc); | |
475 | 145 | frame_type = bytestream2_get_byte(&bc); | |
476 | |||
477 |
1/2✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
|
145 | if (width > avctx->width || |
478 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 145 times.
|
145 | height != avctx->height) { |
479 | ✗ | av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d\n", | |
480 | width, height); | ||
481 | ✗ | return AVERROR_INVALIDDATA; | |
482 | } | ||
483 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
|
145 | if (av_image_check_size2(width, height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0) |
484 | ✗ | return AVERROR_INVALIDDATA; | |
485 | |||
486 |
2/4✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 145 times.
|
145 | if (quality < 1 || quality > 100) { |
487 | ✗ | av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality); | |
488 | ✗ | return AVERROR_INVALIDDATA; | |
489 | } | ||
490 |
2/4✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 145 times.
|
145 | if ((frame_type & ~3) || frame_type == 3) { |
491 | ✗ | av_log(avctx, AV_LOG_ERROR, "Invalid frame type %d\n", frame_type); | |
492 | ✗ | return AVERROR_INVALIDDATA; | |
493 | } | ||
494 | |||
495 |
3/4✓ Branch 0 taken 47 times.
✓ Branch 1 taken 98 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 47 times.
|
145 | if (frame_type != SKIP_FRAME && !bytestream2_get_bytes_left(&bc)) { |
496 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
497 | "Empty frame found but it is not a skip frame.\n"); | ||
498 | ✗ | return AVERROR_INVALIDDATA; | |
499 | } | ||
500 | 145 | mb_width = FFALIGN(width, 16) >> 4; | |
501 | 145 | mb_height = FFALIGN(height, 16) >> 4; | |
502 | |||
503 |
3/4✓ Branch 0 taken 47 times.
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47 times.
|
145 | if (frame_type != SKIP_FRAME && 8*buf_size < 8*HEADER_SIZE + mb_width*mb_height) |
504 | ✗ | return AVERROR_INVALIDDATA; | |
505 | |||
506 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
|
145 | if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0) |
507 | ✗ | return ret; | |
508 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 142 times.
|
145 | if (frame_type == INTRA_FRAME) |
509 | 3 | c->pic->flags |= AV_FRAME_FLAG_KEY; | |
510 | else | ||
511 | 142 | c->pic->flags &= ~AV_FRAME_FLAG_KEY; | |
512 | 145 | c->pic->pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I | |
513 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 142 times.
|
145 | : AV_PICTURE_TYPE_P; |
514 |
2/2✓ Branch 0 taken 98 times.
✓ Branch 1 taken 47 times.
|
145 | if (frame_type == SKIP_FRAME) { |
515 | 98 | *got_frame = 1; | |
516 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 98 times.
|
98 | if ((ret = av_frame_ref(rframe, c->pic)) < 0) |
517 | ✗ | return ret; | |
518 | |||
519 | 98 | return buf_size; | |
520 | } | ||
521 | |||
522 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 45 times.
|
47 | if (c->quality != quality) { |
523 | 2 | c->quality = quality; | |
524 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | for (i = 0; i < 2; i++) |
525 | 4 | ff_mss34_gen_quant_mat(c->quant_mat[i], quality, !i); | |
526 | } | ||
527 | |||
528 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
|
47 | if ((ret = init_get_bits8(&gb, buf + HEADER_SIZE, buf_size - HEADER_SIZE)) < 0) |
529 | ✗ | return ret; | |
530 | 47 | dst[0] = c->pic->data[0]; | |
531 | 47 | dst[1] = c->pic->data[1]; | |
532 | 47 | dst[2] = c->pic->data[2]; | |
533 | |||
534 | 47 | memset(c->prev_vec, 0, sizeof(c->prev_vec)); | |
535 |
2/2✓ Branch 0 taken 2472 times.
✓ Branch 1 taken 47 times.
|
2519 | for (y = 0; y < mb_height; y++) { |
536 | 2472 | memset(c->dc_cache, 0, sizeof(c->dc_cache)); | |
537 |
2/2✓ Branch 0 taken 189264 times.
✓ Branch 1 taken 2472 times.
|
191736 | for (x = 0; x < mb_width; x++) { |
538 | 189264 | blk_type = decode012(&gb); | |
539 |
3/4✓ Branch 0 taken 14214 times.
✓ Branch 1 taken 11379 times.
✓ Branch 2 taken 163671 times.
✗ Branch 3 not taken.
|
189264 | switch (blk_type) { |
540 | 14214 | case DCT_BLOCK: | |
541 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14214 times.
|
14214 | if (mss4_decode_dct_block(c, &gb, dst, x, y) < 0) { |
542 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
543 | "Error decoding DCT block %d,%d\n", | ||
544 | x, y); | ||
545 | ✗ | return AVERROR_INVALIDDATA; | |
546 | } | ||
547 | 14214 | break; | |
548 | 11379 | case IMAGE_BLOCK: | |
549 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 11379 times.
|
11379 | if (mss4_decode_image_block(c, &gb, dst, x, y) < 0) { |
550 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
551 | "Error decoding VQ block %d,%d\n", | ||
552 | x, y); | ||
553 | ✗ | return AVERROR_INVALIDDATA; | |
554 | } | ||
555 | 11379 | break; | |
556 | 163671 | case SKIP_BLOCK: | |
557 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163671 times.
|
163671 | if (frame_type == INTRA_FRAME) { |
558 | ✗ | av_log(avctx, AV_LOG_ERROR, "Skip block in intra frame\n"); | |
559 | ✗ | return AVERROR_INVALIDDATA; | |
560 | } | ||
561 | 163671 | break; | |
562 | } | ||
563 |
2/2✓ Branch 0 taken 175050 times.
✓ Branch 1 taken 14214 times.
|
189264 | if (blk_type != DCT_BLOCK) |
564 | 175050 | mss4_update_dc_cache(c, x); | |
565 | } | ||
566 | 2472 | dst[0] += c->pic->linesize[0] * 16; | |
567 | 2472 | dst[1] += c->pic->linesize[1] * 16; | |
568 | 2472 | dst[2] += c->pic->linesize[2] * 16; | |
569 | } | ||
570 | |||
571 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
|
47 | if ((ret = av_frame_ref(rframe, c->pic)) < 0) |
572 | ✗ | return ret; | |
573 | |||
574 | 47 | *got_frame = 1; | |
575 | |||
576 | 47 | return buf_size; | |
577 | } | ||
578 | |||
579 | 4 | static av_cold int mss4_decode_end(AVCodecContext *avctx) | |
580 | { | ||
581 | 4 | MSS4Context * const c = avctx->priv_data; | |
582 | int i; | ||
583 | |||
584 | 4 | av_frame_free(&c->pic); | |
585 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
|
16 | for (i = 0; i < 3; i++) |
586 | 12 | av_freep(&c->prev_dc[i]); | |
587 | |||
588 | 4 | return 0; | |
589 | } | ||
590 | |||
591 | 4 | static av_cold int mss4_decode_init(AVCodecContext *avctx) | |
592 | { | ||
593 | static AVOnce init_static_once = AV_ONCE_INIT; | ||
594 | 4 | MSS4Context * const c = avctx->priv_data; | |
595 | int i; | ||
596 | |||
597 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
|
16 | for (i = 0; i < 3; i++) { |
598 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
|
12 | c->dc_stride[i] = FFALIGN(avctx->width, 16) >> (2 + !!i); |
599 | 12 | c->prev_dc[i] = av_malloc_array(c->dc_stride[i], sizeof(**c->prev_dc)); | |
600 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (!c->prev_dc[i]) { |
601 | ✗ | av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n"); | |
602 | ✗ | return AVERROR(ENOMEM); | |
603 | } | ||
604 | } | ||
605 | |||
606 | 4 | c->pic = av_frame_alloc(); | |
607 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!c->pic) |
608 | ✗ | return AVERROR(ENOMEM); | |
609 | |||
610 | 4 | avctx->pix_fmt = AV_PIX_FMT_YUV444P; | |
611 | |||
612 | 4 | ff_thread_once(&init_static_once, mss4_init_vlcs); | |
613 | |||
614 | 4 | return 0; | |
615 | } | ||
616 | |||
617 | const FFCodec ff_mts2_decoder = { | ||
618 | .p.name = "mts2", | ||
619 | CODEC_LONG_NAME("MS Expression Encoder Screen"), | ||
620 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
621 | .p.id = AV_CODEC_ID_MTS2, | ||
622 | .priv_data_size = sizeof(MSS4Context), | ||
623 | .init = mss4_decode_init, | ||
624 | .close = mss4_decode_end, | ||
625 | FF_CODEC_DECODE_CB(mss4_decode_frame), | ||
626 | .p.capabilities = AV_CODEC_CAP_DR1, | ||
627 | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | ||
628 | }; | ||
629 |