2 * Sierra VMD Audio & Video Decoders
3 * Copyright (C) 2004 the ffmpeg project
5 * This file is part of Libav.
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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/
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.
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.
46 #include "libavutil/audioconvert.h"
47 #include "libavutil/common.h"
48 #include "libavutil/intreadwrite.h"
51 #define VMD_HEADER_SIZE 0x330
52 #define PALETTE_COUNT 256
58 typedef struct VmdVideoContext {
60 AVCodecContext *avctx;
64 const unsigned char *buf;
67 unsigned char palette[PALETTE_COUNT * 4];
68 unsigned char *unpack_buffer;
69 int unpack_buffer_size;
74 #define QUEUE_SIZE 0x1000
75 #define QUEUE_MASK 0x0FFF
77 static void lz_unpack(const unsigned char *src, int src_len,
78 unsigned char *dest, int dest_len)
80 const unsigned char *s;
84 unsigned char queue[QUEUE_SIZE];
86 unsigned int dataleft;
87 unsigned int chainofs;
88 unsigned int chainlen;
97 dataleft = AV_RL32(s);
99 memset(queue, 0x20, QUEUE_SIZE);
102 if (AV_RL32(s) == 0x56781234) {
108 speclen = 100; /* no speclen */
111 while (dataleft > 0 && s_len > 0) {
113 if ((tag == 0xFF) && (dataleft > 8)) {
114 if (d + 8 > d_end || s_len < 8)
116 for (i = 0; i < 8; i++) {
117 queue[qpos++] = *d++ = *s++;
123 for (i = 0; i < 8; i++) {
127 if (d + 1 > d_end || s_len < 1)
129 queue[qpos++] = *d++ = *s++;
137 chainofs |= ((*s & 0xF0) << 4);
138 chainlen = (*s++ & 0x0F) + 3;
140 if (chainlen == speclen) {
143 chainlen = *s++ + 0xF + 3;
146 if (d + chainlen > d_end)
148 for (j = 0; j < chainlen; j++) {
149 *d = queue[chainofs++ & QUEUE_MASK];
150 queue[qpos++] = *d++;
153 dataleft -= chainlen;
161 static int rle_unpack(const unsigned char *src, unsigned char *dest,
162 int src_count, int src_size, int dest_len)
164 const unsigned char *ps;
167 unsigned char *dest_end = dest + dest_len;
187 if (pd + l > dest_end || src_size < l)
194 if (pd + i > dest_end || src_size < 2)
196 for (i = 0; i < l; i++) {
204 } while (i < src_count);
209 static void vmd_decode(VmdVideoContext *s)
212 unsigned int *palette32;
213 unsigned char r, g, b;
215 /* point to the start of the encoded data */
216 const unsigned char *p = s->buf + 16;
218 const unsigned char *pb;
219 unsigned int pb_size;
221 unsigned char *dp; /* pointer to current frame */
222 unsigned char *pp; /* pointer to previous frame */
226 int frame_x, frame_y;
227 int frame_width, frame_height;
229 frame_x = AV_RL16(&s->buf[6]);
230 frame_y = AV_RL16(&s->buf[8]);
231 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
232 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
233 if (frame_x < 0 || frame_width < 0 ||
234 frame_x >= s->avctx->width ||
235 frame_width > s->avctx->width ||
236 frame_x + frame_width > s->avctx->width)
238 if (frame_y < 0 || frame_height < 0 ||
239 frame_y >= s->avctx->height ||
240 frame_height > s->avctx->height ||
241 frame_y + frame_height > s->avctx->height)
244 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
245 (frame_x || frame_y)) {
253 /* if only a certain region will be updated, copy the entire previous
254 * frame before the decode */
255 if (s->prev_frame.data[0] &&
256 (frame_x || frame_y || (frame_width != s->avctx->width) ||
257 (frame_height != s->avctx->height))) {
259 memcpy(s->frame.data[0], s->prev_frame.data[0],
260 s->avctx->height * s->frame.linesize[0]);
263 /* check if there is a new palette */
264 if (s->buf[15] & 0x02) {
266 palette32 = (unsigned int *)s->palette;
267 for (i = 0; i < PALETTE_COUNT; i++) {
271 palette32[i] = (r << 16) | (g << 8) | (b);
273 s->size -= (256 * 3 + 2);
276 /* originally UnpackFrame in VAG's code */
278 pb_size = s->buf + s->size - pb;
281 meth = *pb++; pb_size--;
283 lz_unpack(pb, pb_size,
284 s->unpack_buffer, s->unpack_buffer_size);
286 pb = s->unpack_buffer;
287 pb_size = s->unpack_buffer_size;
290 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
291 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
294 for (i = 0; i < frame_height; i++) {
302 len = (len & 0x7F) + 1;
303 if (ofs + len > frame_width || pb_size < len)
305 memcpy(&dp[ofs], pb, len);
310 /* interframe pixel copy */
311 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
313 memcpy(&dp[ofs], &pp[ofs], len + 1);
316 } while (ofs < frame_width);
317 if (ofs > frame_width) {
318 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
322 dp += s->frame.linesize[0];
323 pp += s->prev_frame.linesize[0];
328 for (i = 0; i < frame_height; i++) {
329 if (pb_size < frame_width)
331 memcpy(dp, pb, frame_width);
333 pb_size -= frame_width;
334 dp += s->frame.linesize[0];
335 pp += s->prev_frame.linesize[0];
340 for (i = 0; i < frame_height; i++) {
348 len = (len & 0x7F) + 1;
352 len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs);
356 memcpy(&dp[ofs], pb, len);
362 /* interframe pixel copy */
363 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
365 memcpy(&dp[ofs], &pp[ofs], len + 1);
368 } while (ofs < frame_width);
369 if (ofs > frame_width) {
370 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
373 dp += s->frame.linesize[0];
374 pp += s->prev_frame.linesize[0];
381 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
383 VmdVideoContext *s = avctx->priv_data;
385 unsigned int *palette32;
386 int palette_index = 0;
387 unsigned char r, g, b;
388 unsigned char *vmd_header;
389 unsigned char *raw_palette;
392 avctx->pix_fmt = AV_PIX_FMT_PAL8;
394 /* make sure the VMD header made it */
395 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
396 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
400 vmd_header = (unsigned char *)avctx->extradata;
402 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
403 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
404 if (!s->unpack_buffer)
407 /* load up the initial palette */
408 raw_palette = &vmd_header[28];
409 palette32 = (unsigned int *)s->palette;
410 for (i = 0; i < PALETTE_COUNT; i++) {
411 r = raw_palette[palette_index++] * 4;
412 g = raw_palette[palette_index++] * 4;
413 b = raw_palette[palette_index++] * 4;
414 palette32[i] = (r << 16) | (g << 8) | (b);
420 static int vmdvideo_decode_frame(AVCodecContext *avctx,
421 void *data, int *data_size,
424 const uint8_t *buf = avpkt->data;
425 int buf_size = avpkt->size;
426 VmdVideoContext *s = avctx->priv_data;
434 s->frame.reference = 1;
435 if (avctx->get_buffer(avctx, &s->frame)) {
436 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
442 /* make the palette available on the way out */
443 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
446 FFSWAP(AVFrame, s->frame, s->prev_frame);
447 if (s->frame.data[0])
448 avctx->release_buffer(avctx, &s->frame);
450 *data_size = sizeof(AVFrame);
451 *(AVFrame*)data = s->prev_frame;
453 /* report that the buffer was completely consumed */
457 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
459 VmdVideoContext *s = avctx->priv_data;
461 if (s->prev_frame.data[0])
462 avctx->release_buffer(avctx, &s->prev_frame);
463 av_free(s->unpack_buffer);
473 #define BLOCK_TYPE_AUDIO 1
474 #define BLOCK_TYPE_INITIAL 2
475 #define BLOCK_TYPE_SILENCE 3
477 typedef struct VmdAudioContext {
483 static const uint16_t vmdaudio_table[128] = {
484 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
485 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
486 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
487 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
488 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
489 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
490 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
491 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
492 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
493 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
494 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
495 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
496 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
499 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
501 VmdAudioContext *s = avctx->priv_data;
503 if (avctx->channels < 1 || avctx->channels > 2) {
504 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
505 return AVERROR(EINVAL);
507 if (avctx->block_align < 1) {
508 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
509 return AVERROR(EINVAL);
512 avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
515 if (avctx->bits_per_coded_sample == 16)
516 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
518 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
519 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
521 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
523 avcodec_get_frame_defaults(&s->frame);
524 avctx->coded_frame = &s->frame;
526 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
527 "block align = %d, sample rate = %d\n",
528 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
534 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
538 const uint8_t *buf_end = buf + buf_size;
540 int st = channels - 1;
542 /* decode initial raw sample */
543 for (ch = 0; ch < channels; ch++) {
544 predictor[ch] = (int16_t)AV_RL16(buf);
546 *out++ = predictor[ch];
549 /* decode DPCM samples */
551 while (buf < buf_end) {
554 predictor[ch] -= vmdaudio_table[b & 0x7F];
556 predictor[ch] += vmdaudio_table[b];
557 predictor[ch] = av_clip_int16(predictor[ch]);
558 *out++ = predictor[ch];
563 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
564 int *got_frame_ptr, AVPacket *avpkt)
566 const uint8_t *buf = avpkt->data;
567 const uint8_t *buf_end;
568 int buf_size = avpkt->size;
569 VmdAudioContext *s = avctx->priv_data;
570 int block_type, silent_chunks, audio_chunks;
572 uint8_t *output_samples_u8;
573 int16_t *output_samples_s16;
576 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
582 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
583 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
584 return AVERROR(EINVAL);
589 /* get number of silent chunks */
591 if (block_type == BLOCK_TYPE_INITIAL) {
594 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
595 return AVERROR(EINVAL);
597 flags = AV_RB32(buf);
598 silent_chunks = av_popcount(flags);
601 } else if (block_type == BLOCK_TYPE_SILENCE) {
603 buf_size = 0; // should already be zero but set it just to be sure
606 /* ensure output buffer is large enough */
607 audio_chunks = buf_size / s->chunk_size;
609 /* get output buffer */
610 s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
611 if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
612 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
615 output_samples_u8 = s->frame.data[0];
616 output_samples_s16 = (int16_t *)s->frame.data[0];
618 /* decode silent chunks */
619 if (silent_chunks > 0) {
620 int silent_size = avctx->block_align * silent_chunks;
621 if (s->out_bps == 2) {
622 memset(output_samples_s16, 0x00, silent_size * 2);
623 output_samples_s16 += silent_size;
625 memset(output_samples_u8, 0x80, silent_size);
626 output_samples_u8 += silent_size;
630 /* decode audio chunks */
631 if (audio_chunks > 0) {
632 buf_end = buf + buf_size;
633 while (buf < buf_end) {
634 if (s->out_bps == 2) {
635 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
637 output_samples_s16 += avctx->block_align;
639 memcpy(output_samples_u8, buf, s->chunk_size);
640 output_samples_u8 += avctx->block_align;
642 buf += s->chunk_size;
647 *(AVFrame *)data = s->frame;
654 * Public Data Structures
657 AVCodec ff_vmdvideo_decoder = {
659 .type = AVMEDIA_TYPE_VIDEO,
660 .id = AV_CODEC_ID_VMDVIDEO,
661 .priv_data_size = sizeof(VmdVideoContext),
662 .init = vmdvideo_decode_init,
663 .close = vmdvideo_decode_end,
664 .decode = vmdvideo_decode_frame,
665 .capabilities = CODEC_CAP_DR1,
666 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
669 AVCodec ff_vmdaudio_decoder = {
671 .type = AVMEDIA_TYPE_AUDIO,
672 .id = AV_CODEC_ID_VMDAUDIO,
673 .priv_data_size = sizeof(VmdAudioContext),
674 .init = vmdaudio_decode_init,
675 .decode = vmdaudio_decode_frame,
676 .capabilities = CODEC_CAP_DR1,
677 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),