3 * Copyright (c) 2006 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
28 * Based on http://wiki.multimedia.cx/index.php?title=Smacker
34 #include "libavutil/channel_layout.h"
39 #define BITSTREAM_READER_LE
41 #include "bytestream.h"
43 #define SMKTREE_BITS 9
44 #define SMK_NODE 0x80000000
49 typedef struct SmackVContext
{
50 AVCodecContext
*avctx
;
53 int *mmap_tbl
, *mclr_tbl
, *full_tbl
, *type_tbl
;
54 int mmap_last
[3], mclr_last
[3], full_last
[3], type_last
[3];
58 * Context used for code reconstructing
60 typedef struct HuffContext
{
69 /* common parameters used for decode_bigtree */
70 typedef struct DBCtx
{
72 int *recode1
, *recode2
;
78 /* possible runs of blocks */
79 static const int block_runs
[64] = {
80 1, 2, 3, 4, 5, 6, 7, 8,
81 9, 10, 11, 12, 13, 14, 15, 16,
82 17, 18, 19, 20, 21, 22, 23, 24,
83 25, 26, 27, 28, 29, 30, 31, 32,
84 33, 34, 35, 36, 37, 38, 39, 40,
85 41, 42, 43, 44, 45, 46, 47, 48,
86 49, 50, 51, 52, 53, 54, 55, 56,
87 57, 58, 59, 128, 256, 512, 1024, 2048 };
96 * Decode local frame tree
98 static int smacker_decode_tree(GetBitContext
*gb
, HuffContext
*hc
, uint32_t prefix
, int length
)
100 if(length
> 32 || length
> 3*SMKTREE_BITS
) {
101 av_log(NULL
, AV_LOG_ERROR
, "length too long\n");
102 return AVERROR_INVALIDDATA
;
104 if(!get_bits1(gb
)){ //Leaf
105 if(hc
->current
>= hc
->length
){
106 av_log(NULL
, AV_LOG_ERROR
, "Tree size exceeded!\n");
107 return AVERROR_INVALIDDATA
;
110 hc
->bits
[hc
->current
] = prefix
;
111 hc
->lengths
[hc
->current
] = length
;
113 hc
->bits
[hc
->current
] = 0;
114 hc
->lengths
[hc
->current
] = 0;
116 hc
->values
[hc
->current
] = get_bits(gb
, 8);
118 if(hc
->maxlength
< length
)
119 hc
->maxlength
= length
;
124 r
= smacker_decode_tree(gb
, hc
, prefix
, length
);
127 return smacker_decode_tree(gb
, hc
, prefix
| (1 << (length
- 1)), length
);
134 static int smacker_decode_bigtree(GetBitContext
*gb
, HuffContext
*hc
, DBCtx
*ctx
)
136 if (hc
->current
+ 1 >= hc
->length
) {
137 av_log(NULL
, AV_LOG_ERROR
, "Tree size exceeded!\n");
138 return AVERROR_INVALIDDATA
;
140 if(!get_bits1(gb
)){ //Leaf
142 i1
= ctx
->v1
->table
? get_vlc2(gb
, ctx
->v1
->table
, SMKTREE_BITS
, 3) : 0;
143 i2
= ctx
->v2
->table
? get_vlc2(gb
, ctx
->v2
->table
, SMKTREE_BITS
, 3) : 0;
144 if (i1
< 0 || i2
< 0)
145 return AVERROR_INVALIDDATA
;
146 val
= ctx
->recode1
[i1
] | (ctx
->recode2
[i2
] << 8);
147 if(val
== ctx
->escapes
[0]) {
148 ctx
->last
[0] = hc
->current
;
150 } else if(val
== ctx
->escapes
[1]) {
151 ctx
->last
[1] = hc
->current
;
153 } else if(val
== ctx
->escapes
[2]) {
154 ctx
->last
[2] = hc
->current
;
158 hc
->values
[hc
->current
++] = val
;
164 r
= smacker_decode_bigtree(gb
, hc
, ctx
);
167 hc
->values
[t
] = SMK_NODE
| r
;
169 r_new
= smacker_decode_bigtree(gb
, hc
, ctx
);
177 * Store large tree as FFmpeg's vlc codes
179 static int smacker_decode_header_tree(SmackVContext
*smk
, GetBitContext
*gb
, int **recodes
, int *last
, int size
)
183 HuffContext tmp1
, tmp2
;
184 VLC vlc
[2] = { { 0 } };
189 if(size
>= UINT_MAX
>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow
190 av_log(smk
->avctx
, AV_LOG_ERROR
, "size too large\n");
191 return AVERROR_INVALIDDATA
;
197 tmp1
.bits
= av_mallocz(256 * 4);
198 tmp1
.lengths
= av_mallocz(256 * sizeof(int));
199 tmp1
.values
= av_mallocz(256 * sizeof(int));
204 tmp2
.bits
= av_mallocz(256 * 4);
205 tmp2
.lengths
= av_mallocz(256 * sizeof(int));
206 tmp2
.values
= av_mallocz(256 * sizeof(int));
207 if (!tmp1
.bits
|| !tmp1
.lengths
|| !tmp1
.values
||
208 !tmp2
.bits
|| !tmp2
.lengths
|| !tmp2
.values
) {
209 err
= AVERROR(ENOMEM
);
214 res
= smacker_decode_tree(gb
, &tmp1
, 0, 0);
220 if(tmp1
.current
> 1) {
221 res
= init_vlc(&vlc
[0], SMKTREE_BITS
, tmp1
.length
,
222 tmp1
.lengths
, sizeof(int), sizeof(int),
223 tmp1
.bits
, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE
);
225 av_log(smk
->avctx
, AV_LOG_ERROR
, "Cannot build VLC table\n");
232 av_log(smk
->avctx
, AV_LOG_ERROR
, "Skipping low bytes tree\n");
235 res
= smacker_decode_tree(gb
, &tmp2
, 0, 0);
241 if(tmp2
.current
> 1) {
242 res
= init_vlc(&vlc
[1], SMKTREE_BITS
, tmp2
.length
,
243 tmp2
.lengths
, sizeof(int), sizeof(int),
244 tmp2
.bits
, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE
);
246 av_log(smk
->avctx
, AV_LOG_ERROR
, "Cannot build VLC table\n");
253 av_log(smk
->avctx
, AV_LOG_ERROR
, "Skipping high bytes tree\n");
256 escapes
[0] = get_bits(gb
, 16);
257 escapes
[1] = get_bits(gb
, 16);
258 escapes
[2] = get_bits(gb
, 16);
260 last
[0] = last
[1] = last
[2] = -1;
262 ctx
.escapes
[0] = escapes
[0];
263 ctx
.escapes
[1] = escapes
[1];
264 ctx
.escapes
[2] = escapes
[2];
267 ctx
.recode1
= tmp1
.values
;
268 ctx
.recode2
= tmp2
.values
;
271 huff
.length
= ((size
+ 3) >> 2) + 4;
274 huff
.values
= av_mallocz_array(huff
.length
, sizeof(int));
276 err
= AVERROR(ENOMEM
);
280 if (smacker_decode_bigtree(gb
, &huff
, &ctx
) < 0)
283 if(ctx
.last
[0] == -1) ctx
.last
[0] = huff
.current
++;
284 if(ctx
.last
[1] == -1) ctx
.last
[1] = huff
.current
++;
285 if(ctx
.last
[2] == -1) ctx
.last
[2] = huff
.current
++;
286 if (ctx
.last
[0] >= huff
.length
||
287 ctx
.last
[1] >= huff
.length
||
288 ctx
.last
[2] >= huff
.length
) {
289 av_log(smk
->avctx
, AV_LOG_ERROR
, "Huffman codes out of range\n");
290 err
= AVERROR_INVALIDDATA
;
293 *recodes
= huff
.values
;
297 ff_free_vlc(&vlc
[0]);
299 ff_free_vlc(&vlc
[1]);
301 av_free(tmp1
.lengths
);
302 av_free(tmp1
.values
);
304 av_free(tmp2
.lengths
);
305 av_free(tmp2
.values
);
310 static int decode_header_trees(SmackVContext
*smk
) {
312 int mmap_size
, mclr_size
, full_size
, type_size
, ret
;
314 mmap_size
= AV_RL32(smk
->avctx
->extradata
);
315 mclr_size
= AV_RL32(smk
->avctx
->extradata
+ 4);
316 full_size
= AV_RL32(smk
->avctx
->extradata
+ 8);
317 type_size
= AV_RL32(smk
->avctx
->extradata
+ 12);
319 init_get_bits8(&gb
, smk
->avctx
->extradata
+ 16, smk
->avctx
->extradata_size
- 16);
321 if(!get_bits1(&gb
)) {
322 av_log(smk
->avctx
, AV_LOG_INFO
, "Skipping MMAP tree\n");
323 smk
->mmap_tbl
= av_malloc(sizeof(int) * 2);
325 return AVERROR(ENOMEM
);
326 smk
->mmap_tbl
[0] = 0;
327 smk
->mmap_last
[0] = smk
->mmap_last
[1] = smk
->mmap_last
[2] = 1;
329 ret
= smacker_decode_header_tree(smk
, &gb
, &smk
->mmap_tbl
, smk
->mmap_last
, mmap_size
);
333 if(!get_bits1(&gb
)) {
334 av_log(smk
->avctx
, AV_LOG_INFO
, "Skipping MCLR tree\n");
335 smk
->mclr_tbl
= av_malloc(sizeof(int) * 2);
337 return AVERROR(ENOMEM
);
338 smk
->mclr_tbl
[0] = 0;
339 smk
->mclr_last
[0] = smk
->mclr_last
[1] = smk
->mclr_last
[2] = 1;
341 ret
= smacker_decode_header_tree(smk
, &gb
, &smk
->mclr_tbl
, smk
->mclr_last
, mclr_size
);
345 if(!get_bits1(&gb
)) {
346 av_log(smk
->avctx
, AV_LOG_INFO
, "Skipping FULL tree\n");
347 smk
->full_tbl
= av_malloc(sizeof(int) * 2);
349 return AVERROR(ENOMEM
);
350 smk
->full_tbl
[0] = 0;
351 smk
->full_last
[0] = smk
->full_last
[1] = smk
->full_last
[2] = 1;
353 ret
= smacker_decode_header_tree(smk
, &gb
, &smk
->full_tbl
, smk
->full_last
, full_size
);
357 if(!get_bits1(&gb
)) {
358 av_log(smk
->avctx
, AV_LOG_INFO
, "Skipping TYPE tree\n");
359 smk
->type_tbl
= av_malloc(sizeof(int) * 2);
361 return AVERROR(ENOMEM
);
362 smk
->type_tbl
[0] = 0;
363 smk
->type_last
[0] = smk
->type_last
[1] = smk
->type_last
[2] = 1;
365 ret
= smacker_decode_header_tree(smk
, &gb
, &smk
->type_tbl
, smk
->type_last
, type_size
);
373 static av_always_inline
void last_reset(int *recode
, int *last
) {
374 recode
[last
[0]] = recode
[last
[1]] = recode
[last
[2]] = 0;
377 /* get code and update history */
378 static av_always_inline
int smk_get_code(GetBitContext
*gb
, int *recode
, int *last
) {
379 register int *table
= recode
;
382 while(*table
& SMK_NODE
) {
384 table
+= (*table
) & (~SMK_NODE
);
389 if(v
!= recode
[last
[0]]) {
390 recode
[last
[2]] = recode
[last
[1]];
391 recode
[last
[1]] = recode
[last
[0]];
397 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
400 SmackVContext
* const smk
= avctx
->priv_data
;
405 int blocks
, blk
, bw
, bh
;
410 if (avpkt
->size
<= 769)
411 return AVERROR_INVALIDDATA
;
413 if ((ret
= ff_reget_buffer(avctx
, smk
->pic
)) < 0)
416 /* make the palette available on the way out */
417 pal
= (uint32_t*)smk
->pic
->data
[1];
418 bytestream2_init(&gb2
, avpkt
->data
, avpkt
->size
);
419 flags
= bytestream2_get_byteu(&gb2
);
420 smk
->pic
->palette_has_changed
= flags
& 1;
421 smk
->pic
->key_frame
= !!(flags
& 2);
422 if (smk
->pic
->key_frame
)
423 smk
->pic
->pict_type
= AV_PICTURE_TYPE_I
;
425 smk
->pic
->pict_type
= AV_PICTURE_TYPE_P
;
427 for(i
= 0; i
< 256; i
++)
428 *pal
++ = 0xFFU
<< 24 | bytestream2_get_be24u(&gb2
);
430 last_reset(smk
->mmap_tbl
, smk
->mmap_last
);
431 last_reset(smk
->mclr_tbl
, smk
->mclr_last
);
432 last_reset(smk
->full_tbl
, smk
->full_last
);
433 last_reset(smk
->type_tbl
, smk
->type_last
);
434 if ((ret
= init_get_bits8(&gb
, avpkt
->data
+ 769, avpkt
->size
- 769)) < 0)
438 bw
= avctx
->width
>> 2;
439 bh
= avctx
->height
>> 2;
441 stride
= smk
->pic
->linesize
[0];
442 while(blk
< blocks
) {
446 type
= smk_get_code(&gb
, smk
->type_tbl
, smk
->type_last
);
447 run
= block_runs
[(type
>> 2) & 0x3F];
450 while(run
-- && blk
< blocks
){
453 clr
= smk_get_code(&gb
, smk
->mclr_tbl
, smk
->mclr_last
);
454 map
= smk_get_code(&gb
, smk
->mmap_tbl
, smk
->mmap_last
);
455 out
= smk
->pic
->data
[0] + (blk
/ bw
) * (stride
* 4) + (blk
% bw
) * 4;
458 for(i
= 0; i
< 4; i
++) {
459 if(map
& 1) out
[0] = hi
; else out
[0] = lo
;
460 if(map
& 2) out
[1] = hi
; else out
[1] = lo
;
461 if(map
& 4) out
[2] = hi
; else out
[2] = lo
;
462 if(map
& 8) out
[3] = hi
; else out
[3] = lo
;
471 if(avctx
->codec_tag
== MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes
472 if(get_bits1(&gb
)) mode
= 1;
473 else if(get_bits1(&gb
)) mode
= 2;
475 while(run
-- && blk
< blocks
){
476 out
= smk
->pic
->data
[0] + (blk
/ bw
) * (stride
* 4) + (blk
% bw
) * 4;
479 for(i
= 0; i
< 4; i
++) {
480 pix
= smk_get_code(&gb
, smk
->full_tbl
, smk
->full_last
);
482 pix
= smk_get_code(&gb
, smk
->full_tbl
, smk
->full_last
);
488 pix
= smk_get_code(&gb
, smk
->full_tbl
, smk
->full_last
);
489 out
[0] = out
[1] = pix
& 0xFF;
490 out
[2] = out
[3] = pix
>> 8;
492 out
[0] = out
[1] = pix
& 0xFF;
493 out
[2] = out
[3] = pix
>> 8;
495 pix
= smk_get_code(&gb
, smk
->full_tbl
, smk
->full_last
);
496 out
[0] = out
[1] = pix
& 0xFF;
497 out
[2] = out
[3] = pix
>> 8;
499 out
[0] = out
[1] = pix
& 0xFF;
500 out
[2] = out
[3] = pix
>> 8;
503 for(i
= 0; i
< 2; i
++) {
505 pix2
= smk_get_code(&gb
, smk
->full_tbl
, smk
->full_last
);
506 pix1
= smk_get_code(&gb
, smk
->full_tbl
, smk
->full_last
);
520 while(run
-- && blk
< blocks
)
525 while(run
-- && blk
< blocks
){
527 out
= smk
->pic
->data
[0] + (blk
/ bw
) * (stride
* 4) + (blk
% bw
) * 4;
528 col
= mode
* 0x01010101;
529 for(i
= 0; i
< 4; i
++) {
530 *((uint32_t*)out
) = col
;
540 if ((ret
= av_frame_ref(data
, smk
->pic
)) < 0)
545 /* always report that the buffer was completely consumed */
553 * Uninit smacker decoder
556 static av_cold
int decode_end(AVCodecContext
*avctx
)
558 SmackVContext
* const smk
= avctx
->priv_data
;
560 av_freep(&smk
->mmap_tbl
);
561 av_freep(&smk
->mclr_tbl
);
562 av_freep(&smk
->full_tbl
);
563 av_freep(&smk
->type_tbl
);
565 av_frame_free(&smk
->pic
);
573 * Init smacker decoder
576 static av_cold
int decode_init(AVCodecContext
*avctx
)
578 SmackVContext
* const c
= avctx
->priv_data
;
583 avctx
->pix_fmt
= AV_PIX_FMT_PAL8
;
585 c
->pic
= av_frame_alloc();
587 return AVERROR(ENOMEM
);
589 /* decode huffman trees from extradata */
590 if(avctx
->extradata_size
< 16){
591 av_log(avctx
, AV_LOG_ERROR
, "Extradata missing!\n");
593 return AVERROR(EINVAL
);
596 ret
= decode_header_trees(c
);
606 static av_cold
int smka_decode_init(AVCodecContext
*avctx
)
608 if (avctx
->channels
< 1 || avctx
->channels
> 2) {
609 av_log(avctx
, AV_LOG_ERROR
, "invalid number of channels\n");
610 return AVERROR(EINVAL
);
612 avctx
->channel_layout
= (avctx
->channels
==2) ? AV_CH_LAYOUT_STEREO
: AV_CH_LAYOUT_MONO
;
613 avctx
->sample_fmt
= avctx
->bits_per_coded_sample
== 8 ? AV_SAMPLE_FMT_U8
: AV_SAMPLE_FMT_S16
;
619 * Decode Smacker audio data
621 static int smka_decode_frame(AVCodecContext
*avctx
, void *data
,
622 int *got_frame_ptr
, AVPacket
*avpkt
)
624 AVFrame
*frame
= data
;
625 const uint8_t *buf
= avpkt
->data
;
626 int buf_size
= avpkt
->size
;
628 HuffContext h
[4] = { { 0 } };
629 VLC vlc
[4] = { { 0 } };
636 int pred
[2] = {0, 0};
639 av_log(avctx
, AV_LOG_ERROR
, "packet is too small\n");
640 return AVERROR(EINVAL
);
643 unp_size
= AV_RL32(buf
);
645 if (unp_size
> (1U<<24)) {
646 av_log(avctx
, AV_LOG_ERROR
, "packet is too big\n");
647 return AVERROR_INVALIDDATA
;
650 if ((ret
= init_get_bits8(&gb
, buf
+ 4, buf_size
- 4)) < 0)
654 av_log(avctx
, AV_LOG_INFO
, "Sound: no data\n");
658 stereo
= get_bits1(&gb
);
659 bits
= get_bits1(&gb
);
660 if (stereo
^ (avctx
->channels
!= 1)) {
661 av_log(avctx
, AV_LOG_ERROR
, "channels mismatch\n");
662 return AVERROR(EINVAL
);
664 if (bits
== (avctx
->sample_fmt
== AV_SAMPLE_FMT_U8
)) {
665 av_log(avctx
, AV_LOG_ERROR
, "sample format mismatch\n");
666 return AVERROR(EINVAL
);
669 /* get output buffer */
670 frame
->nb_samples
= unp_size
/ (avctx
->channels
* (bits
+ 1));
671 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
673 samples
= (int16_t *)frame
->data
[0];
674 samples8
= frame
->data
[0];
677 for(i
= 0; i
< (1 << (bits
+ stereo
)); i
++) {
681 h
[i
].bits
= av_mallocz(256 * 4);
682 h
[i
].lengths
= av_mallocz(256 * sizeof(int));
683 h
[i
].values
= av_mallocz(256 * sizeof(int));
684 if (!h
[i
].bits
|| !h
[i
].lengths
|| !h
[i
].values
) {
685 ret
= AVERROR(ENOMEM
);
689 if (smacker_decode_tree(&gb
, &h
[i
], 0, 0) < 0) {
690 ret
= AVERROR_INVALIDDATA
;
694 if(h
[i
].current
> 1) {
695 res
= init_vlc(&vlc
[i
], SMKTREE_BITS
, h
[i
].length
,
696 h
[i
].lengths
, sizeof(int), sizeof(int),
697 h
[i
].bits
, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE
);
699 av_log(avctx
, AV_LOG_ERROR
, "Cannot build VLC table\n");
700 ret
= AVERROR_INVALIDDATA
;
705 /* this codec relies on wraparound instead of clipping audio */
706 if(bits
) { //decode 16-bit data
707 for(i
= stereo
; i
>= 0; i
--)
708 pred
[i
] = sign_extend(av_bswap16(get_bits(&gb
, 16)), 16);
709 for(i
= 0; i
<= stereo
; i
++)
710 *samples
++ = pred
[i
];
711 for(; i
< unp_size
/ 2; i
++) {
712 if(get_bits_left(&gb
)<0)
713 return AVERROR_INVALIDDATA
;
716 res
= get_vlc2(&gb
, vlc
[2].table
, SMKTREE_BITS
, 3);
720 av_log(avctx
, AV_LOG_ERROR
, "invalid vlc\n");
721 return AVERROR_INVALIDDATA
;
723 val
= h
[2].values
[res
];
725 res
= get_vlc2(&gb
, vlc
[3].table
, SMKTREE_BITS
, 3);
729 av_log(avctx
, AV_LOG_ERROR
, "invalid vlc\n");
730 return AVERROR_INVALIDDATA
;
732 val
|= h
[3].values
[res
] << 8;
733 pred
[1] += sign_extend(val
, 16);
734 *samples
++ = pred
[1];
737 res
= get_vlc2(&gb
, vlc
[0].table
, SMKTREE_BITS
, 3);
741 av_log(avctx
, AV_LOG_ERROR
, "invalid vlc\n");
742 return AVERROR_INVALIDDATA
;
744 val
= h
[0].values
[res
];
746 res
= get_vlc2(&gb
, vlc
[1].table
, SMKTREE_BITS
, 3);
750 av_log(avctx
, AV_LOG_ERROR
, "invalid vlc\n");
751 return AVERROR_INVALIDDATA
;
753 val
|= h
[1].values
[res
] << 8;
754 pred
[0] += sign_extend(val
, 16);
755 *samples
++ = pred
[0];
758 } else { //8-bit data
759 for(i
= stereo
; i
>= 0; i
--)
760 pred
[i
] = get_bits(&gb
, 8);
761 for(i
= 0; i
<= stereo
; i
++)
762 *samples8
++ = pred
[i
];
763 for(; i
< unp_size
; i
++) {
764 if(get_bits_left(&gb
)<0)
765 return AVERROR_INVALIDDATA
;
768 res
= get_vlc2(&gb
, vlc
[1].table
, SMKTREE_BITS
, 3);
772 av_log(avctx
, AV_LOG_ERROR
, "invalid vlc\n");
773 return AVERROR_INVALIDDATA
;
775 pred
[1] += sign_extend(h
[1].values
[res
], 8);
776 *samples8
++ = pred
[1];
779 res
= get_vlc2(&gb
, vlc
[0].table
, SMKTREE_BITS
, 3);
783 av_log(avctx
, AV_LOG_ERROR
, "invalid vlc\n");
784 return AVERROR_INVALIDDATA
;
786 pred
[0] += sign_extend(h
[0].values
[res
], 8);
787 *samples8
++ = pred
[0];
796 for(i
= 0; i
< 4; i
++) {
798 ff_free_vlc(&vlc
[i
]);
800 av_free(h
[i
].lengths
);
801 av_free(h
[i
].values
);
807 AVCodec ff_smacker_decoder
= {
809 .long_name
= NULL_IF_CONFIG_SMALL("Smacker video"),
810 .type
= AVMEDIA_TYPE_VIDEO
,
811 .id
= AV_CODEC_ID_SMACKVIDEO
,
812 .priv_data_size
= sizeof(SmackVContext
),
815 .decode
= decode_frame
,
816 .capabilities
= CODEC_CAP_DR1
,
819 AVCodec ff_smackaud_decoder
= {
821 .long_name
= NULL_IF_CONFIG_SMALL("Smacker audio"),
822 .type
= AVMEDIA_TYPE_AUDIO
,
823 .id
= AV_CODEC_ID_SMACKAUDIO
,
824 .init
= smka_decode_init
,
825 .decode
= smka_decode_frame
,
826 .capabilities
= CODEC_CAP_DR1
,