Browse code

MS Expression Encoder Screen decoder

Kostya Shishkov authored on 2012/07/07 20:21:52
Showing 8 changed files
... ...
@@ -34,6 +34,7 @@ version <next>:
34 34
 - RTSP listen mode
35 35
 - TechSmith Screen Codec 2 decoder
36 36
 - AAC encoding via libfdk-aac
37
+- Microsoft Expression Encoder Screen decoder
37 38
 
38 39
 
39 40
 version 0.8:
... ...
@@ -541,6 +541,8 @@ following image formats are supported:
541 541
 @item lossless MJPEG         @tab  X  @tab  X
542 542
 @item Microsoft ATC Screen   @tab     @tab  X
543 543
     @tab Also known as Microsoft Screen 3.
544
+@item Microsoft Expression Encoder Screen  @tab     @tab  X
545
+    @tab Also known as Microsoft Titanium Screen 2.
544 546
 @item Microsoft RLE          @tab     @tab  X
545 547
 @item Microsoft Screen 1     @tab     @tab  X
546 548
     @tab Also known as Windows Media Video V7 Screen.
... ...
@@ -296,6 +296,7 @@ OBJS-$(CONFIG_MSA1_DECODER)            += mss3.o mss34dsp.o
296 296
 OBJS-$(CONFIG_MSS1_DECODER)            += mss1.o
297 297
 OBJS-$(CONFIG_MSVIDEO1_DECODER)        += msvideo1.o
298 298
 OBJS-$(CONFIG_MSZH_DECODER)            += lcldec.o
299
+OBJS-$(CONFIG_MTS2_DECODER)            += mss4.o mss34dsp.o
299 300
 OBJS-$(CONFIG_MXPEG_DECODER)           += mxpegdec.o mjpegdec.o mjpeg.o
300 301
 OBJS-$(CONFIG_NELLYMOSER_DECODER)      += nellymoserdec.o nellymoser.o
301 302
 OBJS-$(CONFIG_NELLYMOSER_ENCODER)      += nellymoserenc.o nellymoser.o \
... ...
@@ -160,6 +160,7 @@ void avcodec_register_all(void)
160 160
     REGISTER_DECODER (MSS1, mss1);
161 161
     REGISTER_DECODER (MSVIDEO1, msvideo1);
162 162
     REGISTER_DECODER (MSZH, mszh);
163
+    REGISTER_DECODER (MTS2, mts2);
163 164
     REGISTER_DECODER (MXPEG, mxpeg);
164 165
     REGISTER_DECODER (NUV, nuv);
165 166
     REGISTER_ENCDEC  (PAM, pam);
... ...
@@ -258,6 +258,7 @@ enum CodecID {
258 258
     CODEC_ID_MSS1,
259 259
     CODEC_ID_MSA1,
260 260
     CODEC_ID_TSCC2,
261
+    CODEC_ID_MTS2,
261 262
 
262 263
     /* various PCM "codecs" */
263 264
     CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
264 265
new file mode 100644
... ...
@@ -0,0 +1,682 @@
0
+/*
1
+ * Microsoft Screen 4 (aka Microsoft Expression Encoder Screen) decoder
2
+ * Copyright (c) 2012 Konstantin Shishkov
3
+ *
4
+ * This file is part of Libav.
5
+ *
6
+ * Libav 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
+ * Libav 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 Libav; 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 4 (aka Microsoft Titanium Screen 2,
24
+ * aka Microsoft Expression Encoder Screen) decoder
25
+ */
26
+
27
+#include "avcodec.h"
28
+#include "bytestream.h"
29
+#include "dsputil.h"
30
+#include "get_bits.h"
31
+#include "mss34dsp.h"
32
+#include "unary.h"
33
+
34
+#define HEADER_SIZE 8
35
+
36
+enum FrameType {
37
+    INTRA_FRAME = 0,
38
+    INTER_FRAME,
39
+    SKIP_FRAME
40
+};
41
+
42
+enum BlockType {
43
+    SKIP_BLOCK = 0,
44
+    DCT_BLOCK,
45
+    IMAGE_BLOCK,
46
+};
47
+
48
+enum CachePos {
49
+    LEFT = 0,
50
+    TOP_LEFT,
51
+    TOP,
52
+};
53
+
54
+static const uint8_t mss4_dc_vlc_lens[2][16] = {
55
+    { 0, 1, 5, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
56
+    { 0, 3, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0 }
57
+};
58
+
59
+static const uint8_t mss4_ac_vlc_lens[2][16] = {
60
+    { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 },
61
+    { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 }
62
+};
63
+
64
+static const uint8_t mss4_ac_vlc_syms[2][162] = {
65
+  { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
66
+    0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
67
+    0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
68
+    0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0,
69
+    0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16,
70
+    0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
71
+    0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
72
+    0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
73
+    0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
74
+    0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
75
+    0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
76
+    0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
77
+    0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
78
+    0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
79
+    0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
80
+    0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5,
81
+    0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4,
82
+    0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
83
+    0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
84
+    0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
85
+    0xF9, 0xFA  },
86
+  { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
87
+    0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
88
+    0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
89
+    0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0,
90
+    0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34,
91
+    0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
92
+    0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38,
93
+    0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
94
+    0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
95
+    0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
96
+    0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
97
+    0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
98
+    0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
99
+    0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5,
100
+    0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
101
+    0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3,
102
+    0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
103
+    0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
104
+    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
105
+    0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
106
+    0xF9, 0xFA  }
107
+};
108
+
109
+static const uint8_t vec_len_syms[2][4] = {
110
+    { 4, 2, 3, 1 },
111
+    { 4, 1, 2, 3 }
112
+};
113
+
114
+static const uint8_t mss4_vec_entry_vlc_lens[2][16] = {
115
+    { 0, 2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
116
+    { 0, 1, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
117
+};
118
+
119
+static const uint8_t mss4_vec_entry_vlc_syms[2][9] = {
120
+    { 0, 7, 6, 5, 8, 4, 3, 1, 2 },
121
+    { 0, 2, 3, 4, 5, 6, 7, 1, 8 }
122
+};
123
+
124
+#define MAX_ENTRIES  162
125
+
126
+typedef struct MSS4Context {
127
+    AVFrame    pic;
128
+    DSPContext dsp;
129
+
130
+    VLC        dc_vlc[2], ac_vlc[2];
131
+    VLC        vec_entry_vlc[2];
132
+    int        block[64];
133
+    uint8_t    imgbuf[3][16 * 16];
134
+
135
+    int        quality;
136
+    uint16_t   quant_mat[2][64];
137
+
138
+    int        *prev_dc[3];
139
+    int        dc_stride[3];
140
+    int        dc_cache[4][4];
141
+
142
+    int        prev_vec[3][4];
143
+} MSS4Context;
144
+
145
+static av_cold int mss4_init_vlc(VLC *vlc, const uint8_t *lens,
146
+                                 const uint8_t *syms, int num_syms)
147
+{
148
+    uint8_t  bits[MAX_ENTRIES];
149
+    uint16_t codes[MAX_ENTRIES];
150
+    int i, j;
151
+    int prefix = 0, max_bits = 0, idx = 0;
152
+
153
+    for (i = 0; i < 16; i++) {
154
+        for (j = 0; j < lens[i]; j++) {
155
+            bits[idx]  = i + 1;
156
+            codes[idx] = prefix++;
157
+            max_bits   = i + 1;
158
+            idx++;
159
+        }
160
+        prefix <<= 1;
161
+    }
162
+
163
+    return ff_init_vlc_sparse(vlc, FFMIN(max_bits, 9), num_syms, bits, 1, 1,
164
+                              codes, 2, 2, syms, 1, 1, 0);
165
+}
166
+
167
+static av_cold int mss4_init_vlcs(MSS4Context *ctx)
168
+{
169
+    int ret, i;
170
+
171
+    for (i = 0; i < 2; i++) {
172
+        ret = mss4_init_vlc(&ctx->dc_vlc[i], mss4_dc_vlc_lens[i], NULL, 12);
173
+        if (ret)
174
+            return ret;
175
+        ret = mss4_init_vlc(&ctx->ac_vlc[i], mss4_ac_vlc_lens[i],
176
+                            mss4_ac_vlc_syms[i], 162);
177
+        if (ret)
178
+            return ret;
179
+        ret = mss4_init_vlc(&ctx->vec_entry_vlc[i], mss4_vec_entry_vlc_lens[i],
180
+                            mss4_vec_entry_vlc_syms[i], 9);
181
+        if (ret)
182
+            return ret;
183
+    }
184
+    return 0;
185
+}
186
+
187
+static av_cold void mss4_free_vlcs(MSS4Context *ctx)
188
+{
189
+    int i;
190
+
191
+    for (i = 0; i < 2; i++) {
192
+        ff_free_vlc(&ctx->dc_vlc[i]);
193
+        ff_free_vlc(&ctx->ac_vlc[i]);
194
+        ff_free_vlc(&ctx->vec_entry_vlc[i]);
195
+    }
196
+}
197
+
198
+/* This function returns values in the range
199
+ * (-range + 1; -range/2] U [range/2; range - 1)
200
+ * i.e.
201
+ * nbits = 0 -> 0
202
+ * nbits = 1 -> -1, 1
203
+ * nbits = 2 -> -3, -2, 2, 3
204
+ */
205
+static av_always_inline int get_coeff_bits(GetBitContext *gb, int nbits)
206
+{
207
+    int val;
208
+
209
+    if (!nbits)
210
+        return 0;
211
+
212
+    val = get_bits(gb, nbits);
213
+    if (val < (1 << (nbits - 1)))
214
+        val -= (1 << nbits) - 1;
215
+
216
+    return val;
217
+}
218
+
219
+static inline int get_coeff(GetBitContext *gb, VLC *vlc)
220
+{
221
+    int val = get_vlc2(gb, vlc->table, vlc->bits, 2);
222
+
223
+    return get_coeff_bits(gb, val);
224
+}
225
+
226
+static int mss4_decode_dct(GetBitContext *gb, VLC *dc_vlc, VLC *ac_vlc,
227
+                           int *block, int *dc_cache,
228
+                           int bx, int by, uint16_t *quant_mat)
229
+{
230
+    int skip, val, pos = 1, zz_pos, dc;
231
+
232
+    memset(block, 0, sizeof(*block) * 64);
233
+
234
+    dc = get_coeff(gb, dc_vlc);
235
+    // DC prediction is the same as in MSS3
236
+    if (by) {
237
+        if (bx) {
238
+            int l, tl, t;
239
+
240
+            l  = dc_cache[LEFT];
241
+            tl = dc_cache[TOP_LEFT];
242
+            t  = dc_cache[TOP];
243
+
244
+            if (FFABS(t - tl) <= FFABS(l - tl))
245
+                dc += l;
246
+            else
247
+                dc += t;
248
+        } else {
249
+            dc += dc_cache[TOP];
250
+        }
251
+    } else if (bx) {
252
+        dc += dc_cache[LEFT];
253
+    }
254
+    dc_cache[LEFT] = dc;
255
+    block[0]       = dc * quant_mat[0];
256
+
257
+    while (pos < 64) {
258
+        val = get_vlc2(gb, ac_vlc->table, 9, 2);
259
+        if (!val)
260
+            return 0;
261
+        if (val == -1)
262
+            return -1;
263
+        if (val == 0xF0) {
264
+            pos += 16;
265
+            continue;
266
+        }
267
+        skip = val >> 4;
268
+        val  = get_coeff_bits(gb, val & 0xF);
269
+        pos += skip;
270
+        if (pos >= 64)
271
+            return -1;
272
+
273
+        zz_pos = ff_zigzag_direct[pos];
274
+        block[zz_pos] = val * quant_mat[zz_pos];
275
+        pos++;
276
+    }
277
+
278
+    return pos == 64 ? 0 : -1;
279
+}
280
+
281
+static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb,
282
+                                 uint8_t *dst[3], int mb_x, int mb_y)
283
+{
284
+    int i, j, k, ret;
285
+    uint8_t *out = dst[0];
286
+
287
+    for (j = 0; j < 2; j++) {
288
+        for (i = 0; i < 2; i++) {
289
+            int xpos = mb_x * 2 + i;
290
+            c->dc_cache[j][TOP_LEFT] = c->dc_cache[j][TOP];
291
+            c->dc_cache[j][TOP]      = c->prev_dc[0][mb_x * 2 + i];
292
+            ret = mss4_decode_dct(gb, c->dc_vlc, c->ac_vlc, c->block,
293
+                                  c->dc_cache[j],
294
+                                  xpos, mb_y * 2 + j, c->quant_mat[0]);
295
+            if (ret)
296
+                return ret;
297
+            c->prev_dc[0][mb_x * 2 + i] = c->dc_cache[j][LEFT];
298
+
299
+            ff_mss34_dct_put(out + xpos * 8, c->pic.linesize[0],
300
+                             c->block);
301
+        }
302
+        out += 8 * c->pic.linesize[0];
303
+    }
304
+
305
+    for (i = 1; i < 3; i++) {
306
+        c->dc_cache[i + 1][TOP_LEFT] = c->dc_cache[i + 1][TOP];
307
+        c->dc_cache[i + 1][TOP]      = c->prev_dc[i][mb_x];
308
+        ret = mss4_decode_dct(gb, c->dc_vlc + 1, c->ac_vlc + 1,
309
+                              c->block, c->dc_cache[i + 1], mb_x, mb_y,
310
+                              c->quant_mat[1]);
311
+        if (ret)
312
+            return ret;
313
+        c->prev_dc[i][mb_x] = c->dc_cache[i + 1][LEFT];
314
+
315
+        ff_mss34_dct_put(c->imgbuf[i], 8, c->block);
316
+        out = dst[i] + mb_x * 16;
317
+        // Since the DCT block is coded as YUV420 and the whole frame as YUV444,
318
+        // we need to scale chroma.
319
+        for (j = 0; j < 16; j++) {
320
+            for (k = 0; k < 8; k++)
321
+                AV_WN16A(out + k * 2, c->imgbuf[i][k + (j & ~1) * 4] * 0x101);
322
+            out += c->pic.linesize[i];
323
+        }
324
+    }
325
+
326
+    return 0;
327
+}
328
+
329
+static void read_vec_pos(GetBitContext *gb, int *vec_pos, int *sel_flag,
330
+                         int *sel_len, int *prev)
331
+{
332
+    int i, y_flag = 0;
333
+
334
+    for (i = 2; i >= 0; i--) {
335
+        if (!sel_flag[i]) {
336
+            vec_pos[i] = 0;
337
+            continue;
338
+        }
339
+        if ((!i && !y_flag) || get_bits1(gb)) {
340
+            if (sel_len[i] > 0) {
341
+                int pval = prev[i];
342
+                vec_pos[i] = get_bits(gb, sel_len[i]);
343
+                if (vec_pos[i] >= pval)
344
+                    vec_pos[i]++;
345
+            } else {
346
+                vec_pos[i] = !prev[i];
347
+            }
348
+            y_flag = 1;
349
+        } else {
350
+            vec_pos[i] = prev[i];
351
+        }
352
+    }
353
+}
354
+
355
+static int get_value_cached(GetBitContext *gb, int vec_pos, uint8_t *vec,
356
+                            int vec_size, int component, int shift, int *prev)
357
+{
358
+    if (vec_pos < vec_size)
359
+        return vec[vec_pos];
360
+    if (!get_bits1(gb))
361
+        return prev[component];
362
+    prev[component] = get_bits(gb, 8 - shift) << shift;
363
+    return prev[component];
364
+}
365
+
366
+#define MKVAL(vals)  (vals[0] | (vals[1] << 3) | (vals[2] << 6))
367
+
368
+/* Image mode - the hardest to comprehend MSS4 coding mode.
369
+ *
370
+ * In this mode all three 16x16 blocks are coded together with a method
371
+ * remotely similar to the methods employed in MSS1-MSS3.
372
+ * The idea is that every component has a vector of 1-4 most common symbols
373
+ * and an escape mode for reading new value from the bitstream. Decoding
374
+ * consists of retrieving pixel values from the vector or reading new ones
375
+ * from the bitstream; depending on flags read from the bitstream, these vector
376
+ * positions can be updated or reused from the state of the previous line
377
+ * or previous pixel.
378
+ */
379
+static int mss4_decode_image_block(MSS4Context *ctx, GetBitContext *gb,
380
+                                   uint8_t *picdst[3], int mb_x, int mb_y)
381
+{
382
+    uint8_t vec[3][4];
383
+    int     vec_len[3];
384
+    int     sel_len[3], sel_flag[3];
385
+    int     i, j, k, mode, split;
386
+    int     prev_vec1 = 0, prev_split = 0;
387
+    int     vals[3] = { 0 };
388
+    int     prev_pix[3] = { 0 };
389
+    int     prev_mode[16] = { 0 };
390
+    uint8_t *dst[3];
391
+
392
+    const int val_shift = ctx->quality == 100 ? 0 : 2;
393
+
394
+    for (i = 0; i < 3; i++)
395
+        dst[i] = ctx->imgbuf[i];
396
+
397
+    for (i = 0; i < 3; i++) {
398
+        vec_len[i] = vec_len_syms[!!i][get_unary(gb, 0, 3)];
399
+        for (j = 0; j < vec_len[i]; j++) {
400
+            vec[i][j]  = get_coeff(gb, &ctx->vec_entry_vlc[!!i]);
401
+            vec[i][j] += ctx->prev_vec[i][j];
402
+            ctx->prev_vec[i][j] = vec[i][j];
403
+        }
404
+        sel_flag[i] = vec_len[i] > 1;
405
+        sel_len[i]  = vec_len[i] > 2 ? vec_len[i] - 2 : 0;
406
+    }
407
+
408
+    for (j = 0; j < 16; j++) {
409
+        if (get_bits1(gb)) {
410
+            split = 0;
411
+            if (get_bits1(gb)) {
412
+                prev_mode[0] = 0;
413
+                vals[0] = vals[1] = vals[2] = 0;
414
+                mode = 2;
415
+            } else {
416
+                mode = get_bits1(gb);
417
+                if (mode)
418
+                    split = get_bits(gb, 4);
419
+            }
420
+            for (i = 0; i < 16; i++) {
421
+                if (mode <= 1) {
422
+                    vals[0] =  prev_mode[i]       & 7;
423
+                    vals[1] = (prev_mode[i] >> 3) & 7;
424
+                    vals[2] =  prev_mode[i] >> 6;
425
+                    if (mode == 1 && i == split) {
426
+                        read_vec_pos(gb, vals, sel_flag, sel_len, vals);
427
+                    }
428
+                } else if (mode == 2) {
429
+                    if (get_bits1(gb))
430
+                        read_vec_pos(gb, vals, sel_flag, sel_len, vals);
431
+                }
432
+                for (k = 0; k < 3; k++)
433
+                    *dst[k]++ = get_value_cached(gb, vals[k], vec[k],
434
+                                                 vec_len[k], k,
435
+                                                 val_shift, prev_pix);
436
+                prev_mode[i] = MKVAL(vals);
437
+            }
438
+        } else {
439
+            if (get_bits1(gb)) {
440
+                split = get_bits(gb, 4);
441
+                if (split >= prev_split)
442
+                    split++;
443
+                prev_split = split;
444
+            } else {
445
+                split = prev_split;
446
+            }
447
+            if (split) {
448
+                vals[0] =  prev_mode[0]       & 7;
449
+                vals[1] = (prev_mode[0] >> 3) & 7;
450
+                vals[2] =  prev_mode[0] >> 6;
451
+                for (i = 0; i < 3; i++) {
452
+                    for (k = 0; k < split; k++) {
453
+                        *dst[i]++ = get_value_cached(gb, vals[i], vec[i],
454
+                                                     vec_len[i], i, val_shift,
455
+                                                     prev_pix);
456
+                        prev_mode[k] = MKVAL(vals);
457
+                    }
458
+                }
459
+            }
460
+
461
+            if (split != 16) {
462
+                vals[0] =  prev_vec1       & 7;
463
+                vals[1] = (prev_vec1 >> 3) & 7;
464
+                vals[2] =  prev_vec1 >> 6;
465
+                if (get_bits1(gb)) {
466
+                    read_vec_pos(gb, vals, sel_flag, sel_len, vals);
467
+                    prev_vec1 = MKVAL(vals);
468
+                }
469
+                for (i = 0; i < 3; i++) {
470
+                    for (k = 0; k < 16 - split; k++) {
471
+                        *dst[i]++ = get_value_cached(gb, vals[i], vec[i],
472
+                                                     vec_len[i], i, val_shift,
473
+                                                     prev_pix);
474
+                        prev_mode[split + k] = MKVAL(vals);
475
+                    }
476
+                }
477
+            }
478
+        }
479
+    }
480
+
481
+    for (i = 0; i < 3; i++)
482
+        for (j = 0; j < 16; j++)
483
+            memcpy(picdst[i] + mb_x * 16 + j * ctx->pic.linesize[i],
484
+                   ctx->imgbuf[i] + j * 16, 16);
485
+
486
+    return 0;
487
+}
488
+
489
+static inline void mss4_update_dc_cache(MSS4Context *c, int mb_x)
490
+{
491
+    int i;
492
+
493
+    c->dc_cache[0][TOP]  = c->prev_dc[0][mb_x * 2 + 1];
494
+    c->dc_cache[0][LEFT] = 0;
495
+    c->dc_cache[1][TOP]  = 0;
496
+    c->dc_cache[1][LEFT] = 0;
497
+
498
+    for (i = 0; i < 2; i++)
499
+        c->prev_dc[0][mb_x * 2 + i] = 0;
500
+
501
+    for (i = 1; i < 3; i++) {
502
+        c->dc_cache[i + 1][TOP]  = c->prev_dc[i][mb_x];
503
+        c->dc_cache[i + 1][LEFT] = 0;
504
+        c->prev_dc[i][mb_x]      = 0;
505
+    }
506
+}
507
+
508
+static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
509
+                             AVPacket *avpkt)
510
+{
511
+    const uint8_t *buf = avpkt->data;
512
+    int buf_size = avpkt->size;
513
+    MSS4Context *c = avctx->priv_data;
514
+    GetBitContext gb;
515
+    GetByteContext bc;
516
+    uint8_t *dst[3];
517
+    int width, height, quality, frame_type;
518
+    int x, y, i, mb_width, mb_height, blk_type;
519
+    int ret;
520
+
521
+    if (buf_size < HEADER_SIZE) {
522
+        av_log(avctx, AV_LOG_ERROR,
523
+               "Frame should have at least %d bytes, got %d instead\n",
524
+               HEADER_SIZE, buf_size);
525
+        return AVERROR_INVALIDDATA;
526
+    }
527
+
528
+    bytestream2_init(&bc, buf, buf_size);
529
+    width      = bytestream2_get_be16(&bc);
530
+    height     = bytestream2_get_be16(&bc);
531
+    bytestream2_skip(&bc, 2);
532
+    quality    = bytestream2_get_byte(&bc);
533
+    frame_type = bytestream2_get_byte(&bc);
534
+
535
+    if (width > avctx->width ||
536
+        height != avctx->height) {
537
+        av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d\n",
538
+               width, height);
539
+        return AVERROR_INVALIDDATA;
540
+    }
541
+    if (quality < 1 || quality > 100) {
542
+        av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality);
543
+        return AVERROR_INVALIDDATA;
544
+    }
545
+    if ((frame_type & ~3) || frame_type == 3) {
546
+        av_log(avctx, AV_LOG_ERROR, "Invalid frame type %d\n", frame_type);
547
+        return AVERROR_INVALIDDATA;
548
+    }
549
+
550
+    if (frame_type != SKIP_FRAME && !bytestream2_get_bytes_left(&bc)) {
551
+        av_log(avctx, AV_LOG_ERROR,
552
+               "Empty frame found but it is not a skip frame.\n");
553
+        return AVERROR_INVALIDDATA;
554
+    }
555
+
556
+    c->pic.reference    = 3;
557
+    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID    |
558
+                          FF_BUFFER_HINTS_PRESERVE |
559
+                          FF_BUFFER_HINTS_REUSABLE;
560
+    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
561
+        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
562
+        return ret;
563
+    }
564
+    c->pic.key_frame = (frame_type == INTRA_FRAME);
565
+    c->pic.pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I
566
+                                                   : AV_PICTURE_TYPE_P;
567
+    if (frame_type == SKIP_FRAME) {
568
+        *data_size = sizeof(AVFrame);
569
+        *(AVFrame*)data = c->pic;
570
+
571
+        return buf_size;
572
+    }
573
+
574
+    if (c->quality != quality) {
575
+        c->quality = quality;
576
+        for (i = 0; i < 2; i++)
577
+            ff_mss34_gen_quant_mat(c->quant_mat[i], quality, !i);
578
+    }
579
+
580
+    init_get_bits(&gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
581
+
582
+    mb_width  = FFALIGN(width,  16) >> 4;
583
+    mb_height = FFALIGN(height, 16) >> 4;
584
+    dst[0] = c->pic.data[0];
585
+    dst[1] = c->pic.data[1];
586
+    dst[2] = c->pic.data[2];
587
+
588
+    memset(c->prev_vec, 0, sizeof(c->prev_vec));
589
+    for (y = 0; y < mb_height; y++) {
590
+        memset(c->dc_cache, 0, sizeof(c->dc_cache));
591
+        for (x = 0; x < mb_width; x++) {
592
+            blk_type = decode012(&gb);
593
+            switch (blk_type) {
594
+            case DCT_BLOCK:
595
+                if (mss4_decode_dct_block(c, &gb, dst, x, y) < 0) {
596
+                    av_log(avctx, AV_LOG_ERROR,
597
+                           "Error decoding DCT block %d,%d\n",
598
+                           x, y);
599
+                    return AVERROR_INVALIDDATA;
600
+                }
601
+                break;
602
+            case IMAGE_BLOCK:
603
+                if (mss4_decode_image_block(c, &gb, dst, x, y) < 0) {
604
+                    av_log(avctx, AV_LOG_ERROR,
605
+                           "Error decoding VQ block %d,%d\n",
606
+                           x, y);
607
+                    return AVERROR_INVALIDDATA;
608
+                }
609
+                break;
610
+            case SKIP_BLOCK:
611
+                if (frame_type == INTRA_FRAME) {
612
+                    av_log(avctx, AV_LOG_ERROR, "Skip block in intra frame\n");
613
+                    return AVERROR_INVALIDDATA;
614
+                }
615
+                break;
616
+            }
617
+            if (blk_type != DCT_BLOCK)
618
+                mss4_update_dc_cache(c, x);
619
+        }
620
+        dst[0] += c->pic.linesize[0] * 16;
621
+        dst[1] += c->pic.linesize[1] * 16;
622
+        dst[2] += c->pic.linesize[2] * 16;
623
+    }
624
+
625
+    *data_size = sizeof(AVFrame);
626
+    *(AVFrame*)data = c->pic;
627
+
628
+    return buf_size;
629
+}
630
+
631
+static av_cold int mss4_decode_init(AVCodecContext *avctx)
632
+{
633
+    MSS4Context * const c = avctx->priv_data;
634
+    int i;
635
+
636
+    if (mss4_init_vlcs(c)) {
637
+        av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n");
638
+        mss4_free_vlcs(c);
639
+        return AVERROR(ENOMEM);
640
+    }
641
+    for (i = 0; i < 3; i++) {
642
+        c->dc_stride[i] = FFALIGN(avctx->width, 16) >> (2 + !!i);
643
+        c->prev_dc[i]   = av_malloc(sizeof(**c->prev_dc) * c->dc_stride[i]);
644
+        if (!c->prev_dc[i]) {
645
+            av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n");
646
+            mss4_free_vlcs(c);
647
+            return AVERROR(ENOMEM);
648
+        }
649
+    }
650
+
651
+    avctx->pix_fmt     = PIX_FMT_YUV444P;
652
+    avctx->coded_frame = &c->pic;
653
+
654
+    return 0;
655
+}
656
+
657
+static av_cold int mss4_decode_end(AVCodecContext *avctx)
658
+{
659
+    MSS4Context * const c = avctx->priv_data;
660
+    int i;
661
+
662
+    if (c->pic.data[0])
663
+        avctx->release_buffer(avctx, &c->pic);
664
+    for (i = 0; i < 3; i++)
665
+        av_freep(&c->prev_dc[i]);
666
+    mss4_free_vlcs(c);
667
+
668
+    return 0;
669
+}
670
+
671
+AVCodec ff_mts2_decoder = {
672
+    .name           = "mts2",
673
+    .type           = AVMEDIA_TYPE_VIDEO,
674
+    .id             = CODEC_ID_MTS2,
675
+    .priv_data_size = sizeof(MSS4Context),
676
+    .init           = mss4_decode_init,
677
+    .close          = mss4_decode_end,
678
+    .decode         = mss4_decode_frame,
679
+    .capabilities   = CODEC_CAP_DR1,
680
+    .long_name      = NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"),
681
+};
... ...
@@ -27,7 +27,7 @@
27 27
  */
28 28
 
29 29
 #define LIBAVCODEC_VERSION_MAJOR 54
30
-#define LIBAVCODEC_VERSION_MINOR 19
30
+#define LIBAVCODEC_VERSION_MINOR 20
31 31
 #define LIBAVCODEC_VERSION_MICRO  0
32 32
 
33 33
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -287,6 +287,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
287 287
     { CODEC_ID_MSS1,         MKTAG('M', 'S', 'S', '1') },
288 288
     { CODEC_ID_MSA1,         MKTAG('M', 'S', 'A', '1') },
289 289
     { CODEC_ID_TSCC2,        MKTAG('T', 'S', 'C', '2') },
290
+    { CODEC_ID_MTS2,         MKTAG('M', 'T', 'S', '2') },
290 291
     { CODEC_ID_NONE,         0 }
291 292
 };
292 293