History

MS Screen 1 decoder

Kostya Shishkov committed 14 years ago

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

Unified · Split

8 files
  1. Changelog +1 −0
  2. doc/general.texi +2 −0
  3. libavcodec/Makefile +1 −0
  4. libavcodec/allcodecs.c +1 −0
  5. libavcodec/avcodec.h +1 −0
  6. libavcodec/mss1.c +845 −0
  7. libavcodec/version.h +1 −1
  8. libavformat/riff.c +1 −0
Changelog+1−0
@@ -27,6 +27,7 @@ version <next>: · 26 unmodified lines
2727 - channelsplit audio filter
2828 - RTMPT protocol support
2929 - iLBC encoding/decoding via libilbc
30+- Microsoft Screen 1 decoder
3031
3132
3233 version 0.8:
doc/general.texi+2−0
@@ -532,6 +532,8 @@ following image formats are supported: · 531 unmodified lines
532532 @item LOCO @tab @tab X
533533 @item lossless MJPEG @tab X @tab X
534534 @item Microsoft RLE @tab @tab X
535+@item Microsoft Screen 1 @tab @tab X
536+ @tab Also known as Windows Media Video V7 Screen.
535537 @item Microsoft Video 1 @tab @tab X
536538 @item Mimic @tab @tab X
537539 @tab Used in MSN Messenger Webcam streams.
libavcodec/Makefile+1−0
@@ -292,6 +292,7 @@ OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \ · 291 unmodified lines
292292 h263dec.o h263.o ituh263dec.o \
293293 mpeg4videodec.o
294294 OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o
295+OBJS-$(CONFIG_MSS1_DECODER) += mss1.o
295296 OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o
296297 OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o
297298 OBJS-$(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
156156 REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);
157157 REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);
158158 REGISTER_DECODER (MSRLE, msrle);
159+ REGISTER_DECODER (MSS1, mss1);
159160 REGISTER_DECODER (MSVIDEO1, msvideo1);
160161 REGISTER_DECODER (MSZH, mszh);
161162 REGISTER_DECODER (MXPEG, mxpeg);
libavcodec/avcodec.h+1−0
@@ -255,6 +255,7 @@ enum CodecID { · 254 unmodified lines
255255 CODEC_ID_CDXL,
256256 CODEC_ID_XBM,
257257 CODEC_ID_ZEROCODEC,
258+ CODEC_ID_MSS1,
258259
259260 /* various PCM "codecs" */
260261 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+
32+enum SplitMode {
33+ SPLIT_VERT = 0,
34+ SPLIT_HOR,
35+ SPLIT_NONE
36+};
37+
38+typedef 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+
49+typedef 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+
58+static const int sec_order_sizes[4] = { 1, 7, 6, 1 };
59+
60+enum ContextDirection {
61+ TOP_LEFT = 0,
62+ TOP,
63+ TOP_RIGHT,
64+ LEFT
65+};
66+
67+typedef 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+
74+typedef 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+
89+static 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+
97+static 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+
123+static 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+
138+static 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+
152+static 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+
166+static 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+
181+static 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+
195+static 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+
212+static 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+
220+static 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+
237+static 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+
263+static 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+
277+static 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+
293+static 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+
316+static 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+
339+static 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+
378+static 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+
468+static 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+
491+static 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+
519+static 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+
531+static 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+
544+static 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+
563+static 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+
586+static 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+
610+static 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+
648+static 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+
677+static 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+
711+static 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+
762+static 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+
824+static 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+
835+AVCodec 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
2727 */
2828
2929 #define LIBAVCODEC_VERSION_MAJOR 54
30−#define LIBAVCODEC_VERSION_MINOR 15
30+#define LIBAVCODEC_VERSION_MINOR 16
3131 #define LIBAVCODEC_VERSION_MICRO 0
3232
3333 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
libavformat/riff.c+1−0
@@ -284,6 +284,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { · 283 unmodified lines
284284 { CODEC_ID_VBLE, MKTAG('V', 'B', 'L', 'E') },
285285 { CODEC_ID_DXTORY, MKTAG('x', 't', 'o', 'r') },
286286 { CODEC_ID_ZEROCODEC, MKTAG('Z', 'E', 'C', 'O') },
287+ { CODEC_ID_MSS1, MKTAG('M', 'S', 'S', '1') },
287288 { CODEC_ID_NONE, 0 }
288289 };
289290

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