]> git.sesse.net Git - ffmpeg/blob - libavcodec/vmdav.c
Merge commit 'af7d13ee4a4bf8d708f9b0598abb8f6e22b76de1'
[ffmpeg] / libavcodec / vmdav.c
1 /*
2  * Sierra VMD Audio & Video Decoders
3  * Copyright (C) 2004 the ffmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21
22 /**
23  * @file
24  * Sierra VMD audio & video decoders
25  * by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
26  * for more information on the Sierra VMD format, visit:
27  *   http://www.pcisys.net/~melanson/codecs/
28  *
29  * The video decoder outputs PAL8 colorspace data. The decoder expects
30  * a 0x330-byte VMD file header to be transmitted via extradata during
31  * codec initialization. Each encoded frame that is sent to this decoder
32  * is expected to be prepended with the appropriate 16-byte frame
33  * information record from the VMD file.
34  *
35  * The audio decoder, like the video decoder, expects each encoded data
36  * chunk to be prepended with the appropriate 16-byte frame information
37  * record from the VMD file. It does not require the 0x330-byte VMD file
38  * header, but it does need the audio setup parameters passed in through
39  * normal libavcodec API means.
40  */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45
46 #include "libavutil/channel_layout.h"
47 #include "libavutil/common.h"
48 #include "libavutil/intreadwrite.h"
49 #include "avcodec.h"
50
51 #define VMD_HEADER_SIZE 0x330
52 #define PALETTE_COUNT 256
53
54 /*
55  * Video Decoder
56  */
57
58 typedef struct VmdVideoContext {
59
60     AVCodecContext *avctx;
61     AVFrame frame;
62     AVFrame prev_frame;
63
64     const unsigned char *buf;
65     int size;
66
67     unsigned char palette[PALETTE_COUNT * 4];
68     unsigned char *unpack_buffer;
69     int unpack_buffer_size;
70
71     int x_off, y_off;
72 } VmdVideoContext;
73
74 #define QUEUE_SIZE 0x1000
75 #define QUEUE_MASK 0x0FFF
76
77 static void lz_unpack(const unsigned char *src, int src_len,
78                       unsigned char *dest, int dest_len)
79 {
80     const unsigned char *s;
81     const unsigned char *s_end;
82     unsigned char *d;
83     unsigned char *d_end;
84     unsigned char queue[QUEUE_SIZE];
85     unsigned int qpos;
86     unsigned int dataleft;
87     unsigned int chainofs;
88     unsigned int chainlen;
89     unsigned int speclen;
90     unsigned char tag;
91     unsigned int i, j;
92
93     s = src;
94     s_end = src + src_len;
95     d = dest;
96     d_end = d + dest_len;
97
98     if (s_end - s < 8)
99         return;
100     dataleft = AV_RL32(s);
101     s += 4;
102     memset(queue, 0x20, QUEUE_SIZE);
103     if (AV_RL32(s) == 0x56781234) {
104         s += 4;
105         qpos = 0x111;
106         speclen = 0xF + 3;
107     } else {
108         qpos = 0xFEE;
109         speclen = 100;  /* no speclen */
110     }
111
112     while (s_end - s > 0 && dataleft > 0) {
113         tag = *s++;
114         if ((tag == 0xFF) && (dataleft > 8)) {
115             if (d_end - d < 8 || s_end - s < 8)
116                 return;
117             for (i = 0; i < 8; i++) {
118                 queue[qpos++] = *d++ = *s++;
119                 qpos &= QUEUE_MASK;
120             }
121             dataleft -= 8;
122         } else {
123             for (i = 0; i < 8; i++) {
124                 if (dataleft == 0)
125                     break;
126                 if (tag & 0x01) {
127                     if (d_end - d < 1 || s_end - s < 1)
128                         return;
129                     queue[qpos++] = *d++ = *s++;
130                     qpos &= QUEUE_MASK;
131                     dataleft--;
132                 } else {
133                     if (s_end - s < 2)
134                         return;
135                     chainofs = *s++;
136                     chainofs |= ((*s & 0xF0) << 4);
137                     chainlen = (*s++ & 0x0F) + 3;
138                     if (chainlen == speclen) {
139                         if (s_end - s < 1)
140                             return;
141                         chainlen = *s++ + 0xF + 3;
142                     }
143                     if (d_end - d < chainlen)
144                         return;
145                     for (j = 0; j < chainlen; j++) {
146                         *d = queue[chainofs++ & QUEUE_MASK];
147                         queue[qpos++] = *d++;
148                         qpos &= QUEUE_MASK;
149                     }
150                     dataleft -= chainlen;
151                 }
152                 tag >>= 1;
153             }
154         }
155     }
156 }
157
158 static int rle_unpack(const unsigned char *src, int src_len, int src_count,
159                       unsigned char *dest, int dest_len)
160 {
161     const unsigned char *ps;
162     const unsigned char *ps_end;
163     unsigned char *pd;
164     int i, l;
165     unsigned char *dest_end = dest + dest_len;
166
167     ps = src;
168     ps_end = src + src_len;
169     pd = dest;
170     if (src_count & 1) {
171         if (ps_end - ps < 1)
172             return 0;
173         *pd++ = *ps++;
174     }
175
176     src_count >>= 1;
177     i = 0;
178     do {
179         if (ps_end - ps < 1)
180             break;
181         l = *ps++;
182         if (l & 0x80) {
183             l = (l & 0x7F) * 2;
184             if (dest_end - pd < l || ps_end - ps < l)
185                 return ps - src;
186             memcpy(pd, ps, l);
187             ps += l;
188             pd += l;
189         } else {
190             if (dest_end - pd < i || ps_end - ps < 2)
191                 return ps - src;
192             for (i = 0; i < l; i++) {
193                 *pd++ = ps[0];
194                 *pd++ = ps[1];
195             }
196             ps += 2;
197         }
198         i += l;
199     } while (i < src_count);
200
201     return ps - src;
202 }
203
204 static void vmd_decode(VmdVideoContext *s)
205 {
206     int i;
207     unsigned int *palette32;
208     unsigned char r, g, b;
209
210     /* point to the start of the encoded data */
211     const unsigned char *p = s->buf + 16;
212     const unsigned char *p_end = s->buf + s->size;
213
214     const unsigned char *pb;
215     const unsigned char *pb_end;
216     unsigned char meth;
217     unsigned char *dp;   /* pointer to current frame */
218     unsigned char *pp;   /* pointer to previous frame */
219     unsigned char len;
220     int ofs;
221
222     int frame_x, frame_y;
223     int frame_width, frame_height;
224
225     frame_x = AV_RL16(&s->buf[6]);
226     frame_y = AV_RL16(&s->buf[8]);
227     frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
228     frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
229     if (frame_x < 0 || frame_width < 0 ||
230         frame_x >= s->avctx->width ||
231         frame_width > s->avctx->width ||
232         frame_x + frame_width > s->avctx->width)
233         return;
234     if (frame_y < 0 || frame_height < 0 ||
235         frame_y >= s->avctx->height ||
236         frame_height > s->avctx->height ||
237         frame_y + frame_height > s->avctx->height)
238         return;
239
240     if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
241         (frame_x || frame_y)) {
242
243         s->x_off = frame_x;
244         s->y_off = frame_y;
245     }
246     frame_x -= s->x_off;
247     frame_y -= s->y_off;
248
249     /* if only a certain region will be updated, copy the entire previous
250      * frame before the decode */
251     if (s->prev_frame.data[0] &&
252         (frame_x || frame_y || (frame_width != s->avctx->width) ||
253         (frame_height != s->avctx->height))) {
254
255         memcpy(s->frame.data[0], s->prev_frame.data[0],
256             s->avctx->height * s->frame.linesize[0]);
257     }
258
259     /* check if there is a new palette */
260     if (s->buf[15] & 0x02) {
261         if (p_end - p < 2 + 3 * PALETTE_COUNT)
262             return;
263         p += 2;
264         palette32 = (unsigned int *)s->palette;
265         for (i = 0; i < PALETTE_COUNT; i++) {
266             r = *p++ * 4;
267             g = *p++ * 4;
268             b = *p++ * 4;
269             palette32[i] = 0xFFU << 24 | r << 16 | g << 8 | b;
270             palette32[i] |= palette32[i] >> 6 & 0x30303;
271         }
272     }
273     if (p < p_end) {
274         /* originally UnpackFrame in VAG's code */
275         pb = p;
276         pb_end = p_end;
277         meth = *pb++;
278         if (meth & 0x80) {
279             lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
280             meth &= 0x7F;
281             pb = s->unpack_buffer;
282             pb_end = s->unpack_buffer + s->unpack_buffer_size;
283         }
284
285         dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
286         pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
287         switch (meth) {
288         case 1:
289             for (i = 0; i < frame_height; i++) {
290                 ofs = 0;
291                 do {
292                     if (pb_end - pb < 1)
293                         return;
294                     len = *pb++;
295                     if (len & 0x80) {
296                         len = (len & 0x7F) + 1;
297                         if (ofs + len > frame_width || pb_end - pb < len)
298                             return;
299                         memcpy(&dp[ofs], pb, len);
300                         pb += len;
301                         ofs += len;
302                     } else {
303                         /* interframe pixel copy */
304                         if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
305                             return;
306                         memcpy(&dp[ofs], &pp[ofs], len + 1);
307                         ofs += len + 1;
308                     }
309                 } while (ofs < frame_width);
310                 if (ofs > frame_width) {
311                     av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n",
312                         ofs, frame_width);
313                     break;
314                 }
315                 dp += s->frame.linesize[0];
316                 pp += s->prev_frame.linesize[0];
317             }
318             break;
319
320         case 2:
321             for (i = 0; i < frame_height; i++) {
322                 if (pb_end -pb < frame_width)
323                     return;
324                 memcpy(dp, pb, frame_width);
325                 pb += frame_width;
326                 dp += s->frame.linesize[0];
327                 pp += s->prev_frame.linesize[0];
328             }
329             break;
330
331         case 3:
332             for (i = 0; i < frame_height; i++) {
333                 ofs = 0;
334                 do {
335                     if (pb_end - pb < 1)
336                         return;
337                     len = *pb++;
338                     if (len & 0x80) {
339                         len = (len & 0x7F) + 1;
340                         if (pb_end - pb < 1)
341                             return;
342                         if (*pb++ == 0xFF)
343                             len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs);
344                         else {
345                         if (pb_end - pb < len)
346                             return;
347                             memcpy(&dp[ofs], pb, len);
348                         }
349                         pb += len;
350                         ofs += len;
351                     } else {
352                         /* interframe pixel copy */
353                         if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
354                             return;
355                         memcpy(&dp[ofs], &pp[ofs], len + 1);
356                         ofs += len + 1;
357                     }
358                 } while (ofs < frame_width);
359                 if (ofs > frame_width) {
360                     av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n",
361                         ofs, frame_width);
362                 }
363                 dp += s->frame.linesize[0];
364                 pp += s->prev_frame.linesize[0];
365             }
366             break;
367         }
368     }
369 }
370
371 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
372 {
373     VmdVideoContext *s = avctx->priv_data;
374     int i;
375     unsigned int *palette32;
376     int palette_index = 0;
377     unsigned char r, g, b;
378     unsigned char *vmd_header;
379     unsigned char *raw_palette;
380
381     s->avctx = avctx;
382     avctx->pix_fmt = AV_PIX_FMT_PAL8;
383
384     /* make sure the VMD header made it */
385     if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
386         av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n",
387             VMD_HEADER_SIZE);
388         return -1;
389     }
390     vmd_header = (unsigned char *)avctx->extradata;
391
392     s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
393     s->unpack_buffer = av_malloc(s->unpack_buffer_size);
394     if (!s->unpack_buffer)
395         return -1;
396
397     /* load up the initial palette */
398     raw_palette = &vmd_header[28];
399     palette32 = (unsigned int *)s->palette;
400     for (i = 0; i < PALETTE_COUNT; i++) {
401         r = raw_palette[palette_index++] * 4;
402         g = raw_palette[palette_index++] * 4;
403         b = raw_palette[palette_index++] * 4;
404         palette32[i] = (r << 16) | (g << 8) | (b);
405     }
406
407     avcodec_get_frame_defaults(&s->frame);
408     avcodec_get_frame_defaults(&s->prev_frame);
409
410     return 0;
411 }
412
413 static int vmdvideo_decode_frame(AVCodecContext *avctx,
414                                  void *data, int *data_size,
415                                  AVPacket *avpkt)
416 {
417     const uint8_t *buf = avpkt->data;
418     int buf_size = avpkt->size;
419     VmdVideoContext *s = avctx->priv_data;
420
421     s->buf = buf;
422     s->size = buf_size;
423
424     if (buf_size < 16)
425         return buf_size;
426
427     s->frame.reference = 3;
428     if (avctx->get_buffer(avctx, &s->frame)) {
429         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
430         return -1;
431     }
432
433     vmd_decode(s);
434
435     /* make the palette available on the way out */
436     memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
437
438     /* shuffle frames */
439     FFSWAP(AVFrame, s->frame, s->prev_frame);
440     if (s->frame.data[0])
441         avctx->release_buffer(avctx, &s->frame);
442
443     *data_size = sizeof(AVFrame);
444     *(AVFrame*)data = s->prev_frame;
445
446     /* report that the buffer was completely consumed */
447     return buf_size;
448 }
449
450 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
451 {
452     VmdVideoContext *s = avctx->priv_data;
453
454     if (s->prev_frame.data[0])
455         avctx->release_buffer(avctx, &s->prev_frame);
456     av_free(s->unpack_buffer);
457
458     return 0;
459 }
460
461
462 /*
463  * Audio Decoder
464  */
465
466 #define BLOCK_TYPE_AUDIO    1
467 #define BLOCK_TYPE_INITIAL  2
468 #define BLOCK_TYPE_SILENCE  3
469
470 typedef struct VmdAudioContext {
471     AVFrame frame;
472     int out_bps;
473     int chunk_size;
474 } VmdAudioContext;
475
476 static const uint16_t vmdaudio_table[128] = {
477     0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
478     0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
479     0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
480     0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
481     0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
482     0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
483     0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
484     0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
485     0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
486     0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
487     0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
488     0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
489     0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
490 };
491
492 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
493 {
494     VmdAudioContext *s = avctx->priv_data;
495
496     if (avctx->channels < 1 || avctx->channels > 2) {
497         av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
498         return AVERROR(EINVAL);
499     }
500     if (avctx->block_align < 1 || avctx->block_align % avctx->channels) {
501         av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
502         return AVERROR(EINVAL);
503     }
504
505     avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
506                                                    AV_CH_LAYOUT_STEREO;
507
508     if (avctx->bits_per_coded_sample == 16)
509         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
510     else
511         avctx->sample_fmt = AV_SAMPLE_FMT_U8;
512     s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
513
514     s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
515
516     avcodec_get_frame_defaults(&s->frame);
517     avctx->coded_frame = &s->frame;
518
519     av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
520            "block align = %d, sample rate = %d\n",
521            avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
522            avctx->sample_rate);
523
524     return 0;
525 }
526
527 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
528                              int channels)
529 {
530     int ch;
531     const uint8_t *buf_end = buf + buf_size;
532     int predictor[2];
533     int st = channels - 1;
534
535     /* decode initial raw sample */
536     for (ch = 0; ch < channels; ch++) {
537         predictor[ch] = (int16_t)AV_RL16(buf);
538         buf += 2;
539         *out++ = predictor[ch];
540     }
541
542     /* decode DPCM samples */
543     ch = 0;
544     while (buf < buf_end) {
545         uint8_t b = *buf++;
546         if (b & 0x80)
547             predictor[ch] -= vmdaudio_table[b & 0x7F];
548         else
549             predictor[ch] += vmdaudio_table[b];
550         predictor[ch] = av_clip_int16(predictor[ch]);
551         *out++ = predictor[ch];
552         ch ^= st;
553     }
554 }
555
556 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
557                                  int *got_frame_ptr, AVPacket *avpkt)
558 {
559     const uint8_t *buf = avpkt->data;
560     const uint8_t *buf_end;
561     int buf_size = avpkt->size;
562     VmdAudioContext *s = avctx->priv_data;
563     int block_type, silent_chunks, audio_chunks;
564     int ret;
565     uint8_t *output_samples_u8;
566     int16_t *output_samples_s16;
567
568     if (buf_size < 16) {
569         av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
570         *got_frame_ptr = 0;
571         return buf_size;
572     }
573
574     block_type = buf[6];
575     if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
576         av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
577         return AVERROR(EINVAL);
578     }
579     buf      += 16;
580     buf_size -= 16;
581
582     /* get number of silent chunks */
583     silent_chunks = 0;
584     if (block_type == BLOCK_TYPE_INITIAL) {
585         uint32_t flags;
586         if (buf_size < 4) {
587             av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
588             return AVERROR(EINVAL);
589         }
590         flags         = AV_RB32(buf);
591         silent_chunks = av_popcount(flags);
592         buf      += 4;
593         buf_size -= 4;
594     } else if (block_type == BLOCK_TYPE_SILENCE) {
595         silent_chunks = 1;
596         buf_size = 0; // should already be zero but set it just to be sure
597     }
598
599     /* ensure output buffer is large enough */
600     audio_chunks = buf_size / s->chunk_size;
601
602     /* get output buffer */
603     s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
604     if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
605         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
606         return ret;
607     }
608     output_samples_u8  = s->frame.data[0];
609     output_samples_s16 = (int16_t *)s->frame.data[0];
610
611     /* decode silent chunks */
612     if (silent_chunks > 0) {
613         int silent_size = avctx->block_align * silent_chunks;
614         if (s->out_bps == 2) {
615             memset(output_samples_s16, 0x00, silent_size * 2);
616             output_samples_s16 += silent_size;
617         } else {
618             memset(output_samples_u8,  0x80, silent_size);
619             output_samples_u8 += silent_size;
620         }
621     }
622
623     /* decode audio chunks */
624     if (audio_chunks > 0) {
625         buf_end = buf + buf_size;
626         while ( buf_end - buf >= s->chunk_size) {
627             if (s->out_bps == 2) {
628                 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
629                                  avctx->channels);
630                 output_samples_s16 += avctx->block_align;
631             } else {
632                 memcpy(output_samples_u8, buf, s->chunk_size);
633                 output_samples_u8  += avctx->block_align;
634             }
635             buf += s->chunk_size;
636         }
637     }
638
639     *got_frame_ptr   = 1;
640     *(AVFrame *)data = s->frame;
641
642     return avpkt->size;
643 }
644
645
646 /*
647  * Public Data Structures
648  */
649
650 AVCodec ff_vmdvideo_decoder = {
651     .name           = "vmdvideo",
652     .type           = AVMEDIA_TYPE_VIDEO,
653     .id             = AV_CODEC_ID_VMDVIDEO,
654     .priv_data_size = sizeof(VmdVideoContext),
655     .init           = vmdvideo_decode_init,
656     .close          = vmdvideo_decode_end,
657     .decode         = vmdvideo_decode_frame,
658     .capabilities   = CODEC_CAP_DR1,
659     .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
660 };
661
662 AVCodec ff_vmdaudio_decoder = {
663     .name           = "vmdaudio",
664     .type           = AVMEDIA_TYPE_AUDIO,
665     .id             = AV_CODEC_ID_VMDAUDIO,
666     .priv_data_size = sizeof(VmdAudioContext),
667     .init           = vmdaudio_decode_init,
668     .decode         = vmdaudio_decode_frame,
669     .capabilities   = CODEC_CAP_DR1,
670     .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
671 };