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