History

MS Screen 1 decoder

Kostya Shishkov committed 14 years ago

Commit 005c80b1 parent 43886ea8 files · +853 −1Browse files

Showing the changes to libavcodec (5 of 8 files). Show all

Unified · Split

5 files
  1. libavcodec/Makefile +1 −0
  2. libavcodec/allcodecs.c +1 −0
  3. libavcodec/avcodec.h +1 −0
  4. libavcodec/mss1.c +845 −0
  5. libavcodec/version.h +1 −1
libavcodec/Makefile+1−0
@@ -292,6 +292,7 @@ OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \ · 291 unmodified lines
292 h263dec.o h263.o ituh263dec.o \292 h263dec.o h263.o ituh263dec.o \
293 mpeg4videodec.o293 mpeg4videodec.o
294OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o294OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o
295OBJS-$(CONFIG_MSS1_DECODER) += mss1.o
295OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o296OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o
296OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o297OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o
297OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o mjpegdec.o mjpeg.o298OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o mjpegdec.o mjpeg.o
libavcodec/allcodecs.c+1−0
@@ -156,6 +156,7 @@ void avcodec_register_all(void) · 155 unmodified lines
156 REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);156 REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);
157 REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);157 REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);
158 REGISTER_DECODER (MSRLE, msrle);158 REGISTER_DECODER (MSRLE, msrle);
159 REGISTER_DECODER (MSS1, mss1);
159 REGISTER_DECODER (MSVIDEO1, msvideo1);160 REGISTER_DECODER (MSVIDEO1, msvideo1);
160 REGISTER_DECODER (MSZH, mszh);161 REGISTER_DECODER (MSZH, mszh);
161 REGISTER_DECODER (MXPEG, mxpeg);162 REGISTER_DECODER (MXPEG, mxpeg);
libavcodec/avcodec.h+1−0
@@ -255,6 +255,7 @@ enum CodecID { · 254 unmodified lines
255 CODEC_ID_CDXL,255 CODEC_ID_CDXL,
256 CODEC_ID_XBM,256 CODEC_ID_XBM,
257 CODEC_ID_ZEROCODEC,257 CODEC_ID_ZEROCODEC,
258 CODEC_ID_MSS1,
258 259
259 /* various PCM "codecs" */260 /* various PCM "codecs" */
260 CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs261 CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
libavcodec/mss1.c+845−0
@@ -0,0 +1,845 @@
1/*
2 * Microsoft Screen 1 (aka Windows Media Video V7 Screen) decoder
3 * Copyright (c) 2012 Konstantin Shishkov
4 *
5 * This file is part of Libav.
6 *
7 * Libav 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 * Libav 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 Libav; 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 1 (aka Windows Media Video V7 Screen) decoder
25 */
26
27#include "libavutil/intfloat.h"
28#include "libavutil/intreadwrite.h"
29#include "avcodec.h"
30#include "get_bits.h"
31
32enum SplitMode {
33 SPLIT_VERT = 0,
34 SPLIT_HOR,
35 SPLIT_NONE
36};
37
38typedef struct ArithCoder {
39 int low, high, value;
40 GetBitContext *gb;
41} ArithCoder;
42
43#define MODEL_MIN_SYMS 2
44#define MODEL_MAX_SYMS 256
45#define THRESH_ADAPTIVE -1
46#define THRESH_LOW 15
47#define THRESH_HIGH 50
48
49typedef struct Model {
50 int cum_prob[MODEL_MAX_SYMS + 1];
51 int weights[MODEL_MAX_SYMS + 1];
52 int idx2sym[MODEL_MAX_SYMS + 1];
53 int sym2idx[MODEL_MAX_SYMS + 1];
54 int num_syms;
55 int thr_weight, threshold;
56} Model;
57
58static const int sec_order_sizes[4] = { 1, 7, 6, 1 };
59
60enum ContextDirection {
61 TOP_LEFT = 0,
62 TOP,
63 TOP_RIGHT,
64 LEFT
65};
66
67typedef struct PixContext {
68 int cache_size, num_syms;
69 uint8_t cache[12];
70 Model cache_model, full_model;
71 Model sec_models[4][8][4];
72} PixContext;
73
74typedef struct MSS1Context {
75 AVCodecContext *avctx;
76 AVFrame pic;
77 uint8_t *pic_start;
78 int pic_stride;
79 uint8_t *mask;
80 int mask_linesize;
81 uint32_t pal[256];
82 int free_colours;
83 Model intra_region, inter_region;
84 Model pivot, edge_mode, split_mode;
85 PixContext intra_pix_ctx, inter_pix_ctx;
86 int corrupted;
87} MSS1Context;
88
89static void arith_init(ArithCoder *c, GetBitContext *gb)
90{
91 c->low = 0;
92 c->high = 0xFFFF;
93 c->value = get_bits(gb, 16);
94 c->gb = gb;
95}
96
97static void arith_normalise(ArithCoder *c)
98{
99 for (;;) {
100 if (c->high >= 0x8000) {
101 if (c->low < 0x8000) {
102 if (c->low >= 0x4000 && c->high < 0xC000) {
103 c->value -= 0x4000;
104 c->low -= 0x4000;
105 c->high -= 0x4000;
106 } else {
107 return;
108 }
109 } else {
110 c->value -= 0x8000;
111 c->low -= 0x8000;
112 c->high -= 0x8000;
113 }
114 }
115 c->value <<= 1;
116 c->low <<= 1;
117 c->high <<= 1;
118 c->high |= 1;
119 c->value |= get_bits1(c->gb);
120 }
121}
122
123static int arith_get_bit(ArithCoder *c)
124{
125 int range = c->high - c->low + 1;
126 int bit = (((c->value - c->low) << 1) + 1) / range;
127
128 if (bit)
129 c->low += range >> 1;
130 else
131 c->high = c->low + (range >> 1) - 1;
132
133 arith_normalise(c);
134
135 return bit;
136}
137
138static int arith_get_bits(ArithCoder *c, int bits)
139{
140 int range = c->high - c->low + 1;
141 int val = (((c->value - c->low + 1) << bits) - 1) / range;
142 int prob = range * val;
143
144 c->high = ((prob + range) >> bits) + c->low - 1;
145 c->low += prob >> bits;
146
147 arith_normalise(c);
148
149 return val;
150}
151
152static int arith_get_number(ArithCoder *c, int mod_val)
153{
154 int range = c->high - c->low + 1;
155 int val = ((c->value - c->low + 1) * mod_val - 1) / range;
156 int prob = range * val;
157
158 c->high = (prob + range) / mod_val + c->low - 1;
159 c->low += prob / mod_val;
160
161 arith_normalise(c);
162
163 return val;
164}
165
166static int arith_get_prob(ArithCoder *c, int *probs)
167{
168 int range = c->high - c->low + 1;
169 int val = ((c->value - c->low + 1) * probs[0] - 1) / range;
170 int sym = 1;
171
172 while (probs[sym] > val)
173 sym++;
174
175 c->high = range * probs[sym - 1] / probs[0] + c->low - 1;
176 c->low += range * probs[sym] / probs[0];
177
178 return sym;
179}
180
181static int model_calc_threshold(Model *m)
182{
183 int thr;
184
185 if (m->thr_weight == -1) {
186 thr = 2 * m->weights[m->num_syms] - 1;
187 thr = ((thr >> 1) + 4 * m->cum_prob[0]) / thr;
188 } else {
189 thr = m->num_syms * m->thr_weight;
190 }
191
192 return FFMIN(thr, 0x3FFF);
193}
194
195static void model_reset(Model *m)
196{
197 int i;
198
199 for (i = 0; i <= m->num_syms; i++) {
200 m->weights[i] = 1;
201 m->cum_prob[i] = m->num_syms - i;
202 }
203 m->weights[0] = -1;
204 m->idx2sym[0] = -1;
205 m->sym2idx[m->num_syms] = -1;
206 for (i = 0; i < m->num_syms; i++) {
207 m->sym2idx[i] = i + 1;
208 m->idx2sym[i + 1] = i;
209 }
210}
211
212static av_cold void model_init(Model *m, int num_syms, int thr_weight)
213{
214 m->num_syms = num_syms;
215 m->thr_weight = thr_weight;
216 m->threshold = model_calc_threshold(m);
217 model_reset(m);
218}
219
220static void model_rescale_weights(Model *m)
221{
222 int i;
223 int cum_prob;
224
225 if (m->thr_weight == -1)
226 m->threshold = model_calc_threshold(m);
227 while (m->cum_prob[0] > m->threshold) {
228 cum_prob = 0;
229 for (i = m->num_syms; i >= 0; i--) {
230 m->cum_prob[i] = cum_prob;
231 m->weights[i] = (m->weights[i] + 1) >> 1;
232 cum_prob += m->weights[i];
233 }
234 }
235}
236
237static void model_update(Model *m, int val)
238{
239 int i;
240
241 if (m->weights[val] == m->weights[val - 1]) {
242 for (i = val; m->weights[i - 1] == m->weights[val]; i--);
243 if (i != val) {
244 int sym1, sym2;
245
246 sym1 = m->idx2sym[val];
247 sym2 = m->idx2sym[i];
248
249 m->idx2sym[val] = sym2;
250 m->idx2sym[i] = sym1;
251 m->sym2idx[sym1] = i;
252 m->sym2idx[sym2] = val;
253
254 val = i;
255 }
256 }
257 m->weights[val]++;
258 for (i = val - 1; i >= 0; i--)
259 m->cum_prob[i]++;
260 model_rescale_weights(m);
261}
262
263static int arith_get_model_sym(ArithCoder *c, Model *m)
264{
265 int idx, val;
266
267 idx = arith_get_prob(c, m->cum_prob);
268
269 val = m->idx2sym[idx];
270 model_update(m, idx);
271
272 arith_normalise(c);
273
274 return val;
275}
276
277static void pixctx_reset(PixContext *ctx)
278{
279 int i, j, k;
280
281 for (i = 0; i < ctx->cache_size; i++)
282 ctx->cache[i] = i;
283
284 model_reset(&ctx->cache_model);
285 model_reset(&ctx->full_model);
286
287 for (i = 0; i < 4; i++)
288 for (j = 0; j < sec_order_sizes[i]; j++)
289 for (k = 0; k < 4; k++)
290 model_reset(&ctx->sec_models[i][j][k]);
291}
292
293static av_cold void pixctx_init(PixContext *ctx, int cache_size)
294{
295 int i, j, k;
296
297 ctx->cache_size = cache_size + 4;
298 ctx->num_syms = cache_size;
299
300 for (i = 0; i < ctx->cache_size; i++)
301 ctx->cache[i] = i;
302
303 model_init(&ctx->cache_model, ctx->num_syms + 1, THRESH_LOW);
304 model_init(&ctx->full_model, 256, THRESH_HIGH);
305
306 for (i = 0; i < 4; i++) {
307 for (j = 0; j < sec_order_sizes[i]; j++) {
308 for (k = 0; k < 4; k++) {
309 model_init(&ctx->sec_models[i][j][k], 2 + i,
310 i ? THRESH_LOW : THRESH_ADAPTIVE);
311 }
312 }
313 }
314}
315
316static int decode_top_left_pixel(ArithCoder *acoder, PixContext *pctx)
317{
318 int i, val, pix;
319
320 val = arith_get_model_sym(acoder, &pctx->cache_model);
321 if (val < pctx->num_syms) {
322 pix = pctx->cache[val];
323 } else {
324 pix = arith_get_model_sym(acoder, &pctx->full_model);
325 for (i = 0; i < pctx->cache_size - 1; i++)
326 if (pctx->cache[i] == pix)
327 break;
328 val = i;
329 }
330 if (val) {
331 for (i = val; i > 0; i--)
332 pctx->cache[i] = pctx->cache[i - 1];
333 pctx->cache[0] = pix;
334 }
335
336 return pix;
337}
338
339static int decode_pixel(ArithCoder *acoder, PixContext *pctx,
340 uint8_t *ngb, int num_ngb)
341{
342 int i, val, pix;
343
344 val = arith_get_model_sym(acoder, &pctx->cache_model);
345 if (val < pctx->num_syms) {
346 int idx, j;
347
348
349 idx = 0;
350 for (i = 0; i < pctx->cache_size; i++) {
351 for (j = 0; j < num_ngb; j++)
352 if (pctx->cache[i] == ngb[j])
353 break;
354 if (j == num_ngb) {
355 if (idx == val)
356 break;
357 idx++;
358 }
359 }
360 val = FFMIN(i, pctx->cache_size - 1);
361 pix = pctx->cache[val];
362 } else {
363 pix = arith_get_model_sym(acoder, &pctx->full_model);
364 for (i = 0; i < pctx->cache_size - 1; i++)
365 if (pctx->cache[i] == pix)
366 break;
367 val = i;
368 }
369 if (val) {
370 for (i = val; i > 0; i--)
371 pctx->cache[i] = pctx->cache[i - 1];
372 pctx->cache[0] = pix;
373 }
374
375 return pix;
376}
377
378static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx,
379 uint8_t *src, int stride, int x, int y,
380 int has_right)
381{
382 uint8_t neighbours[4];
383 uint8_t ref_pix[4];
384 int nlen;
385 int layer = 0, sub;
386 int pix;
387 int i, j;
388
389 if (!y) {
390 memset(neighbours, src[-1], 4);
391 } else {
392 neighbours[TOP] = src[-stride];
393 if (!x) {
394 neighbours[TOP_LEFT] = neighbours[LEFT] = neighbours[TOP];
395 } else {
396 neighbours[TOP_LEFT] = src[-stride - 1];
397 neighbours[ LEFT] = src[-1];
398 }
399 if (has_right)
400 neighbours[TOP_RIGHT] = src[-stride + 1];
401 else
402 neighbours[TOP_RIGHT] = neighbours[TOP];
403 }
404
405 sub = 0;
406 if (x >= 2 && src[-2] == neighbours[LEFT])
407 sub = 1;
408 if (y >= 2 && src[-2 * stride] == neighbours[TOP])
409 sub |= 2;
410
411 nlen = 1;
412 ref_pix[0] = neighbours[0];
413 for (i = 1; i < 4; i++) {
414 for (j = 0; j < nlen; j++)
415 if (ref_pix[j] == neighbours[i])
416 break;
417 if (j == nlen)
418 ref_pix[nlen++] = neighbours[i];
419 }
420
421 switch (nlen) {
422 case 1:
423 case 4:
424 layer = 0;
425 break;
426 case 2:
427 if (neighbours[TOP] == neighbours[TOP_LEFT]) {
428 if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
429 layer = 3;
430 else if (neighbours[LEFT] == neighbours[TOP_LEFT])
431 layer = 2;
432 else
433 layer = 4;
434 } else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) {
435 if (neighbours[LEFT] == neighbours[TOP_LEFT])
436 layer = 1;
437 else
438 layer = 5;
439 } else if (neighbours[LEFT] == neighbours[TOP_LEFT]) {
440 layer = 6;
441 } else {
442 layer = 0;
443 }
444 break;
445 case 3:
446 if (neighbours[TOP] == neighbours[TOP_LEFT])
447 layer = 0;
448 else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
449 layer = 1;
450 else if (neighbours[LEFT] == neighbours[TOP_LEFT])
451 layer = 2;
452 else if (neighbours[TOP_RIGHT] == neighbours[TOP])
453 layer = 3;
454 else if (neighbours[TOP] == neighbours[LEFT])
455 layer = 4;
456 else
457 layer = 5;
458 break;
459 }
460
461 pix = arith_get_model_sym(acoder, &pctx->sec_models[nlen - 1][layer][sub]);
462 if (pix < nlen)
463 return ref_pix[pix];
464 else
465 return decode_pixel(acoder, pctx, ref_pix, nlen);
466}
467
468static int decode_region(MSS1Context *ctx, ArithCoder *acoder, uint8_t *dst,
469 int x, int y, int width, int height, int stride,
470 PixContext *pctx)
471{
472 int i, j;
473
474 dst += x + y * stride;
475
476 dst[0] = decode_top_left_pixel(acoder, pctx);
477 for (j = 0; j < height; j++) {
478 for (i = 0; i < width; i++) {
479 if (!i && !j)
480 continue;
481
482 dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride,
483 i, j, width - i - 1);
484 }
485 dst += stride;
486 }
487
488 return 0;
489}
490
491static int decode_region_masked(MSS1Context *ctx, ArithCoder *acoder,
492 uint8_t *dst, int stride, uint8_t *mask,
493 int mask_stride, int x, int y,
494 int width, int height,
495 PixContext *pctx)
496{
497 int i, j;
498
499 dst += x + y * stride;
500 mask += x + y * mask_stride;
501
502 if (mask[0] != 0xFF)
503 dst[0] = decode_top_left_pixel(acoder, pctx);
504 for (j = 0; j < height; j++) {
505 for (i = 0; i < width; i++) {
506 if (!i && !j || mask[i] != 0xFF)
507 continue;
508
509 dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride,
510 i, j, width - i - 1);
511 }
512 dst += stride;
513 mask += mask_stride;
514 }
515
516 return 0;
517}
518
519static av_cold void codec_init(MSS1Context *ctx)
520{
521 model_init(&ctx->intra_region, 2, THRESH_ADAPTIVE);
522 model_init(&ctx->inter_region, 2, THRESH_ADAPTIVE);
523 model_init(&ctx->split_mode, 3, THRESH_HIGH);
524 model_init(&ctx->edge_mode, 2, THRESH_HIGH);
525 model_init(&ctx->pivot, 3, THRESH_LOW);
526 pixctx_init(&ctx->intra_pix_ctx, 8);
527 pixctx_init(&ctx->inter_pix_ctx, 2);
528 ctx->corrupted = 1;
529}
530
531static void codec_reset(MSS1Context *ctx)
532{
533 model_reset(&ctx->intra_region);
534 model_reset(&ctx->inter_region);
535 model_reset(&ctx->split_mode);
536 model_reset(&ctx->edge_mode);
537 model_reset(&ctx->pivot);
538 pixctx_reset(&ctx->intra_pix_ctx);
539 pixctx_reset(&ctx->inter_pix_ctx);
540
541 ctx->corrupted = 0;
542}
543
544static int decode_pal(MSS1Context *ctx, ArithCoder *acoder)
545{
546 int i, ncol, r, g, b;
547 uint32_t *pal = ctx->pal + 256 - ctx->free_colours;
548
549 if (!ctx->free_colours)
550 return 0;
551
552 ncol = arith_get_number(acoder, ctx->free_colours + 1);
553 for (i = 0; i < ncol; i++) {
554 r = arith_get_bits(acoder, 8);
555 g = arith_get_bits(acoder, 8);
556 b = arith_get_bits(acoder, 8);
557 *pal++ = (r << 16) | (g << 8) | b;
558 }
559
560 return 0;
561}
562
563static int decode_pivot(MSS1Context *ctx, ArithCoder *acoder, int base)
564{
565 int val, inv;
566
567 inv = arith_get_model_sym(acoder, &ctx->edge_mode);
568 val = arith_get_model_sym(acoder, &ctx->pivot) + 1;
569
570 if (val > 2) {
571 if ((base + 1) / 2 - 2 <= 0) {
572 ctx->corrupted = 1;
573 return 0;
574 }
575 val = arith_get_number(acoder, (base + 1) / 2 - 2) + 3;
576 }
577
578 if (val == base) {
579 ctx->corrupted = 1;
580 return 0;
581 }
582
583 return inv ? base - val : val;
584}
585
586static int decode_region_intra(MSS1Context *ctx, ArithCoder *acoder,
587 int x, int y, int width, int height)
588{
589 int mode;
590
591 mode = arith_get_model_sym(acoder, &ctx->intra_region);
592
593 if (!mode) {
594 int i, pix;
595 int stride = ctx->pic_stride;
596 uint8_t *dst = ctx->pic_start + x + y * stride;
597
598 pix = decode_top_left_pixel(acoder, &ctx->intra_pix_ctx);
599 for (i = 0; i < height; i++, dst += stride)
600 memset(dst, pix, width);
601 } else {
602 return decode_region(ctx, acoder, ctx->pic_start,
603 x, y, width, height, ctx->pic_stride,
604 &ctx->intra_pix_ctx);
605 }
606
607 return 0;
608}
609
610static int decode_intra(MSS1Context *ctx, ArithCoder *acoder,
611 int x, int y, int width, int height)
612{
613 int mode, pivot;
614
615 if (ctx->corrupted)
616 return -1;
617
618 mode = arith_get_model_sym(acoder, &ctx->split_mode);
619
620 switch (mode) {
621 case SPLIT_VERT:
622 pivot = decode_pivot(ctx, acoder, height);
623 if (ctx->corrupted)
624 return -1;
625 if (decode_intra(ctx, acoder, x, y, width, pivot))
626 return -1;
627 if (decode_intra(ctx, acoder, x, y + pivot, width, height - pivot))
628 return -1;
629 break;
630 case SPLIT_HOR:
631 pivot = decode_pivot(ctx, acoder, width);
632 if (ctx->corrupted)
633 return -1;
634 if (decode_intra(ctx, acoder, x, y, pivot, height))
635 return -1;
636 if (decode_intra(ctx, acoder, x + pivot, y, width - pivot, height))
637 return -1;
638 break;
639 case SPLIT_NONE:
640 return decode_region_intra(ctx, acoder, x, y, width, height);
641 default:
642 return -1;
643 }
644
645 return 0;
646}
647
648static int decode_region_inter(MSS1Context *ctx, ArithCoder *acoder,
649 int x, int y, int width, int height)
650{
651 int mode;
652
653 mode = arith_get_model_sym(acoder, &ctx->inter_region);
654
655 if (!mode) {
656 mode = decode_top_left_pixel(acoder, &ctx->inter_pix_ctx);
657 if (mode != 0xFF) {
658 return 0;
659 } else {
660 return decode_region_intra(ctx, acoder, x, y, width, height);
661 }
662 } else {
663 if (decode_region(ctx, acoder, ctx->mask,
664 x, y, width, height, ctx->mask_linesize,
665 &ctx->inter_pix_ctx) < 0)
666 return -1;
667 return decode_region_masked(ctx, acoder, ctx->pic_start,
668 -ctx->pic.linesize[0], ctx->mask,
669 ctx->mask_linesize,
670 x, y, width, height,
671 &ctx->intra_pix_ctx);
672 }
673
674 return 0;
675}
676
677static int decode_inter(MSS1Context *ctx, ArithCoder *acoder,
678 int x, int y, int width, int height)
679{
680 int mode, pivot;
681
682 if (ctx->corrupted)
683 return -1;
684
685 mode = arith_get_model_sym(acoder, &ctx->split_mode);
686
687 switch (mode) {
688 case SPLIT_VERT:
689 pivot = decode_pivot(ctx, acoder, height);
690 if (decode_inter(ctx, acoder, x, y, width, pivot))
691 return -1;
692 if (decode_inter(ctx, acoder, x, y + pivot, width, height - pivot))
693 return -1;
694 break;
695 case SPLIT_HOR:
696 pivot = decode_pivot(ctx, acoder, width);
697 if (decode_inter(ctx, acoder, x, y, pivot, height))
698 return -1;
699 if (decode_inter(ctx, acoder, x + pivot, y, width - pivot, height))
700 return -1;
701 break;
702 case SPLIT_NONE:
703 return decode_region_inter(ctx, acoder, x, y, width, height);
704 default:
705 return -1;
706 }
707
708 return 0;
709}
710
711static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
712 AVPacket *avpkt)
713{
714 const uint8_t *buf = avpkt->data;
715 int buf_size = avpkt->size;
716 MSS1Context *c = avctx->priv_data;
717 GetBitContext gb;
718 ArithCoder acoder;
719 int pal_changed = 0;
720 int ret;
721
722 init_get_bits(&gb, buf, buf_size * 8);
723 arith_init(&acoder, &gb);
724
725 c->pic.reference = 3;
726 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
727 FF_BUFFER_HINTS_REUSABLE;
728 if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
729 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
730 return ret;
731 }
732
733 c->pic_start = c->pic.data[0] + c->pic.linesize[0] * (avctx->height - 1);
734 c->pic_stride = -c->pic.linesize[0];
735 if (!arith_get_bit(&acoder)) {
736 codec_reset(c);
737 pal_changed = decode_pal(c, &acoder);
738 c->corrupted = decode_intra(c, &acoder, 0, 0,
739 avctx->width, avctx->height);
740 c->pic.key_frame = 1;
741 c->pic.pict_type = AV_PICTURE_TYPE_I;
742 } else {
743 if (c->corrupted)
744 return AVERROR_INVALIDDATA;
745 c->corrupted = decode_inter(c, &acoder, 0, 0,
746 avctx->width, avctx->height);
747 c->pic.key_frame = 0;
748 c->pic.pict_type = AV_PICTURE_TYPE_P;
749 }
750 if (c->corrupted)
751 return AVERROR_INVALIDDATA;
752 memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
753 c->pic.palette_has_changed = pal_changed;
754
755 *data_size = sizeof(AVFrame);
756 *(AVFrame*)data = c->pic;
757
758 /* always report that the buffer was completely consumed */
759 return buf_size;
760}
761
762static av_cold int mss1_decode_init(AVCodecContext *avctx)
763{
764 MSS1Context * const c = avctx->priv_data;
765 int i;
766
767 c->avctx = avctx;
768
769 if (avctx->extradata_size < 52 + 256 * 3) {
770 av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d\n",
771 avctx->extradata_size);
772 return AVERROR_INVALIDDATA;
773 }
774
775 if (AV_RB32(avctx->extradata) < avctx->extradata_size) {
776 av_log(avctx, AV_LOG_ERROR,
777 "Insufficient extradata size: expected %d got %d\n",
778 AV_RB32(avctx->extradata),
779 avctx->extradata_size);
780 return AVERROR_INVALIDDATA;
781 }
782
783 av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n",
784 AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8));
785 c->free_colours = AV_RB32(avctx->extradata + 48);
786 av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours);
787 avctx->coded_width = AV_RB32(avctx->extradata + 20);
788 avctx->coded_height = AV_RB32(avctx->extradata + 24);
789
790 av_log(avctx, AV_LOG_DEBUG, "Display dimensions %dx%d\n",
791 AV_RB32(avctx->extradata + 12), AV_RB32(avctx->extradata + 16));
792 av_log(avctx, AV_LOG_DEBUG, "Coded dimensions %dx%d\n",
793 avctx->coded_width, avctx->coded_height);
794 av_log(avctx, AV_LOG_DEBUG, "%g frames per second\n",
795 av_int2float(AV_RB32(avctx->extradata + 28)));
796 av_log(avctx, AV_LOG_DEBUG, "Bitrate %d bps\n",
797 AV_RB32(avctx->extradata + 32));
798 av_log(avctx, AV_LOG_DEBUG, "Max. lead time %g ms\n",
799 av_int2float(AV_RB32(avctx->extradata + 36)));
800 av_log(avctx, AV_LOG_DEBUG, "Max. lag time %g ms\n",
801 av_int2float(AV_RB32(avctx->extradata + 40)));
802 av_log(avctx, AV_LOG_DEBUG, "Max. seek time %g ms\n",
803 av_int2float(AV_RB32(avctx->extradata + 44)));
804
805 for (i = 0; i < 256; i++)
806 c->pal[i] = AV_RB24(avctx->extradata + 52 + i * 3);
807
808 avctx->pix_fmt = PIX_FMT_PAL8;
809
810 c->mask_linesize = FFALIGN(avctx->width, 16);
811 c->mask = av_malloc(c->mask_linesize * avctx->height);
812 if (!c->mask) {
813 av_log(avctx, AV_LOG_ERROR, "Cannot allocate mask plane\n");
814 return AVERROR(ENOMEM);
815 }
816
817 avctx->coded_frame = &c->pic;
818
819 codec_init(c);
820
821 return 0;
822}
823
824static av_cold int mss1_decode_end(AVCodecContext *avctx)
825{
826 MSS1Context * const c = avctx->priv_data;
827
828 if (c->pic.data[0])
829 avctx->release_buffer(avctx, &c->pic);
830 av_freep(&c->mask);
831
832 return 0;
833}
834
835AVCodec ff_mss1_decoder = {
836 .name = "mss1",
837 .type = AVMEDIA_TYPE_VIDEO,
838 .id = CODEC_ID_MSS1,
839 .priv_data_size = sizeof(MSS1Context),
840 .init = mss1_decode_init,
841 .close = mss1_decode_end,
842 .decode = mss1_decode_frame,
843 .capabilities = CODEC_CAP_DR1,
844 .long_name = NULL_IF_CONFIG_SMALL("MS Screen 1"),
845};
libavcodec/version.h+1−1
@@ -27,7 +27,7 @@ · 26 unmodified lines
27 */27 */
28 28
29#define LIBAVCODEC_VERSION_MAJOR 5429#define LIBAVCODEC_VERSION_MAJOR 54
30#define LIBAVCODEC_VERSION_MINOR 1530#define LIBAVCODEC_VERSION_MINOR 16
31#define LIBAVCODEC_VERSION_MICRO 031#define LIBAVCODEC_VERSION_MICRO 0
32 32
33#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \33#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t