2 * Microsoft Screen 4 (aka Microsoft Expression Encoder Screen) decoder
3 * Copyright (c) 2012 Konstantin Shishkov
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * Microsoft Screen 4 (aka Microsoft Titanium Screen 2,
25 * aka Microsoft Expression Encoder Screen) decoder
29 #include "bytestream.h"
55 static const uint8_t mss4_dc_vlc_lens
[2][16] = {
56 { 0, 1, 5, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
57 { 0, 3, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0 }
60 static const uint8_t mss4_ac_vlc_lens
[2][16] = {
61 { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 },
62 { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 }
65 static const uint8_t mss4_ac_vlc_syms
[2][162] = {
66 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
67 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
68 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
69 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0,
70 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16,
71 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
72 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
73 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
74 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
75 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
76 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
77 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
78 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
79 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
80 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
81 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5,
82 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4,
83 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
84 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
85 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
87 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
88 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
89 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
90 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0,
91 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34,
92 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
93 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38,
94 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
95 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
96 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
97 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
98 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
99 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
100 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5,
101 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
102 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3,
103 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
104 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
105 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
106 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
110 static const uint8_t vec_len_syms
[2][4] = {
115 static const uint8_t mss4_vec_entry_vlc_lens
[2][16] = {
116 { 0, 2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
117 { 0, 1, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
120 static const uint8_t mss4_vec_entry_vlc_syms
[2][9] = {
121 { 0, 7, 6, 5, 8, 4, 3, 1, 2 },
122 { 0, 2, 3, 4, 5, 6, 7, 1, 8 }
125 #define MAX_ENTRIES 162
127 typedef struct MSS4Context
{
130 VLC dc_vlc
[2], ac_vlc
[2];
131 VLC vec_entry_vlc
[2];
133 uint8_t imgbuf
[3][16 * 16];
136 uint16_t quant_mat
[2][64];
145 static av_cold
int mss4_init_vlc(VLC
*vlc
, const uint8_t *lens
,
146 const uint8_t *syms
, int num_syms
)
148 uint8_t bits
[MAX_ENTRIES
];
149 uint16_t codes
[MAX_ENTRIES
];
151 int prefix
= 0, max_bits
= 0, idx
= 0;
153 for (i
= 0; i
< 16; i
++) {
154 for (j
= 0; j
< lens
[i
]; j
++) {
156 codes
[idx
] = prefix
++;
163 return ff_init_vlc_sparse(vlc
, FFMIN(max_bits
, 9), num_syms
, bits
, 1, 1,
164 codes
, 2, 2, syms
, 1, 1, 0);
167 static av_cold
int mss4_init_vlcs(MSS4Context
*ctx
)
171 for (i
= 0; i
< 2; i
++) {
172 ret
= mss4_init_vlc(&ctx
->dc_vlc
[i
], mss4_dc_vlc_lens
[i
], NULL
, 12);
175 ret
= mss4_init_vlc(&ctx
->ac_vlc
[i
], mss4_ac_vlc_lens
[i
],
176 mss4_ac_vlc_syms
[i
], 162);
179 ret
= mss4_init_vlc(&ctx
->vec_entry_vlc
[i
], mss4_vec_entry_vlc_lens
[i
],
180 mss4_vec_entry_vlc_syms
[i
], 9);
187 static av_cold
void mss4_free_vlcs(MSS4Context
*ctx
)
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
]);
198 /* This function returns values in the range
199 * (-range + 1; -range/2] U [range/2; range - 1)
203 * nbits = 2 -> -3, -2, 2, 3
205 static av_always_inline
int get_coeff_bits(GetBitContext
*gb
, int nbits
)
212 val
= get_bits(gb
, nbits
);
213 if (val
< (1 << (nbits
- 1)))
214 val
-= (1 << nbits
) - 1;
219 static inline int get_coeff(GetBitContext
*gb
, VLC
*vlc
)
221 int val
= get_vlc2(gb
, vlc
->table
, vlc
->bits
, 2);
223 return get_coeff_bits(gb
, val
);
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
)
230 int skip
, val
, pos
= 1, zz_pos
, dc
;
232 memset(block
, 0, sizeof(*block
) * 64);
234 dc
= get_coeff(gb
, dc_vlc
);
235 // DC prediction is the same as in MSS3
241 tl
= dc_cache
[TOP_LEFT
];
244 if (FFABS(t
- tl
) <= FFABS(l
- tl
))
252 dc
+= dc_cache
[LEFT
];
255 block
[0] = dc
* quant_mat
[0];
258 val
= get_vlc2(gb
, ac_vlc
->table
, 9, 2);
268 val
= get_coeff_bits(gb
, val
& 0xF);
273 zz_pos
= ff_zigzag_direct
[pos
];
274 block
[zz_pos
] = val
* quant_mat
[zz_pos
];
278 return pos
== 64 ? 0 : -1;
281 static int mss4_decode_dct_block(MSS4Context
*c
, GetBitContext
*gb
,
282 uint8_t *dst
[3], int mb_x
, int mb_y
)
285 uint8_t *out
= dst
[0];
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
,
294 xpos
, mb_y
* 2 + j
, c
->quant_mat
[0]);
297 c
->prev_dc
[0][mb_x
* 2 + i
] = c
->dc_cache
[j
][LEFT
];
299 ff_mss34_dct_put(out
+ xpos
* 8, c
->pic
->linesize
[0],
302 out
+= 8 * c
->pic
->linesize
[0];
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
,
313 c
->prev_dc
[i
][mb_x
] = c
->dc_cache
[i
+ 1][LEFT
];
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
];
329 static void read_vec_pos(GetBitContext
*gb
, int *vec_pos
, int *sel_flag
,
330 int *sel_len
, int *prev
)
334 for (i
= 2; i
>= 0; i
--) {
339 if ((!i
&& !y_flag
) || get_bits1(gb
)) {
340 if (sel_len
[i
] > 0) {
342 vec_pos
[i
] = get_bits(gb
, sel_len
[i
]);
343 if (vec_pos
[i
] >= pval
)
346 vec_pos
[i
] = !prev
[i
];
350 vec_pos
[i
] = prev
[i
];
355 static int get_value_cached(GetBitContext
*gb
, int vec_pos
, uint8_t *vec
,
356 int vec_size
, int component
, int shift
, int *prev
)
358 if (vec_pos
< vec_size
)
361 return prev
[component
];
362 prev
[component
] = get_bits(gb
, 8 - shift
) << shift
;
363 return prev
[component
];
366 #define MKVAL(vals) ((vals)[0] | ((vals)[1] << 3) | ((vals)[2] << 6))
368 /* Image mode - the hardest to comprehend MSS4 coding mode.
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
379 static int mss4_decode_image_block(MSS4Context
*ctx
, GetBitContext
*gb
,
380 uint8_t *picdst
[3], int mb_x
, int mb_y
)
384 int sel_len
[3], sel_flag
[3];
385 int i
, j
, k
, mode
, split
;
386 int prev_vec1
= 0, prev_split
= 0;
388 int prev_pix
[3] = { 0 };
389 int prev_mode
[16] = { 0 };
392 const int val_shift
= ctx
->quality
== 100 ? 0 : 2;
394 for (i
= 0; i
< 3; i
++)
395 dst
[i
] = ctx
->imgbuf
[i
];
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
];
404 sel_flag
[i
] = vec_len
[i
] > 1;
405 sel_len
[i
] = vec_len
[i
] > 2 ? vec_len
[i
] - 2 : 0;
408 for (j
= 0; j
< 16; j
++) {
413 vals
[0] = vals
[1] = vals
[2] = 0;
416 mode
= get_bits1(gb
);
418 split
= get_bits(gb
, 4);
420 for (i
= 0; i
< 16; i
++) {
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
);
428 } else if (mode
== 2) {
430 read_vec_pos(gb
, vals
, sel_flag
, sel_len
, vals
);
432 for (k
= 0; k
< 3; k
++)
433 *dst
[k
]++ = get_value_cached(gb
, vals
[k
], vec
[k
],
435 val_shift
, prev_pix
);
436 prev_mode
[i
] = MKVAL(vals
);
440 split
= get_bits(gb
, 4);
441 if (split
>= prev_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
,
456 prev_mode
[k
] = MKVAL(vals
);
462 vals
[0] = prev_vec1
& 7;
463 vals
[1] = (prev_vec1
>> 3) & 7;
464 vals
[2] = prev_vec1
>> 6;
466 read_vec_pos(gb
, vals
, sel_flag
, sel_len
, vals
);
467 prev_vec1
= MKVAL(vals
);
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
,
474 prev_mode
[split
+ k
] = MKVAL(vals
);
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);
489 static inline void mss4_update_dc_cache(MSS4Context
*c
, int mb_x
)
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;
498 for (i
= 0; i
< 2; i
++)
499 c
->prev_dc
[0][mb_x
* 2 + i
] = 0;
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;
508 static int mss4_decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
511 const uint8_t *buf
= avpkt
->data
;
512 int buf_size
= avpkt
->size
;
513 MSS4Context
*c
= avctx
->priv_data
;
517 int width
, height
, quality
, frame_type
;
518 int x
, y
, i
, mb_width
, mb_height
, blk_type
;
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
;
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
);
535 if (width
> avctx
->width
||
536 height
!= avctx
->height
) {
537 av_log(avctx
, AV_LOG_ERROR
, "Invalid frame dimensions %dx%d\n",
539 return AVERROR_INVALIDDATA
;
541 if (quality
< 1 || quality
> 100) {
542 av_log(avctx
, AV_LOG_ERROR
, "Invalid quality setting %d\n", quality
);
543 return AVERROR_INVALIDDATA
;
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
;
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
;
556 if ((ret
= ff_reget_buffer(avctx
, c
->pic
)) < 0)
558 c
->pic
->key_frame
= (frame_type
== INTRA_FRAME
);
559 c
->pic
->pict_type
= (frame_type
== INTRA_FRAME
) ? AV_PICTURE_TYPE_I
561 if (frame_type
== SKIP_FRAME
) {
563 if ((ret
= av_frame_ref(data
, c
->pic
)) < 0)
569 if (c
->quality
!= quality
) {
570 c
->quality
= quality
;
571 for (i
= 0; i
< 2; i
++)
572 ff_mss34_gen_quant_mat(c
->quant_mat
[i
], quality
, !i
);
575 init_get_bits8(&gb
, buf
+ HEADER_SIZE
, (buf_size
- HEADER_SIZE
));
577 mb_width
= FFALIGN(width
, 16) >> 4;
578 mb_height
= FFALIGN(height
, 16) >> 4;
579 dst
[0] = c
->pic
->data
[0];
580 dst
[1] = c
->pic
->data
[1];
581 dst
[2] = c
->pic
->data
[2];
583 memset(c
->prev_vec
, 0, sizeof(c
->prev_vec
));
584 for (y
= 0; y
< mb_height
; y
++) {
585 memset(c
->dc_cache
, 0, sizeof(c
->dc_cache
));
586 for (x
= 0; x
< mb_width
; x
++) {
587 blk_type
= decode012(&gb
);
590 if (mss4_decode_dct_block(c
, &gb
, dst
, x
, y
) < 0) {
591 av_log(avctx
, AV_LOG_ERROR
,
592 "Error decoding DCT block %d,%d\n",
594 return AVERROR_INVALIDDATA
;
598 if (mss4_decode_image_block(c
, &gb
, dst
, x
, y
) < 0) {
599 av_log(avctx
, AV_LOG_ERROR
,
600 "Error decoding VQ block %d,%d\n",
602 return AVERROR_INVALIDDATA
;
606 if (frame_type
== INTRA_FRAME
) {
607 av_log(avctx
, AV_LOG_ERROR
, "Skip block in intra frame\n");
608 return AVERROR_INVALIDDATA
;
612 if (blk_type
!= DCT_BLOCK
)
613 mss4_update_dc_cache(c
, x
);
615 dst
[0] += c
->pic
->linesize
[0] * 16;
616 dst
[1] += c
->pic
->linesize
[1] * 16;
617 dst
[2] += c
->pic
->linesize
[2] * 16;
620 if ((ret
= av_frame_ref(data
, c
->pic
)) < 0)
628 static av_cold
int mss4_decode_end(AVCodecContext
*avctx
)
630 MSS4Context
* const c
= avctx
->priv_data
;
633 av_frame_free(&c
->pic
);
634 for (i
= 0; i
< 3; i
++)
635 av_freep(&c
->prev_dc
[i
]);
641 static av_cold
int mss4_decode_init(AVCodecContext
*avctx
)
643 MSS4Context
* const c
= avctx
->priv_data
;
646 if (mss4_init_vlcs(c
)) {
647 av_log(avctx
, AV_LOG_ERROR
, "Cannot initialise VLCs\n");
649 return AVERROR(ENOMEM
);
651 for (i
= 0; i
< 3; i
++) {
652 c
->dc_stride
[i
] = FFALIGN(avctx
->width
, 16) >> (2 + !!i
);
653 c
->prev_dc
[i
] = av_malloc(sizeof(**c
->prev_dc
) * c
->dc_stride
[i
]);
654 if (!c
->prev_dc
[i
]) {
655 av_log(avctx
, AV_LOG_ERROR
, "Cannot allocate buffer\n");
657 return AVERROR(ENOMEM
);
661 c
->pic
= av_frame_alloc();
663 mss4_decode_end(avctx
);
664 return AVERROR(ENOMEM
);
667 avctx
->pix_fmt
= AV_PIX_FMT_YUV444P
;
672 AVCodec ff_mts2_decoder
= {
674 .long_name
= NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"),
675 .type
= AVMEDIA_TYPE_VIDEO
,
676 .id
= AV_CODEC_ID_MTS2
,
677 .priv_data_size
= sizeof(MSS4Context
),
678 .init
= mss4_decode_init
,
679 .close
= mss4_decode_end
,
680 .decode
= mss4_decode_frame
,
681 .capabilities
= CODEC_CAP_DR1
,