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/intreadwrite.h"
49 #define VMD_HEADER_SIZE 0x330
50 #define PALETTE_COUNT 256
56 typedef struct VmdVideoContext {
58 AVCodecContext *avctx;
62 const unsigned char *buf;
65 unsigned char palette[PALETTE_COUNT * 4];
66 unsigned char *unpack_buffer;
67 int unpack_buffer_size;
72 #define QUEUE_SIZE 0x1000
73 #define QUEUE_MASK 0x0FFF
75 static void lz_unpack(const unsigned char *src, int src_len,
76 unsigned char *dest, int dest_len)
78 const unsigned char *s;
82 unsigned char queue[QUEUE_SIZE];
84 unsigned int dataleft;
85 unsigned int chainofs;
86 unsigned int chainlen;
95 dataleft = AV_RL32(s);
97 memset(queue, 0x20, QUEUE_SIZE);
100 if (AV_RL32(s) == 0x56781234) {
106 speclen = 100; /* no speclen */
109 while (dataleft > 0 && s_len > 0) {
111 if ((tag == 0xFF) && (dataleft > 8)) {
112 if (d + 8 > d_end || s_len < 8)
114 for (i = 0; i < 8; i++) {
115 queue[qpos++] = *d++ = *s++;
121 for (i = 0; i < 8; i++) {
125 if (d + 1 > d_end || s_len < 1)
127 queue[qpos++] = *d++ = *s++;
135 chainofs |= ((*s & 0xF0) << 4);
136 chainlen = (*s++ & 0x0F) + 3;
138 if (chainlen == speclen) {
141 chainlen = *s++ + 0xF + 3;
144 if (d + chainlen > d_end)
146 for (j = 0; j < chainlen; j++) {
147 *d = queue[chainofs++ & QUEUE_MASK];
148 queue[qpos++] = *d++;
151 dataleft -= chainlen;
159 static int rle_unpack(const unsigned char *src, unsigned char *dest,
160 int src_count, int src_size, int dest_len)
162 const unsigned char *ps;
165 unsigned char *dest_end = dest + dest_len;
185 if (pd + l > dest_end || src_size < l)
192 if (pd + i > dest_end || src_size < 2)
194 for (i = 0; i < l; i++) {
202 } while (i < src_count);
207 static void vmd_decode(VmdVideoContext *s)
210 unsigned int *palette32;
211 unsigned char r, g, b;
213 /* point to the start of the encoded data */
214 const unsigned char *p = s->buf + 16;
216 const unsigned char *pb;
217 unsigned int pb_size;
219 unsigned char *dp; /* pointer to current frame */
220 unsigned char *pp; /* pointer to previous frame */
224 int frame_x, frame_y;
225 int frame_width, frame_height;
227 frame_x = AV_RL16(&s->buf[6]);
228 frame_y = AV_RL16(&s->buf[8]);
229 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
230 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
231 if (frame_x < 0 || frame_width < 0 ||
232 frame_x >= s->avctx->width ||
233 frame_width > s->avctx->width ||
234 frame_x + frame_width > s->avctx->width)
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)
242 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
243 (frame_x || frame_y)) {
251 /* if only a certain region will be updated, copy the entire previous
252 * frame before the decode */
253 if (s->prev_frame.data[0] &&
254 (frame_x || frame_y || (frame_width != s->avctx->width) ||
255 (frame_height != s->avctx->height))) {
257 memcpy(s->frame.data[0], s->prev_frame.data[0],
258 s->avctx->height * s->frame.linesize[0]);
261 /* check if there is a new palette */
262 if (s->buf[15] & 0x02) {
264 palette32 = (unsigned int *)s->palette;
265 for (i = 0; i < PALETTE_COUNT; i++) {
269 palette32[i] = (r << 16) | (g << 8) | (b);
271 s->size -= (256 * 3 + 2);
274 /* originally UnpackFrame in VAG's code */
276 pb_size = s->buf + s->size - pb;
279 meth = *pb++; pb_size--;
281 lz_unpack(pb, pb_size,
282 s->unpack_buffer, s->unpack_buffer_size);
284 pb = s->unpack_buffer;
285 pb_size = s->unpack_buffer_size;
288 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
289 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
292 for (i = 0; i < frame_height; i++) {
300 len = (len & 0x7F) + 1;
301 if (ofs + len > frame_width || pb_size < len)
303 memcpy(&dp[ofs], pb, len);
308 /* interframe pixel copy */
309 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
311 memcpy(&dp[ofs], &pp[ofs], len + 1);
314 } while (ofs < frame_width);
315 if (ofs > frame_width) {
316 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
320 dp += s->frame.linesize[0];
321 pp += s->prev_frame.linesize[0];
326 for (i = 0; i < frame_height; i++) {
327 if (pb_size < frame_width)
329 memcpy(dp, pb, frame_width);
331 pb_size -= frame_width;
332 dp += s->frame.linesize[0];
333 pp += s->prev_frame.linesize[0];
338 for (i = 0; i < frame_height; i++) {
346 len = (len & 0x7F) + 1;
350 len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs);
354 memcpy(&dp[ofs], pb, len);
360 /* interframe pixel copy */
361 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
363 memcpy(&dp[ofs], &pp[ofs], len + 1);
366 } while (ofs < frame_width);
367 if (ofs > frame_width) {
368 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
371 dp += s->frame.linesize[0];
372 pp += s->prev_frame.linesize[0];
379 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
381 VmdVideoContext *s = avctx->priv_data;
383 unsigned int *palette32;
384 int palette_index = 0;
385 unsigned char r, g, b;
386 unsigned char *vmd_header;
387 unsigned char *raw_palette;
390 avctx->pix_fmt = PIX_FMT_PAL8;
392 /* make sure the VMD header made it */
393 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
394 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
398 vmd_header = (unsigned char *)avctx->extradata;
400 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
401 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
402 if (!s->unpack_buffer)
405 /* load up the initial palette */
406 raw_palette = &vmd_header[28];
407 palette32 = (unsigned int *)s->palette;
408 for (i = 0; i < PALETTE_COUNT; i++) {
409 r = raw_palette[palette_index++] * 4;
410 g = raw_palette[palette_index++] * 4;
411 b = raw_palette[palette_index++] * 4;
412 palette32[i] = (r << 16) | (g << 8) | (b);
418 static int vmdvideo_decode_frame(AVCodecContext *avctx,
419 void *data, int *data_size,
422 const uint8_t *buf = avpkt->data;
423 int buf_size = avpkt->size;
424 VmdVideoContext *s = avctx->priv_data;
432 s->frame.reference = 1;
433 if (avctx->get_buffer(avctx, &s->frame)) {
434 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
440 /* make the palette available on the way out */
441 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
444 FFSWAP(AVFrame, s->frame, s->prev_frame);
445 if (s->frame.data[0])
446 avctx->release_buffer(avctx, &s->frame);
448 *data_size = sizeof(AVFrame);
449 *(AVFrame*)data = s->prev_frame;
451 /* report that the buffer was completely consumed */
455 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
457 VmdVideoContext *s = avctx->priv_data;
459 if (s->prev_frame.data[0])
460 avctx->release_buffer(avctx, &s->prev_frame);
461 av_free(s->unpack_buffer);
471 #define BLOCK_TYPE_AUDIO 1
472 #define BLOCK_TYPE_INITIAL 2
473 #define BLOCK_TYPE_SILENCE 3
475 typedef struct VmdAudioContext {
481 static const uint16_t vmdaudio_table[128] = {
482 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
483 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
484 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
485 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
486 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
487 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
488 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
489 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
490 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
491 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
492 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
493 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
494 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
497 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
499 VmdAudioContext *s = avctx->priv_data;
501 if (avctx->channels < 1 || avctx->channels > 2) {
502 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
503 return AVERROR(EINVAL);
505 if (avctx->block_align < 1) {
506 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
507 return AVERROR(EINVAL);
510 if (avctx->bits_per_coded_sample == 16)
511 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
513 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
514 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
516 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
518 avcodec_get_frame_defaults(&s->frame);
519 avctx->coded_frame = &s->frame;
521 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
522 "block align = %d, sample rate = %d\n",
523 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
529 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
533 const uint8_t *buf_end = buf + buf_size;
535 int st = channels - 1;
537 /* decode initial raw sample */
538 for (ch = 0; ch < channels; ch++) {
539 predictor[ch] = (int16_t)AV_RL16(buf);
541 *out++ = predictor[ch];
544 /* decode DPCM samples */
546 while (buf < buf_end) {
549 predictor[ch] -= vmdaudio_table[b & 0x7F];
551 predictor[ch] += vmdaudio_table[b];
552 predictor[ch] = av_clip_int16(predictor[ch]);
553 *out++ = predictor[ch];
558 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
559 int *got_frame_ptr, AVPacket *avpkt)
561 const uint8_t *buf = avpkt->data;
562 const uint8_t *buf_end;
563 int buf_size = avpkt->size;
564 VmdAudioContext *s = avctx->priv_data;
565 int block_type, silent_chunks, audio_chunks;
567 uint8_t *output_samples_u8;
568 int16_t *output_samples_s16;
571 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
577 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
578 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
579 return AVERROR(EINVAL);
584 /* get number of silent chunks */
586 if (block_type == BLOCK_TYPE_INITIAL) {
589 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
590 return AVERROR(EINVAL);
592 flags = AV_RB32(buf);
593 silent_chunks = av_popcount(flags);
596 } else if (block_type == BLOCK_TYPE_SILENCE) {
598 buf_size = 0; // should already be zero but set it just to be sure
601 /* ensure output buffer is large enough */
602 audio_chunks = buf_size / s->chunk_size;
604 /* get output buffer */
605 s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
606 if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
607 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
610 output_samples_u8 = s->frame.data[0];
611 output_samples_s16 = (int16_t *)s->frame.data[0];
613 /* decode silent chunks */
614 if (silent_chunks > 0) {
615 int silent_size = avctx->block_align * silent_chunks;
616 if (s->out_bps == 2) {
617 memset(output_samples_s16, 0x00, silent_size * 2);
618 output_samples_s16 += silent_size;
620 memset(output_samples_u8, 0x80, silent_size);
621 output_samples_u8 += silent_size;
625 /* decode audio chunks */
626 if (audio_chunks > 0) {
627 buf_end = buf + buf_size;
628 while (buf < buf_end) {
629 if (s->out_bps == 2) {
630 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
632 output_samples_s16 += avctx->block_align;
634 memcpy(output_samples_u8, buf, s->chunk_size);
635 output_samples_u8 += avctx->block_align;
637 buf += s->chunk_size;
642 *(AVFrame *)data = s->frame;
649 * Public Data Structures
652 AVCodec ff_vmdvideo_decoder = {
654 .type = AVMEDIA_TYPE_VIDEO,
655 .id = AV_CODEC_ID_VMDVIDEO,
656 .priv_data_size = sizeof(VmdVideoContext),
657 .init = vmdvideo_decode_init,
658 .close = vmdvideo_decode_end,
659 .decode = vmdvideo_decode_frame,
660 .capabilities = CODEC_CAP_DR1,
661 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
664 AVCodec ff_vmdaudio_decoder = {
666 .type = AVMEDIA_TYPE_AUDIO,
667 .id = AV_CODEC_ID_VMDAUDIO,
668 .priv_data_size = sizeof(VmdAudioContext),
669 .init = vmdaudio_decode_init,
670 .decode = vmdaudio_decode_frame,
671 .capabilities = CODEC_CAP_DR1,
672 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),