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