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/common.h"
47 #include "libavutil/intreadwrite.h"
50 #define VMD_HEADER_SIZE 0x330
51 #define PALETTE_COUNT 256
57 typedef struct VmdVideoContext {
59 AVCodecContext *avctx;
63 const unsigned char *buf;
66 unsigned char palette[PALETTE_COUNT * 4];
67 unsigned char *unpack_buffer;
68 int unpack_buffer_size;
73 #define QUEUE_SIZE 0x1000
74 #define QUEUE_MASK 0x0FFF
76 static void lz_unpack(const unsigned char *src, int src_len,
77 unsigned char *dest, int dest_len)
79 const unsigned char *s;
83 unsigned char queue[QUEUE_SIZE];
85 unsigned int dataleft;
86 unsigned int chainofs;
87 unsigned int chainlen;
96 dataleft = AV_RL32(s);
98 memset(queue, 0x20, QUEUE_SIZE);
101 if (AV_RL32(s) == 0x56781234) {
107 speclen = 100; /* no speclen */
110 while (dataleft > 0 && s_len > 0) {
112 if ((tag == 0xFF) && (dataleft > 8)) {
113 if (d + 8 > d_end || s_len < 8)
115 for (i = 0; i < 8; i++) {
116 queue[qpos++] = *d++ = *s++;
122 for (i = 0; i < 8; i++) {
126 if (d + 1 > d_end || s_len < 1)
128 queue[qpos++] = *d++ = *s++;
136 chainofs |= ((*s & 0xF0) << 4);
137 chainlen = (*s++ & 0x0F) + 3;
139 if (chainlen == speclen) {
142 chainlen = *s++ + 0xF + 3;
145 if (d + chainlen > d_end)
147 for (j = 0; j < chainlen; j++) {
148 *d = queue[chainofs++ & QUEUE_MASK];
149 queue[qpos++] = *d++;
152 dataleft -= chainlen;
160 static int rle_unpack(const unsigned char *src, unsigned char *dest,
161 int src_count, int src_size, int dest_len)
163 const unsigned char *ps;
166 unsigned char *dest_end = dest + dest_len;
186 if (pd + l > dest_end || src_size < l)
193 if (pd + i > dest_end || src_size < 2)
195 for (i = 0; i < l; i++) {
203 } while (i < src_count);
208 static void vmd_decode(VmdVideoContext *s)
211 unsigned int *palette32;
212 unsigned char r, g, b;
214 /* point to the start of the encoded data */
215 const unsigned char *p = s->buf + 16;
217 const unsigned char *pb;
218 unsigned int pb_size;
220 unsigned char *dp; /* pointer to current frame */
221 unsigned char *pp; /* pointer to previous frame */
225 int frame_x, frame_y;
226 int frame_width, frame_height;
228 frame_x = AV_RL16(&s->buf[6]);
229 frame_y = AV_RL16(&s->buf[8]);
230 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
231 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
232 if (frame_x < 0 || frame_width < 0 ||
233 frame_x >= s->avctx->width ||
234 frame_width > s->avctx->width ||
235 frame_x + frame_width > s->avctx->width)
237 if (frame_y < 0 || frame_height < 0 ||
238 frame_y >= s->avctx->height ||
239 frame_height > s->avctx->height ||
240 frame_y + frame_height > s->avctx->height)
243 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
244 (frame_x || frame_y)) {
252 /* if only a certain region will be updated, copy the entire previous
253 * frame before the decode */
254 if (s->prev_frame.data[0] &&
255 (frame_x || frame_y || (frame_width != s->avctx->width) ||
256 (frame_height != s->avctx->height))) {
258 memcpy(s->frame.data[0], s->prev_frame.data[0],
259 s->avctx->height * s->frame.linesize[0]);
262 /* check if there is a new palette */
263 if (s->buf[15] & 0x02) {
265 palette32 = (unsigned int *)s->palette;
266 for (i = 0; i < PALETTE_COUNT; i++) {
270 palette32[i] = (r << 16) | (g << 8) | (b);
272 s->size -= (256 * 3 + 2);
275 /* originally UnpackFrame in VAG's code */
277 pb_size = s->buf + s->size - pb;
280 meth = *pb++; pb_size--;
282 lz_unpack(pb, pb_size,
283 s->unpack_buffer, s->unpack_buffer_size);
285 pb = s->unpack_buffer;
286 pb_size = s->unpack_buffer_size;
289 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
290 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
293 for (i = 0; i < frame_height; i++) {
301 len = (len & 0x7F) + 1;
302 if (ofs + len > frame_width || pb_size < len)
304 memcpy(&dp[ofs], pb, len);
309 /* interframe pixel copy */
310 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
312 memcpy(&dp[ofs], &pp[ofs], len + 1);
315 } while (ofs < frame_width);
316 if (ofs > frame_width) {
317 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
321 dp += s->frame.linesize[0];
322 pp += s->prev_frame.linesize[0];
327 for (i = 0; i < frame_height; i++) {
328 if (pb_size < frame_width)
330 memcpy(dp, pb, frame_width);
332 pb_size -= frame_width;
333 dp += s->frame.linesize[0];
334 pp += s->prev_frame.linesize[0];
339 for (i = 0; i < frame_height; i++) {
347 len = (len & 0x7F) + 1;
351 len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs);
355 memcpy(&dp[ofs], pb, len);
361 /* interframe pixel copy */
362 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
364 memcpy(&dp[ofs], &pp[ofs], len + 1);
367 } while (ofs < frame_width);
368 if (ofs > frame_width) {
369 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
372 dp += s->frame.linesize[0];
373 pp += s->prev_frame.linesize[0];
380 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
382 VmdVideoContext *s = avctx->priv_data;
384 unsigned int *palette32;
385 int palette_index = 0;
386 unsigned char r, g, b;
387 unsigned char *vmd_header;
388 unsigned char *raw_palette;
391 avctx->pix_fmt = AV_PIX_FMT_PAL8;
393 /* make sure the VMD header made it */
394 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
395 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
399 vmd_header = (unsigned char *)avctx->extradata;
401 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
402 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
403 if (!s->unpack_buffer)
406 /* load up the initial palette */
407 raw_palette = &vmd_header[28];
408 palette32 = (unsigned int *)s->palette;
409 for (i = 0; i < PALETTE_COUNT; i++) {
410 r = raw_palette[palette_index++] * 4;
411 g = raw_palette[palette_index++] * 4;
412 b = raw_palette[palette_index++] * 4;
413 palette32[i] = (r << 16) | (g << 8) | (b);
419 static int vmdvideo_decode_frame(AVCodecContext *avctx,
420 void *data, int *data_size,
423 const uint8_t *buf = avpkt->data;
424 int buf_size = avpkt->size;
425 VmdVideoContext *s = avctx->priv_data;
433 s->frame.reference = 1;
434 if (avctx->get_buffer(avctx, &s->frame)) {
435 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
441 /* make the palette available on the way out */
442 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
445 FFSWAP(AVFrame, s->frame, s->prev_frame);
446 if (s->frame.data[0])
447 avctx->release_buffer(avctx, &s->frame);
449 *data_size = sizeof(AVFrame);
450 *(AVFrame*)data = s->prev_frame;
452 /* report that the buffer was completely consumed */
456 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
458 VmdVideoContext *s = avctx->priv_data;
460 if (s->prev_frame.data[0])
461 avctx->release_buffer(avctx, &s->prev_frame);
462 av_free(s->unpack_buffer);
472 #define BLOCK_TYPE_AUDIO 1
473 #define BLOCK_TYPE_INITIAL 2
474 #define BLOCK_TYPE_SILENCE 3
476 typedef struct VmdAudioContext {
482 static const uint16_t vmdaudio_table[128] = {
483 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
484 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
485 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
486 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
487 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
488 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
489 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
490 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
491 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
492 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
493 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
494 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
495 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
498 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
500 VmdAudioContext *s = avctx->priv_data;
502 if (avctx->channels < 1 || avctx->channels > 2) {
503 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
504 return AVERROR(EINVAL);
506 if (avctx->block_align < 1) {
507 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
508 return AVERROR(EINVAL);
511 if (avctx->bits_per_coded_sample == 16)
512 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
514 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
515 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
517 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
519 avcodec_get_frame_defaults(&s->frame);
520 avctx->coded_frame = &s->frame;
522 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
523 "block align = %d, sample rate = %d\n",
524 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
530 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
534 const uint8_t *buf_end = buf + buf_size;
536 int st = channels - 1;
538 /* decode initial raw sample */
539 for (ch = 0; ch < channels; ch++) {
540 predictor[ch] = (int16_t)AV_RL16(buf);
542 *out++ = predictor[ch];
545 /* decode DPCM samples */
547 while (buf < buf_end) {
550 predictor[ch] -= vmdaudio_table[b & 0x7F];
552 predictor[ch] += vmdaudio_table[b];
553 predictor[ch] = av_clip_int16(predictor[ch]);
554 *out++ = predictor[ch];
559 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
560 int *got_frame_ptr, AVPacket *avpkt)
562 const uint8_t *buf = avpkt->data;
563 const uint8_t *buf_end;
564 int buf_size = avpkt->size;
565 VmdAudioContext *s = avctx->priv_data;
566 int block_type, silent_chunks, audio_chunks;
568 uint8_t *output_samples_u8;
569 int16_t *output_samples_s16;
572 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
578 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
579 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
580 return AVERROR(EINVAL);
585 /* get number of silent chunks */
587 if (block_type == BLOCK_TYPE_INITIAL) {
590 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
591 return AVERROR(EINVAL);
593 flags = AV_RB32(buf);
594 silent_chunks = av_popcount(flags);
597 } else if (block_type == BLOCK_TYPE_SILENCE) {
599 buf_size = 0; // should already be zero but set it just to be sure
602 /* ensure output buffer is large enough */
603 audio_chunks = buf_size / s->chunk_size;
605 /* get output buffer */
606 s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
607 if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
608 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
611 output_samples_u8 = s->frame.data[0];
612 output_samples_s16 = (int16_t *)s->frame.data[0];
614 /* decode silent chunks */
615 if (silent_chunks > 0) {
616 int silent_size = avctx->block_align * silent_chunks;
617 if (s->out_bps == 2) {
618 memset(output_samples_s16, 0x00, silent_size * 2);
619 output_samples_s16 += silent_size;
621 memset(output_samples_u8, 0x80, silent_size);
622 output_samples_u8 += silent_size;
626 /* decode audio chunks */
627 if (audio_chunks > 0) {
628 buf_end = buf + buf_size;
629 while (buf < buf_end) {
630 if (s->out_bps == 2) {
631 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
633 output_samples_s16 += avctx->block_align;
635 memcpy(output_samples_u8, buf, s->chunk_size);
636 output_samples_u8 += avctx->block_align;
638 buf += s->chunk_size;
643 *(AVFrame *)data = s->frame;
650 * Public Data Structures
653 AVCodec ff_vmdvideo_decoder = {
655 .type = AVMEDIA_TYPE_VIDEO,
656 .id = AV_CODEC_ID_VMDVIDEO,
657 .priv_data_size = sizeof(VmdVideoContext),
658 .init = vmdvideo_decode_init,
659 .close = vmdvideo_decode_end,
660 .decode = vmdvideo_decode_frame,
661 .capabilities = CODEC_CAP_DR1,
662 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
665 AVCodec ff_vmdaudio_decoder = {
667 .type = AVMEDIA_TYPE_AUDIO,
668 .id = AV_CODEC_ID_VMDAUDIO,
669 .priv_data_size = sizeof(VmdAudioContext),
670 .init = vmdaudio_decode_init,
671 .decode = vmdaudio_decode_frame,
672 .capabilities = CODEC_CAP_DR1,
673 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),