Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / third_party / 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 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
196 static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
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) {
231         av_log(s->avctx, AV_LOG_ERROR,
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) {
240         av_log(s->avctx, AV_LOG_ERROR,
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;
261         if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) {
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) {
285             av_log(s->avctx, AV_LOG_ERROR,
286                    "Trying to unpack LZ-compressed frame with no LZ buffer\n");
287             return AVERROR_INVALIDDATA;
288         }
289         size = lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
290                          s->unpack_buffer, s->unpack_buffer_size);
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 ||
308                         bytestream2_get_bytes_left(&gb) < len)
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) {
321                 av_log(s->avctx, AV_LOG_ERROR,
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) {
367                 av_log(s->avctx, AV_LOG_ERROR,
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
380 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
381 {
382     VmdVideoContext *s = avctx->priv_data;
383
384     av_frame_free(&s->prev_frame);
385     av_freep(&s->unpack_buffer);
386     s->unpack_buffer_size = 0;
387
388     return 0;
389 }
390
391 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
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",
407             VMD_HEADER_SIZE);
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) {
414         s->unpack_buffer = av_malloc(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
439 static int vmdvideo_decode_frame(AVCodecContext *avctx,
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 */
465     av_frame_unref(s->prev_frame);
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;
485     int chunk_size;
486 } VmdAudioContext;
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
504 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
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 :
518                                                    AV_CH_LAYOUT_STEREO;
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;
524     s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
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
664 AVCodec ff_vmdvideo_decoder = {
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),
670     .init           = vmdvideo_decode_init,
671     .close          = vmdvideo_decode_end,
672     .decode         = vmdvideo_decode_frame,
673     .capabilities   = CODEC_CAP_DR1,
674 };
675
676 AVCodec ff_vmdaudio_decoder = {
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),
682     .init           = vmdaudio_decode_init,
683     .decode         = vmdaudio_decode_frame,
684     .capabilities   = CODEC_CAP_DR1,
685 };