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