/src/ffmpeg/libavcodec/mss2.c
Line | Count | Source |
1 | | /* |
2 | | * Microsoft Screen 2 (aka Windows Media Video V9 Screen) decoder |
3 | | * |
4 | | * This file is part of FFmpeg. |
5 | | * |
6 | | * FFmpeg is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * FFmpeg is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | * Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with FFmpeg; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | */ |
20 | | |
21 | | /** |
22 | | * @file |
23 | | * Microsoft Screen 2 (aka Windows Media Video V9 Screen) decoder |
24 | | */ |
25 | | |
26 | | #include "libavutil/avassert.h" |
27 | | #include "libavutil/mem.h" |
28 | | #include "codec_internal.h" |
29 | | #include "decode.h" |
30 | | #include "error_resilience.h" |
31 | | #include "mpeg_er.h" |
32 | | #include "mpegvideodec.h" |
33 | | #include "vc1.h" |
34 | | #include "wmv2data.h" |
35 | | #include "mss12.h" |
36 | | #include "mss2dsp.h" |
37 | | |
38 | | typedef struct MSS2Context { |
39 | | VC1Context v; |
40 | | int split_position; |
41 | | AVFrame *last_pic; |
42 | | MSS12Context c; |
43 | | MSS2DSPContext dsp; |
44 | | SliceContext sc[2]; |
45 | | } MSS2Context; |
46 | | |
47 | | static void arith2_normalise(ArithCoder *c) |
48 | 482M | { |
49 | 644M | while ((c->high >> 15) - (c->low >> 15) < 2) { |
50 | 161M | if ((c->low ^ c->high) & 0x10000) { |
51 | 166k | c->high ^= 0x8000; |
52 | 166k | c->value ^= 0x8000; |
53 | 166k | c->low ^= 0x8000; |
54 | 166k | } |
55 | 161M | c->high = (uint16_t)c->high << 8 | 0xFF; |
56 | 161M | c->value = (uint16_t)c->value << 8 | bytestream2_get_byte(c->gbc.gB); |
57 | 161M | c->low = (uint16_t)c->low << 8; |
58 | 161M | } |
59 | 482M | } |
60 | | |
61 | | ARITH_GET_BIT(arith2) |
62 | | |
63 | | /* L. Stuiver and A. Moffat: "Piecewise Integer Mapping for Arithmetic Coding." |
64 | | * In Proc. 8th Data Compression Conference (DCC '98), pp. 3-12, Mar. 1998 */ |
65 | | |
66 | | static int arith2_get_scaled_value(int value, int n, int range) |
67 | 481M | { |
68 | 481M | int split = (n << 1) - range; |
69 | | |
70 | 481M | if (value > split) |
71 | 8.24M | return split + (value - split >> 1); |
72 | 473M | else |
73 | 473M | return value; |
74 | 481M | } |
75 | | |
76 | | static void arith2_rescale_interval(ArithCoder *c, int range, |
77 | | int low, int high, int n) |
78 | 481M | { |
79 | 481M | int split = (n << 1) - range; |
80 | | |
81 | 481M | if (high > split) |
82 | 81.7M | c->high = split + (high - split << 1); |
83 | 400M | else |
84 | 400M | c->high = high; |
85 | | |
86 | 481M | c->high += c->low - 1; |
87 | | |
88 | 481M | if (low > split) |
89 | 884k | c->low += split + (low - split << 1); |
90 | 480M | else |
91 | 480M | c->low += low; |
92 | 481M | } |
93 | | |
94 | | static int arith2_get_number(ArithCoder *c, int n) |
95 | 322k | { |
96 | 322k | int range = c->high - c->low + 1; |
97 | 322k | int scale = av_log2(range) - av_log2(n); |
98 | 322k | int val; |
99 | | |
100 | 322k | if (n << scale > range) |
101 | 90.3k | scale--; |
102 | | |
103 | 322k | n <<= scale; |
104 | | |
105 | 322k | val = arith2_get_scaled_value(c->value - c->low, n, range) >> scale; |
106 | | |
107 | 322k | arith2_rescale_interval(c, range, val << scale, (val + 1) << scale, n); |
108 | | |
109 | 322k | arith2_normalise(c); |
110 | | |
111 | 322k | return val; |
112 | 322k | } |
113 | | |
114 | | static int arith2_get_prob(ArithCoder *c, int16_t *probs) |
115 | 481M | { |
116 | 481M | int range = c->high - c->low + 1, n = *probs; |
117 | 481M | int scale = av_log2(range) - av_log2(n); |
118 | 481M | int i = 0, val; |
119 | | |
120 | 481M | if (n << scale > range) |
121 | 264M | scale--; |
122 | | |
123 | 481M | n <<= scale; |
124 | | |
125 | 481M | val = arith2_get_scaled_value(c->value - c->low, n, range) >> scale; |
126 | 3.87G | while (probs[++i] > val) ; |
127 | | |
128 | 481M | arith2_rescale_interval(c, range, |
129 | 481M | probs[i] << scale, probs[i - 1] << scale, n); |
130 | | |
131 | 481M | return i; |
132 | 481M | } |
133 | | |
134 | | ARITH_GET_MODEL_SYM(arith2) |
135 | | |
136 | | static int arith2_get_consumed_bytes(ArithCoder *c) |
137 | 139k | { |
138 | 139k | int diff = (c->high >> 16) - (c->low >> 16); |
139 | 139k | int bp = bytestream2_tell(c->gbc.gB) - 3 << 3; |
140 | 139k | int bits = 1; |
141 | | |
142 | 662k | while (!(diff & 0x80)) { |
143 | 522k | bits++; |
144 | 522k | diff <<= 1; |
145 | 522k | } |
146 | | |
147 | 139k | return (bits + bp + 7 >> 3) + ((c->low >> 16) + 1 == c->high >> 16); |
148 | 139k | } |
149 | | |
150 | | static void arith2_init(ArithCoder *c, GetByteContext *gB) |
151 | 80.5k | { |
152 | 80.5k | c->low = 0; |
153 | 80.5k | c->high = 0xFFFFFF; |
154 | 80.5k | c->value = bytestream2_get_be24(gB); |
155 | 80.5k | c->overread = 0; |
156 | 80.5k | c->gbc.gB = gB; |
157 | 80.5k | c->get_model_sym = arith2_get_model_sym; |
158 | 80.5k | c->get_number = arith2_get_number; |
159 | 80.5k | } |
160 | | |
161 | | static int decode_pal_v2(MSS12Context *ctx, const uint8_t *buf, int buf_size) |
162 | 28.7k | { |
163 | 28.7k | int i, ncol; |
164 | 28.7k | uint32_t *pal = ctx->pal + 256 - ctx->free_colours; |
165 | | |
166 | 28.7k | if (!ctx->free_colours) |
167 | 24.4k | return 0; |
168 | | |
169 | 4.26k | ncol = *buf++; |
170 | 4.26k | if (ncol > ctx->free_colours || buf_size < 2 + ncol * 3) |
171 | 1.04k | return AVERROR_INVALIDDATA; |
172 | 13.1k | for (i = 0; i < ncol; i++) |
173 | 9.90k | *pal++ = AV_RB24(buf + 3 * i); |
174 | | |
175 | 3.22k | return 1 + ncol * 3; |
176 | 4.26k | } |
177 | | |
178 | | static int decode_555(AVCodecContext *avctx, GetByteContext *gB, uint16_t *dst, ptrdiff_t stride, |
179 | | int keyframe, int w, int h) |
180 | 4.10k | { |
181 | 4.10k | int last_symbol = 0, repeat = 0, prev_avail = 0; |
182 | | |
183 | 4.10k | if (!keyframe) { |
184 | 2.87k | int x, y, endx, endy, t; |
185 | | |
186 | 2.87k | #define READ_PAIR(a, b) \ |
187 | 5.75k | a = bytestream2_get_byte(gB) << 4; \ |
188 | 5.75k | t = bytestream2_get_byte(gB); \ |
189 | 5.75k | a |= t >> 4; \ |
190 | 5.75k | b = (t & 0xF) << 8; \ |
191 | 5.75k | b |= bytestream2_get_byte(gB); \ |
192 | 2.87k | |
193 | 2.87k | READ_PAIR(x, endx) |
194 | 2.87k | READ_PAIR(y, endy) |
195 | | |
196 | 2.87k | if (endx >= w || endy >= h || x > endx || y > endy) |
197 | 2.40k | return AVERROR_INVALIDDATA; |
198 | 472 | dst += x + stride * y; |
199 | 472 | w = endx - x + 1; |
200 | 472 | h = endy - y + 1; |
201 | 472 | if (y) |
202 | 202 | prev_avail = 1; |
203 | 472 | } |
204 | | |
205 | 248k | do { |
206 | 248k | uint16_t *p = dst; |
207 | 13.0M | do { |
208 | 13.0M | if (repeat-- < 1) { |
209 | 3.69M | int b = bytestream2_get_byte(gB); |
210 | 3.69M | if (b < 128) |
211 | 3.68M | last_symbol = b << 8 | bytestream2_get_byte(gB); |
212 | 6.67k | else if (b > 129) { |
213 | 5.07k | repeat = 0; |
214 | 11.7k | while (b-- > 130) { |
215 | 7.32k | if (repeat >= (INT_MAX >> 8) - 1) { |
216 | 677 | av_log(avctx, AV_LOG_ERROR, "repeat overflow\n"); |
217 | 677 | return AVERROR_INVALIDDATA; |
218 | 677 | } |
219 | 6.64k | repeat = (repeat << 8) + bytestream2_get_byte(gB) + 1; |
220 | 6.64k | } |
221 | 4.39k | if (last_symbol == -2) { |
222 | 1.33k | int skip = FFMIN((unsigned)repeat, dst + w - p); |
223 | 1.33k | repeat -= skip; |
224 | 1.33k | p += skip; |
225 | 1.33k | } |
226 | 4.39k | } else |
227 | 1.60k | last_symbol = 127 - b; |
228 | 3.69M | } |
229 | 13.0M | if (last_symbol >= 0) |
230 | 4.64M | *p = last_symbol; |
231 | 8.37M | else if (last_symbol == -1 && prev_avail) |
232 | 190k | *p = *(p - stride); |
233 | 13.0M | } while (++p < dst + w); |
234 | 247k | dst += stride; |
235 | 247k | prev_avail = 1; |
236 | 247k | } while (--h); |
237 | | |
238 | 1.02k | return 0; |
239 | 1.69k | } |
240 | | |
241 | | static int decode_rle(GetBitContext *gb, uint8_t *pal_dst, ptrdiff_t pal_stride, |
242 | | uint8_t *rgb_dst, ptrdiff_t rgb_stride, uint32_t *pal, |
243 | | int keyframe, int kf_slipt, int slice, int w, int h) |
244 | 34.1k | { |
245 | 34.1k | uint8_t bits[270] = { 0 }; |
246 | 34.1k | uint32_t codes[270]; |
247 | 34.1k | VLC vlc; |
248 | | |
249 | 34.1k | int current_length = 0, read_codes = 0, next_code = 0, current_codes = 0; |
250 | 34.1k | int remaining_codes, surplus_codes, i; |
251 | | |
252 | 34.1k | const int alphabet_size = 270 - keyframe; |
253 | | |
254 | 34.1k | int last_symbol = 0, repeat = 0, prev_avail = 0; |
255 | | |
256 | 34.1k | if (!keyframe) { |
257 | 5.12k | int x, y, clipw, cliph; |
258 | | |
259 | 5.12k | x = get_bits(gb, 12); |
260 | 5.12k | y = get_bits(gb, 12); |
261 | 5.12k | clipw = get_bits(gb, 12) + 1; |
262 | 5.12k | cliph = get_bits(gb, 12) + 1; |
263 | | |
264 | 5.12k | if (x + clipw > w || y + cliph > h) |
265 | 1.61k | return AVERROR_INVALIDDATA; |
266 | 3.51k | pal_dst += pal_stride * y + x; |
267 | 3.51k | rgb_dst += rgb_stride * y + x * 3; |
268 | 3.51k | w = clipw; |
269 | 3.51k | h = cliph; |
270 | 3.51k | if (y) |
271 | 335 | prev_avail = 1; |
272 | 29.0k | } else { |
273 | 29.0k | if (slice > 0) { |
274 | 10.5k | pal_dst += pal_stride * kf_slipt; |
275 | 10.5k | rgb_dst += rgb_stride * kf_slipt; |
276 | 10.5k | prev_avail = 1; |
277 | 10.5k | h -= kf_slipt; |
278 | 10.5k | } else |
279 | 18.5k | h = kf_slipt; |
280 | 29.0k | } |
281 | | |
282 | | /* read explicit codes */ |
283 | 159k | do { |
284 | 240k | while (current_codes--) { |
285 | 82.2k | int symbol = get_bits(gb, 8); |
286 | 82.2k | if (symbol >= 204 - keyframe) |
287 | 13.5k | symbol += 14 - keyframe; |
288 | 68.6k | else if (symbol > 189) |
289 | 2.29k | symbol = get_bits1(gb) + (symbol << 1) - 190; |
290 | 82.2k | if (bits[symbol]) |
291 | 1.69k | return AVERROR_INVALIDDATA; |
292 | 80.5k | bits[symbol] = current_length; |
293 | 80.5k | codes[symbol] = next_code++; |
294 | 80.5k | read_codes++; |
295 | 80.5k | } |
296 | 157k | current_length++; |
297 | 157k | next_code <<= 1; |
298 | 157k | remaining_codes = (1 << current_length) - next_code; |
299 | 157k | current_codes = get_bits(gb, av_ceil_log2(remaining_codes + 1)); |
300 | 157k | if (current_length > 22 || current_codes > remaining_codes) |
301 | 8.42k | return AVERROR_INVALIDDATA; |
302 | 157k | } while (current_codes != remaining_codes); |
303 | | |
304 | 22.4k | remaining_codes = alphabet_size - read_codes; |
305 | | |
306 | | /* determine the minimum length to fit the rest of the alphabet */ |
307 | 175k | while ((surplus_codes = (2 << current_length) - |
308 | 175k | (next_code << 1) - remaining_codes) < 0) { |
309 | 152k | current_length++; |
310 | 152k | next_code <<= 1; |
311 | 152k | } |
312 | | |
313 | | /* add the rest of the symbols lexicographically */ |
314 | 6.06M | for (i = 0; i < alphabet_size; i++) |
315 | 6.03M | if (!bits[i]) { |
316 | 5.97M | if (surplus_codes-- == 0) { |
317 | 22.1k | current_length++; |
318 | 22.1k | next_code <<= 1; |
319 | 22.1k | } |
320 | 5.97M | bits[i] = current_length; |
321 | 5.97M | codes[i] = next_code++; |
322 | 5.97M | } |
323 | | |
324 | 22.4k | if (next_code != 1 << current_length) |
325 | 259 | return AVERROR_INVALIDDATA; |
326 | | |
327 | 22.1k | if ((i = vlc_init(&vlc, 9, alphabet_size, bits, 1, 1, codes, 4, 4, 0)) < 0) |
328 | 198 | return i; |
329 | | |
330 | | /* frame decode */ |
331 | 581k | do { |
332 | 581k | uint8_t *pp = pal_dst; |
333 | 581k | uint8_t *rp = rgb_dst; |
334 | 187M | do { |
335 | 187M | if (repeat-- < 1) { |
336 | 63.6M | int b = get_vlc2(gb, vlc.table, 9, 3); |
337 | 63.6M | if (b < 256) |
338 | 63.5M | last_symbol = b; |
339 | 109k | else if (b < 268) { |
340 | 61.4k | b -= 256; |
341 | 61.4k | if (b == 11) |
342 | 4.05k | b = get_bits(gb, 4) + 10; |
343 | | |
344 | 61.4k | if (!b) |
345 | 21.7k | repeat = 0; |
346 | 39.6k | else |
347 | 39.6k | repeat = get_bits(gb, b); |
348 | | |
349 | 61.4k | repeat += (1 << b) - 1; |
350 | | |
351 | 61.4k | if (last_symbol == -2) { |
352 | 864 | int skip = FFMIN(repeat, pal_dst + w - pp); |
353 | 864 | repeat -= skip; |
354 | 864 | pp += skip; |
355 | 864 | rp += skip * 3; |
356 | 864 | } |
357 | 61.4k | } else |
358 | 48.3k | last_symbol = 267 - b; |
359 | 63.6M | } |
360 | 187M | if (last_symbol >= 0) { |
361 | 160M | *pp = last_symbol; |
362 | 160M | AV_WB24(rp, pal[last_symbol]); |
363 | 160M | } else if (last_symbol == -1 && prev_avail) { |
364 | 24.3M | *pp = *(pp - pal_stride); |
365 | 24.3M | memcpy(rp, rp - rgb_stride, 3); |
366 | 24.3M | } |
367 | 187M | rp += 3; |
368 | 187M | } while (++pp < pal_dst + w); |
369 | 581k | pal_dst += pal_stride; |
370 | 581k | rgb_dst += rgb_stride; |
371 | 581k | prev_avail = 1; |
372 | 581k | } while (--h); |
373 | | |
374 | 21.9k | ff_vlc_free(&vlc); |
375 | 21.9k | return 0; |
376 | 22.1k | } |
377 | | |
378 | | static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size, |
379 | | int x, int y, int w, int h, int wmv9_mask) |
380 | 34.7k | { |
381 | 34.7k | MSS2Context *ctx = avctx->priv_data; |
382 | 34.7k | MSS12Context *c = &ctx->c; |
383 | 34.7k | VC1Context *v = avctx->priv_data; |
384 | 34.7k | MpegEncContext *s = &v->s; |
385 | 34.7k | MPVWorkPicture *f; |
386 | 34.7k | int ret; |
387 | | |
388 | 34.7k | ff_mpeg_flush(avctx); |
389 | | |
390 | 34.7k | if ((ret = init_get_bits8(&v->gb, buf, buf_size)) < 0) |
391 | 0 | return ret; |
392 | | |
393 | 34.7k | v->loop_filter = avctx->skip_loop_filter < AVDISCARD_ALL; |
394 | | |
395 | 34.7k | if (ff_vc1_parse_frame_header(v, &v->gb) < 0) { |
396 | 7.03k | av_log(v->s.avctx, AV_LOG_ERROR, "header error\n"); |
397 | 7.03k | return AVERROR_INVALIDDATA; |
398 | 7.03k | } |
399 | | |
400 | 27.7k | if (s->pict_type != AV_PICTURE_TYPE_I) { |
401 | 10.7k | av_log(v->s.avctx, AV_LOG_ERROR, "expected I-frame\n"); |
402 | 10.7k | return AVERROR_INVALIDDATA; |
403 | 10.7k | } |
404 | | |
405 | 16.9k | avctx->pix_fmt = AV_PIX_FMT_YUV420P; |
406 | | |
407 | 16.9k | if ((ret = ff_mpv_frame_start(s, avctx)) < 0) { |
408 | 806 | av_log(v->s.avctx, AV_LOG_ERROR, "ff_mpv_frame_start error\n"); |
409 | 806 | avctx->pix_fmt = AV_PIX_FMT_RGB24; |
410 | 806 | return ret; |
411 | 806 | } |
412 | | |
413 | 16.1k | ff_mpeg_er_frame_start(s); |
414 | | |
415 | 16.1k | v->end_mb_x = (w + 15) >> 4; |
416 | 16.1k | s->end_mb_y = (h + 15) >> 4; |
417 | 16.1k | if (v->respic & 1) |
418 | 2.30k | v->end_mb_x = v->end_mb_x + 1 >> 1; |
419 | 16.1k | if (v->respic & 2) |
420 | 3.18k | s->end_mb_y = s->end_mb_y + 1 >> 1; |
421 | | |
422 | 16.1k | ff_vc1_decode_blocks(v); |
423 | | |
424 | 16.1k | if (v->end_mb_x == s->mb_width && s->end_mb_y == s->mb_height) { |
425 | 9.42k | ff_er_frame_end(&s->er, NULL); |
426 | 9.42k | } else { |
427 | 6.76k | av_log(v->s.avctx, AV_LOG_WARNING, |
428 | 6.76k | "disabling error correction due to block count mismatch %dx%d != %dx%d\n", |
429 | 6.76k | v->end_mb_x, s->end_mb_y, s->mb_width, s->mb_height); |
430 | 6.76k | } |
431 | | |
432 | 16.1k | ff_mpv_frame_end(s); |
433 | | |
434 | 16.1k | f = &s->cur_pic; |
435 | | |
436 | 16.1k | if (v->respic == 3) { |
437 | 2.21k | ctx->dsp.upsample_plane(f->data[0], f->linesize[0], w, h); |
438 | 2.21k | ctx->dsp.upsample_plane(f->data[1], f->linesize[1], w+1 >> 1, h+1 >> 1); |
439 | 2.21k | ctx->dsp.upsample_plane(f->data[2], f->linesize[2], w+1 >> 1, h+1 >> 1); |
440 | 13.9k | } else if (v->respic) |
441 | 1.04k | avpriv_request_sample(v->s.avctx, |
442 | 1.04k | "Asymmetric WMV9 rectangle subsampling"); |
443 | | |
444 | 16.1k | av_assert0(f->linesize[1] == f->linesize[2]); |
445 | | |
446 | 16.1k | if (wmv9_mask != -1) |
447 | 459 | ctx->dsp.mss2_blit_wmv9_masked(c->rgb_pic + y * c->rgb_stride + x * 3, |
448 | 459 | c->rgb_stride, wmv9_mask, |
449 | 459 | c->pal_pic + y * c->pal_stride + x, |
450 | 459 | c->pal_stride, |
451 | 459 | f->data[0], f->linesize[0], |
452 | 459 | f->data[1], f->data[2], f->linesize[1], |
453 | 459 | w, h); |
454 | 15.7k | else |
455 | 15.7k | ctx->dsp.mss2_blit_wmv9(c->rgb_pic + y * c->rgb_stride + x * 3, |
456 | 15.7k | c->rgb_stride, |
457 | 15.7k | f->data[0], f->linesize[0], |
458 | 15.7k | f->data[1], f->data[2], f->linesize[1], |
459 | 15.7k | w, h); |
460 | | |
461 | 16.1k | avctx->pix_fmt = AV_PIX_FMT_RGB24; |
462 | | |
463 | 16.1k | return 0; |
464 | 16.1k | } |
465 | | |
466 | | struct Rectangle { |
467 | | int coded, x, y, w, h; |
468 | | }; |
469 | | |
470 | | struct Rectangle2 { |
471 | | int left, right, top, bottom; |
472 | | }; |
473 | | |
474 | | static void calc_draw_region(struct Rectangle2 * draw, const struct Rectangle2 * rect) |
475 | 9.41k | { |
476 | 9.41k | #define COMPARE(top, bottom, left, right) \ |
477 | 18.8k | if (rect->top <= draw->top && rect->bottom >= draw->bottom) { \ |
478 | 10.9k | if (rect->left <= draw->left && rect->right >= draw->left) \ |
479 | 10.9k | draw->left = FFMIN(rect->right, draw->right); \ |
480 | 10.9k | \ |
481 | 10.9k | if (rect->right >= draw->right) { \ |
482 | 9.29k | if (rect->left >= draw->left) { \ |
483 | 5.48k | if (rect->left < draw->right) \ |
484 | 5.48k | draw->right = rect->left; \ |
485 | 5.48k | } else { \ |
486 | 3.80k | draw->right = draw->left; \ |
487 | 3.80k | } \ |
488 | 9.29k | } \ |
489 | 10.9k | } |
490 | | |
491 | 9.41k | COMPARE(top, bottom, left, right) |
492 | 9.41k | COMPARE(left, right, top, bottom) |
493 | 9.41k | } |
494 | | |
495 | | static int calc_split_position(int split_position, const struct Rectangle2 * rect, int height) |
496 | 4.09k | { |
497 | 4.09k | if (rect->top || rect->bottom != height) |
498 | 527 | split_position = rect->top + split_position * (rect->bottom - rect->top) / height; |
499 | | |
500 | 4.09k | return av_clip(split_position, rect->top + 1, rect->bottom - 1); |
501 | 4.09k | } |
502 | | |
503 | 55.2k | #define MAX_WMV9_RECTANGLES 20 |
504 | 80.5k | #define ARITH2_PADDING 2 |
505 | | |
506 | | static int mss2_decode_frame(AVCodecContext *avctx, AVFrame *frame, |
507 | | int *got_frame, AVPacket *avpkt) |
508 | 114k | { |
509 | 114k | const uint8_t *buf = avpkt->data; |
510 | 114k | int buf_size = avpkt->size; |
511 | 114k | MSS2Context *ctx = avctx->priv_data; |
512 | 114k | MSS12Context *c = &ctx->c; |
513 | 114k | GetBitContext gb; |
514 | 114k | GetByteContext gB; |
515 | 114k | ArithCoder acoder; |
516 | | |
517 | 114k | int keyframe, has_wmv9, has_mv, is_rle, is_555, ret; |
518 | | |
519 | 114k | struct Rectangle wmv9rects[MAX_WMV9_RECTANGLES], *r; |
520 | 114k | struct Rectangle2 draw; |
521 | 114k | int used_rects = 0, i, implicit_rect = 0, wmv9_mask = -1; |
522 | | |
523 | 114k | if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) |
524 | 0 | return ret; |
525 | | |
526 | 114k | if (keyframe = get_bits1(&gb)) |
527 | 48.5k | skip_bits(&gb, 7); |
528 | 114k | has_wmv9 = get_bits1(&gb); |
529 | 114k | has_mv = keyframe ? 0 : get_bits1(&gb); |
530 | 114k | is_rle = get_bits1(&gb); |
531 | 114k | is_555 = is_rle && get_bits1(&gb); |
532 | 114k | if (c->slice_split > 0) |
533 | 8.01k | ctx->split_position = c->slice_split; |
534 | 106k | else if (c->slice_split < 0) { |
535 | 48.2k | if (get_bits1(&gb)) { |
536 | 3.22k | if (get_bits1(&gb)) { |
537 | 2.06k | if (get_bits1(&gb)) |
538 | 1.25k | ctx->split_position = get_bits(&gb, 16); |
539 | 812 | else |
540 | 812 | ctx->split_position = get_bits(&gb, 12); |
541 | 2.06k | } else |
542 | 1.15k | ctx->split_position = get_bits(&gb, 8) << 4; |
543 | 45.0k | } else { |
544 | 45.0k | if (keyframe) |
545 | 25.4k | ctx->split_position = avctx->height / 2; |
546 | 45.0k | } |
547 | 48.2k | } else |
548 | 58.4k | ctx->split_position = avctx->height; |
549 | | |
550 | 114k | if (c->slice_split && (ctx->split_position < 1 - is_555 || |
551 | 55.9k | ctx->split_position > avctx->height - 1)) |
552 | 4.74k | return AVERROR_INVALIDDATA; |
553 | | |
554 | 109k | align_get_bits(&gb); |
555 | 109k | buf += get_bits_count(&gb) >> 3; |
556 | 109k | buf_size -= get_bits_count(&gb) >> 3; |
557 | | |
558 | 109k | if (buf_size < 1) |
559 | 15.0k | return AVERROR_INVALIDDATA; |
560 | | |
561 | 94.9k | if (is_555 && (has_wmv9 || has_mv || c->slice_split && ctx->split_position)) |
562 | 1.61k | return AVERROR_INVALIDDATA; |
563 | | |
564 | 93.3k | avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24; |
565 | 93.3k | if (ctx->last_pic->format != avctx->pix_fmt) |
566 | 5.23k | av_frame_unref(ctx->last_pic); |
567 | | |
568 | 93.3k | if (has_wmv9) { |
569 | 55.5k | bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING); |
570 | 55.5k | arith2_init(&acoder, &gB); |
571 | | |
572 | 55.5k | implicit_rect = !arith2_get_bit(&acoder); |
573 | | |
574 | 110k | while (arith2_get_bit(&acoder)) { |
575 | 55.2k | if (used_rects == MAX_WMV9_RECTANGLES) |
576 | 223 | return AVERROR_INVALIDDATA; |
577 | 55.0k | r = &wmv9rects[used_rects]; |
578 | 55.0k | if (!used_rects) |
579 | 13.6k | r->x = arith2_get_number(&acoder, avctx->width); |
580 | 41.3k | else |
581 | 41.3k | r->x = arith2_get_number(&acoder, avctx->width - |
582 | 41.3k | wmv9rects[used_rects - 1].x) + |
583 | 41.3k | wmv9rects[used_rects - 1].x; |
584 | 55.0k | r->y = arith2_get_number(&acoder, avctx->height); |
585 | 55.0k | r->w = arith2_get_number(&acoder, avctx->width - r->x) + 1; |
586 | 55.0k | r->h = arith2_get_number(&acoder, avctx->height - r->y) + 1; |
587 | 55.0k | used_rects++; |
588 | 55.0k | } |
589 | | |
590 | 55.2k | if (implicit_rect && used_rects) { |
591 | 770 | av_log(avctx, AV_LOG_ERROR, "implicit_rect && used_rects > 0\n"); |
592 | 770 | return AVERROR_INVALIDDATA; |
593 | 770 | } |
594 | | |
595 | 54.5k | if (implicit_rect) { |
596 | 40.5k | wmv9rects[0].x = 0; |
597 | 40.5k | wmv9rects[0].y = 0; |
598 | 40.5k | wmv9rects[0].w = avctx->width; |
599 | 40.5k | wmv9rects[0].h = avctx->height; |
600 | | |
601 | 40.5k | used_rects = 1; |
602 | 40.5k | } |
603 | 136k | for (i = 0; i < used_rects; i++) { |
604 | 83.8k | if (!implicit_rect && arith2_get_bit(&acoder)) { |
605 | 1.64k | av_log(avctx, AV_LOG_ERROR, "Unexpected grandchildren\n"); |
606 | 1.64k | return AVERROR_INVALIDDATA; |
607 | 1.64k | } |
608 | 82.1k | if (!i) { |
609 | 52.5k | wmv9_mask = arith2_get_bit(&acoder) - 1; |
610 | 52.5k | if (!wmv9_mask) |
611 | 3.33k | wmv9_mask = arith2_get_number(&acoder, 256); |
612 | 52.5k | } |
613 | 82.1k | wmv9rects[i].coded = arith2_get_number(&acoder, 2); |
614 | 82.1k | } |
615 | | |
616 | 52.8k | buf += arith2_get_consumed_bytes(&acoder); |
617 | 52.8k | buf_size -= arith2_get_consumed_bytes(&acoder); |
618 | 52.8k | if (buf_size < 1) |
619 | 864 | return AVERROR_INVALIDDATA; |
620 | 52.8k | } |
621 | | |
622 | 89.8k | c->mvX = c->mvY = 0; |
623 | 89.8k | if (keyframe && !is_555) { |
624 | 28.7k | if ((i = decode_pal_v2(c, buf, buf_size)) < 0) |
625 | 1.04k | return AVERROR_INVALIDDATA; |
626 | 27.6k | buf += i; |
627 | 27.6k | buf_size -= i; |
628 | 61.1k | } else if (has_mv) { |
629 | 9.74k | buf += 4; |
630 | 9.74k | buf_size -= 4; |
631 | 9.74k | if (buf_size < 1) |
632 | 379 | return AVERROR_INVALIDDATA; |
633 | 9.36k | c->mvX = AV_RB16(buf - 4) - avctx->width; |
634 | 9.36k | c->mvY = AV_RB16(buf - 2) - avctx->height; |
635 | 9.36k | } |
636 | | |
637 | 88.4k | if (c->mvX < 0 || c->mvY < 0) { |
638 | 7.20k | FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic); |
639 | | |
640 | 7.20k | if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) |
641 | 0 | return ret; |
642 | | |
643 | 7.20k | if (ctx->last_pic->data[0]) { |
644 | 6.94k | av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]); |
645 | 6.94k | c->last_rgb_pic = ctx->last_pic->data[0] + |
646 | 6.94k | ctx->last_pic->linesize[0] * (avctx->height - 1); |
647 | 6.94k | } else { |
648 | 258 | av_log(avctx, AV_LOG_ERROR, "Missing keyframe\n"); |
649 | 258 | return AVERROR_INVALIDDATA; |
650 | 258 | } |
651 | 81.2k | } else { |
652 | 81.2k | if ((ret = ff_reget_buffer(avctx, ctx->last_pic, 0)) < 0) |
653 | 0 | return ret; |
654 | 81.2k | if ((ret = av_frame_ref(frame, ctx->last_pic)) < 0) |
655 | 0 | return ret; |
656 | | |
657 | 81.2k | c->last_rgb_pic = NULL; |
658 | 81.2k | } |
659 | 88.1k | c->rgb_pic = frame->data[0] + |
660 | 88.1k | frame->linesize[0] * (avctx->height - 1); |
661 | 88.1k | c->rgb_stride = -frame->linesize[0]; |
662 | | |
663 | 88.1k | if (keyframe) |
664 | 28.9k | frame->flags |= AV_FRAME_FLAG_KEY; |
665 | 59.2k | else |
666 | 59.2k | frame->flags &= ~AV_FRAME_FLAG_KEY; |
667 | 88.1k | frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; |
668 | | |
669 | 88.1k | if (is_555) { |
670 | 4.10k | bytestream2_init(&gB, buf, buf_size); |
671 | | |
672 | 4.10k | if (decode_555(avctx, &gB, (uint16_t *)c->rgb_pic, c->rgb_stride >> 1, |
673 | 4.10k | keyframe, avctx->width, avctx->height)) |
674 | 3.08k | return AVERROR_INVALIDDATA; |
675 | | |
676 | 1.02k | buf_size -= bytestream2_tell(&gB); |
677 | 84.0k | } else { |
678 | 84.0k | if (keyframe) { |
679 | 27.6k | c->corrupted = 0; |
680 | 27.6k | ff_mss12_slicecontext_reset(&ctx->sc[0]); |
681 | 27.6k | if (c->slice_split) |
682 | 15.4k | ff_mss12_slicecontext_reset(&ctx->sc[1]); |
683 | 27.6k | } |
684 | 84.0k | if (is_rle) { |
685 | 22.8k | if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) |
686 | 0 | return ret; |
687 | 22.8k | if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride, |
688 | 22.8k | c->rgb_pic, c->rgb_stride, c->pal, keyframe, |
689 | 22.8k | ctx->split_position, 0, |
690 | 22.8k | avctx->width, avctx->height)) |
691 | 8.16k | return ret; |
692 | 14.7k | align_get_bits(&gb); |
693 | | |
694 | 14.7k | if (c->slice_split) |
695 | 11.3k | if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride, |
696 | 11.3k | c->rgb_pic, c->rgb_stride, c->pal, keyframe, |
697 | 11.3k | ctx->split_position, 1, |
698 | 11.3k | avctx->width, avctx->height)) |
699 | 4.02k | return ret; |
700 | | |
701 | 10.6k | align_get_bits(&gb); |
702 | 10.6k | buf += get_bits_count(&gb) >> 3; |
703 | 10.6k | buf_size -= get_bits_count(&gb) >> 3; |
704 | 61.2k | } else if (!implicit_rect || wmv9_mask != -1) { |
705 | 25.6k | if (c->corrupted) |
706 | 3.06k | return AVERROR_INVALIDDATA; |
707 | 22.5k | bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING); |
708 | 22.5k | arith2_init(&acoder, &gB); |
709 | 22.5k | c->keyframe = keyframe; |
710 | | |
711 | 22.5k | draw.left = 0; |
712 | 22.5k | draw.top = 0; |
713 | 22.5k | draw.right = avctx->width; |
714 | 22.5k | draw.bottom = avctx->height; |
715 | 22.5k | if (wmv9_mask == -1) { |
716 | 30.1k | for (i = 0; i < used_rects; i++) { |
717 | 9.41k | struct Rectangle2 r; |
718 | 9.41k | r.left = wmv9rects[i].x; |
719 | 9.41k | r.top = wmv9rects[i].y; |
720 | 9.41k | r.right = r.left + wmv9rects[i].w; |
721 | 9.41k | r.bottom = r.top + wmv9rects[i].h; |
722 | 9.41k | calc_draw_region(&draw, &r); |
723 | 9.41k | } |
724 | 20.7k | } |
725 | | |
726 | 22.5k | if (draw.left >= avctx->width || draw.right > avctx->width || |
727 | 21.6k | draw.top >= avctx->height || draw.bottom > avctx->height) |
728 | 906 | return AVERROR_INVALIDDATA; |
729 | | |
730 | 21.6k | if (c->slice_split && draw.bottom - draw.top >= 10) { |
731 | 4.09k | ctx->split_position = calc_split_position(ctx->split_position, &draw, avctx->height); |
732 | 4.09k | if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, draw.top, |
733 | 4.09k | avctx->width, |
734 | 4.09k | ctx->split_position - draw.top)) |
735 | 1.11k | return AVERROR_INVALIDDATA; |
736 | 2.98k | buf += arith2_get_consumed_bytes(&acoder); |
737 | 2.98k | buf_size -= arith2_get_consumed_bytes(&acoder); |
738 | 2.98k | if (c->slice_split) { |
739 | 2.98k | if (buf_size < 1) |
740 | 536 | return AVERROR_INVALIDDATA; |
741 | 2.44k | bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING); |
742 | 2.44k | arith2_init(&acoder, &gB); |
743 | 2.44k | if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0, |
744 | 2.44k | ctx->split_position, |
745 | 2.44k | avctx->width, |
746 | 2.44k | draw.bottom - ctx->split_position)) |
747 | 523 | return AVERROR_INVALIDDATA; |
748 | 1.92k | buf += arith2_get_consumed_bytes(&acoder); |
749 | 1.92k | buf_size -= arith2_get_consumed_bytes(&acoder); |
750 | 1.92k | } |
751 | 17.5k | } else { |
752 | 17.5k | if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, draw.left, draw.top, |
753 | 17.5k | draw.right - draw.left, draw.bottom - draw.top)) |
754 | 5.70k | return AVERROR_INVALIDDATA; |
755 | | |
756 | 11.8k | buf += arith2_get_consumed_bytes(&acoder); |
757 | 11.8k | buf_size -= arith2_get_consumed_bytes(&acoder); |
758 | 11.8k | } |
759 | 21.6k | } else |
760 | 35.5k | memset(c->pal_pic, 0, c->pal_stride * avctx->height); |
761 | 84.0k | } |
762 | | |
763 | 61.0k | if (has_wmv9) { |
764 | 67.4k | for (i = 0; i < used_rects; i++) { |
765 | 46.9k | int x = wmv9rects[i].x; |
766 | 46.9k | int y = wmv9rects[i].y; |
767 | 46.9k | int w = wmv9rects[i].w; |
768 | 46.9k | int h = wmv9rects[i].h; |
769 | 46.9k | if (wmv9rects[i].coded) { |
770 | 37.3k | int WMV9codedFrameSize; |
771 | 37.3k | if (buf_size < 4 || !(WMV9codedFrameSize = AV_RL24(buf))) |
772 | 2.59k | return AVERROR_INVALIDDATA; |
773 | 34.7k | if (ret = decode_wmv9(avctx, buf + 3, buf_size - 3, |
774 | 34.7k | x, y, w, h, wmv9_mask)) |
775 | 18.6k | return ret; |
776 | 16.1k | buf += WMV9codedFrameSize + 3; |
777 | 16.1k | buf_size -= WMV9codedFrameSize + 3; |
778 | 16.1k | } else { |
779 | 9.55k | uint8_t *dst = c->rgb_pic + y * c->rgb_stride + x * 3; |
780 | 9.55k | if (wmv9_mask != -1) { |
781 | 749 | ctx->dsp.mss2_gray_fill_masked(dst, c->rgb_stride, |
782 | 749 | wmv9_mask, |
783 | 749 | c->pal_pic + y * c->pal_stride + x, |
784 | 749 | c->pal_stride, |
785 | 749 | w, h); |
786 | 8.81k | } else { |
787 | 350k | do { |
788 | 350k | memset(dst, 0x80, w * 3); |
789 | 350k | dst += c->rgb_stride; |
790 | 350k | } while (--h); |
791 | 8.81k | } |
792 | 9.55k | } |
793 | 46.9k | } |
794 | 41.7k | } |
795 | | |
796 | 39.8k | if (buf_size) |
797 | 36.2k | av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n"); |
798 | | |
799 | 39.8k | if (c->mvX < 0 || c->mvY < 0) { |
800 | 2.27k | ret = av_frame_replace(ctx->last_pic, frame); |
801 | 2.27k | if (ret < 0) |
802 | 0 | return ret; |
803 | 2.27k | } |
804 | | |
805 | 39.8k | *got_frame = 1; |
806 | | |
807 | 39.8k | return avpkt->size; |
808 | 39.8k | } |
809 | | |
810 | | static av_cold int wmv9_init(AVCodecContext *avctx) |
811 | 2.18k | { |
812 | 2.18k | VC1Context *v = avctx->priv_data; |
813 | 2.18k | int ret; |
814 | | |
815 | 2.18k | v->s.avctx = avctx; |
816 | | |
817 | 2.18k | ff_vc1_init_common(v); |
818 | | |
819 | 2.18k | v->profile = PROFILE_MAIN; |
820 | | |
821 | 2.18k | v->zz_8x4 = ff_wmv2_scantableA; |
822 | 2.18k | v->zz_4x8 = ff_wmv2_scantableB; |
823 | 2.18k | v->res_y411 = 0; |
824 | 2.18k | v->res_sprite = 0; |
825 | | |
826 | 2.18k | v->frmrtq_postproc = 7; |
827 | 2.18k | v->bitrtq_postproc = 31; |
828 | | |
829 | 2.18k | v->res_x8 = 0; |
830 | 2.18k | v->multires = 0; |
831 | 2.18k | v->res_fasttx = 1; |
832 | | |
833 | 2.18k | v->fastuvmc = 0; |
834 | | |
835 | 2.18k | v->extended_mv = 0; |
836 | | |
837 | 2.18k | v->dquant = 1; |
838 | 2.18k | v->vstransform = 1; |
839 | | |
840 | 2.18k | v->res_transtab = 0; |
841 | | |
842 | 2.18k | v->overlap = 0; |
843 | | |
844 | 2.18k | v->resync_marker = 0; |
845 | 2.18k | v->rangered = 0; |
846 | | |
847 | 2.18k | v->max_b_frames = avctx->max_b_frames = 0; |
848 | 2.18k | v->quantizer_mode = 0; |
849 | | |
850 | 2.18k | v->finterpflag = 0; |
851 | | |
852 | 2.18k | v->res_rtm_flag = 1; |
853 | | |
854 | 2.18k | ff_vc1_init_transposed_scantables(v); |
855 | | |
856 | 2.18k | ret = ff_vc1_decode_init(avctx); |
857 | 2.18k | if (ret < 0) |
858 | 1 | return ret; |
859 | | |
860 | 2.18k | return 0; |
861 | 2.18k | } |
862 | | |
863 | | static av_cold int mss2_decode_end(AVCodecContext *avctx) |
864 | 2.57k | { |
865 | 2.57k | MSS2Context *const ctx = avctx->priv_data; |
866 | | |
867 | 2.57k | av_frame_free(&ctx->last_pic); |
868 | | |
869 | 2.57k | ff_mss12_decode_end(&ctx->c); |
870 | 2.57k | av_freep(&ctx->c.pal_pic); |
871 | 2.57k | av_freep(&ctx->c.last_pal_pic); |
872 | 2.57k | ff_vc1_decode_end(avctx); |
873 | | |
874 | 2.57k | return 0; |
875 | 2.57k | } |
876 | | |
877 | | static av_cold int mss2_decode_init(AVCodecContext *avctx) |
878 | 2.57k | { |
879 | 2.57k | MSS2Context * const ctx = avctx->priv_data; |
880 | 2.57k | MSS12Context *c = &ctx->c; |
881 | 2.57k | int ret; |
882 | 2.57k | c->avctx = avctx; |
883 | 2.57k | if (ret = ff_mss12_decode_init(c, 1, &ctx->sc[0], &ctx->sc[1])) |
884 | 390 | return ret; |
885 | 2.18k | ctx->last_pic = av_frame_alloc(); |
886 | 2.18k | c->pal_stride = c->mask_stride; |
887 | 2.18k | c->pal_pic = av_mallocz(c->pal_stride * avctx->height); |
888 | 2.18k | c->last_pal_pic = av_mallocz(c->pal_stride * avctx->height); |
889 | 2.18k | if (!c->pal_pic || !c->last_pal_pic || !ctx->last_pic) |
890 | 0 | return AVERROR(ENOMEM); |
891 | 2.18k | if (ret = wmv9_init(avctx)) |
892 | 1 | return ret; |
893 | 2.18k | ff_mss2dsp_init(&ctx->dsp); |
894 | | |
895 | 2.18k | avctx->pix_fmt = c->free_colours == 127 ? AV_PIX_FMT_RGB555 |
896 | 2.18k | : AV_PIX_FMT_RGB24; |
897 | | |
898 | | |
899 | 2.18k | return 0; |
900 | 2.18k | } |
901 | | |
902 | | const FFCodec ff_mss2_decoder = { |
903 | | .p.name = "mss2", |
904 | | CODEC_LONG_NAME("MS Windows Media Video V9 Screen"), |
905 | | .p.type = AVMEDIA_TYPE_VIDEO, |
906 | | .p.id = AV_CODEC_ID_MSS2, |
907 | | .priv_data_size = sizeof(MSS2Context), |
908 | | .init = mss2_decode_init, |
909 | | .close = mss2_decode_end, |
910 | | FF_CODEC_DECODE_CB(mss2_decode_frame), |
911 | | .p.capabilities = AV_CODEC_CAP_DR1, |
912 | | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, |
913 | | }; |