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/channel_layout.h"
47 #include "libavutil/common.h"
48 #include "libavutil/intreadwrite.h"
51 #include "bytestream.h"
53 #define VMD_HEADER_SIZE 0x330
54 #define PALETTE_COUNT 256
60 typedef struct VmdVideoContext {
62 AVCodecContext *avctx;
65 const unsigned char *buf;
68 unsigned char palette[PALETTE_COUNT * 4];
69 unsigned char *unpack_buffer;
70 int unpack_buffer_size;
75 #define QUEUE_SIZE 0x1000
76 #define QUEUE_MASK 0x0FFF
78 static void lz_unpack(const unsigned char *src, int src_len,
79 unsigned char *dest, int dest_len)
83 unsigned char queue[QUEUE_SIZE];
85 unsigned int dataleft;
86 unsigned int chainofs;
87 unsigned int chainlen;
93 bytestream2_init(&gb, src, src_len);
96 dataleft = bytestream2_get_le32(&gb);
97 memset(queue, 0x20, QUEUE_SIZE);
98 if (bytestream2_get_bytes_left(&gb) < 4)
100 if (bytestream2_peek_le32(&gb) == 0x56781234) {
101 bytestream2_get_le32(&gb);
106 speclen = 100; /* no speclen */
109 while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) {
110 tag = bytestream2_get_byteu(&gb);
111 if ((tag == 0xFF) && (dataleft > 8)) {
112 if (d + 8 > d_end || bytestream2_get_bytes_left(&gb) < 8)
114 for (i = 0; i < 8; i++) {
115 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
120 for (i = 0; i < 8; i++) {
124 if (d + 1 > d_end || bytestream2_get_bytes_left(&gb) < 1)
126 queue[qpos++] = *d++ = bytestream2_get_byte(&gb);
130 chainofs = bytestream2_get_byte(&gb);
131 chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4);
132 chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3;
133 if (chainlen == speclen) {
134 chainlen = bytestream2_get_byte(&gb) + 0xF + 3;
136 if (d + chainlen > d_end)
138 for (j = 0; j < chainlen; j++) {
139 *d = queue[chainofs++ & QUEUE_MASK];
140 queue[qpos++] = *d++;
143 dataleft -= chainlen;
151 static int rle_unpack(const unsigned char *src, unsigned char *dest,
152 int src_count, int src_size, int dest_len)
156 unsigned char *dest_end = dest + dest_len;
160 bytestream2_init(&gb, src, src_size);
163 if (bytestream2_get_bytes_left(&gb) < 1)
165 *pd++ = bytestream2_get_byteu(&gb);
170 if (bytestream2_get_bytes_left(&gb) < 1)
172 l = bytestream2_get_byteu(&gb);
175 if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < l)
176 return bytestream2_tell(&gb);
177 bytestream2_get_buffer(&gb, pd, l);
180 if (pd + l > dest_end || 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);
190 } while (used < src_count);
192 return bytestream2_tell(&gb);
195 static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
198 unsigned int *palette32;
199 unsigned char r, g, b;
204 unsigned char *dp; /* pointer to current frame */
205 unsigned char *pp; /* pointer to previous frame */
209 int frame_x, frame_y;
210 int frame_width, frame_height;
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 if (frame_x < 0 || frame_width < 0 ||
217 frame_x >= s->avctx->width ||
218 frame_width > s->avctx->width ||
219 frame_x + frame_width > s->avctx->width) {
220 av_log(s->avctx, AV_LOG_ERROR,
221 "Invalid horizontal range %d-%d\n",
222 frame_x, frame_width);
223 return AVERROR_INVALIDDATA;
225 if (frame_y < 0 || frame_height < 0 ||
226 frame_y >= s->avctx->height ||
227 frame_height > s->avctx->height ||
228 frame_y + frame_height > s->avctx->height) {
229 av_log(s->avctx, AV_LOG_ERROR,
230 "Invalid vertical range %d-%d\n",
231 frame_x, frame_width);
232 return AVERROR_INVALIDDATA;
235 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
236 (frame_x || frame_y)) {
244 /* if only a certain region will be updated, copy the entire previous
245 * frame before the decode */
246 if (s->prev_frame.data[0] &&
247 (frame_x || frame_y || (frame_width != s->avctx->width) ||
248 (frame_height != s->avctx->height))) {
250 memcpy(frame->data[0], s->prev_frame.data[0],
251 s->avctx->height * frame->linesize[0]);
254 /* check if there is a new palette */
255 bytestream2_init(&gb, s->buf + 16, s->size - 16);
256 if (s->buf[15] & 0x02) {
257 bytestream2_skip(&gb, 2);
258 palette32 = (unsigned int *)s->palette;
259 if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) {
260 for (i = 0; i < PALETTE_COUNT; i++) {
261 r = bytestream2_get_byteu(&gb) * 4;
262 g = bytestream2_get_byteu(&gb) * 4;
263 b = bytestream2_get_byteu(&gb) * 4;
264 palette32[i] = (r << 16) | (g << 8) | (b);
267 av_log(s->avctx, AV_LOG_ERROR, "Incomplete palette\n");
268 return AVERROR_INVALIDDATA;
270 s->size -= PALETTE_COUNT * 3 + 2;
276 /* originally UnpackFrame in VAG's code */
277 if (bytestream2_get_bytes_left(&gb) < 1)
278 return AVERROR_INVALIDDATA;
279 meth = bytestream2_get_byteu(&gb);
281 if (!s->unpack_buffer_size) {
282 av_log(s->avctx, AV_LOG_ERROR,
283 "Trying to unpack LZ-compressed frame with no LZ buffer\n");
284 return AVERROR_INVALIDDATA;
286 lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
287 s->unpack_buffer, s->unpack_buffer_size);
289 bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
292 dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
293 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
296 for (i = 0; i < frame_height; i++) {
299 len = bytestream2_get_byte(&gb);
301 len = (len & 0x7F) + 1;
302 if (ofs + len > frame_width ||
303 bytestream2_get_bytes_left(&gb) < len)
304 return AVERROR_INVALIDDATA;
305 bytestream2_get_buffer(&gb, &dp[ofs], len);
308 /* interframe pixel copy */
309 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
310 return AVERROR_INVALIDDATA;
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,
317 "VMD video: offset > width (%d > %d)\n",
319 return AVERROR_INVALIDDATA;
321 dp += frame->linesize[0];
322 pp += s->prev_frame.linesize[0];
327 for (i = 0; i < frame_height; i++) {
328 bytestream2_get_buffer(&gb, dp, frame_width);
329 dp += frame->linesize[0];
330 pp += s->prev_frame.linesize[0];
335 for (i = 0; i < frame_height; i++) {
338 len = bytestream2_get_byte(&gb);
340 len = (len & 0x7F) + 1;
341 if (bytestream2_peek_byte(&gb) == 0xFF) {
343 bytestream2_get_byte(&gb);
344 len = rle_unpack(gb.buffer, &dp[ofs],
345 len, bytestream2_get_bytes_left(&gb),
348 bytestream2_skip(&gb, len);
350 bytestream2_get_buffer(&gb, &dp[ofs], len);
354 /* interframe pixel copy */
355 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
356 return AVERROR_INVALIDDATA;
357 memcpy(&dp[ofs], &pp[ofs], len + 1);
360 } while (ofs < frame_width);
361 if (ofs > frame_width) {
362 av_log(s->avctx, AV_LOG_ERROR,
363 "VMD video: offset > width (%d > %d)\n",
365 return AVERROR_INVALIDDATA;
367 dp += frame->linesize[0];
368 pp += s->prev_frame.linesize[0];
375 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
377 VmdVideoContext *s = avctx->priv_data;
379 unsigned int *palette32;
380 int palette_index = 0;
381 unsigned char r, g, b;
382 unsigned char *vmd_header;
383 unsigned char *raw_palette;
386 avctx->pix_fmt = AV_PIX_FMT_PAL8;
388 /* make sure the VMD header made it */
389 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
390 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
394 vmd_header = (unsigned char *)avctx->extradata;
396 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
397 if (s->unpack_buffer_size) {
398 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
399 if (!s->unpack_buffer)
400 return AVERROR(ENOMEM);
403 /* load up the initial palette */
404 raw_palette = &vmd_header[28];
405 palette32 = (unsigned int *)s->palette;
406 for (i = 0; i < PALETTE_COUNT; i++) {
407 r = raw_palette[palette_index++] * 4;
408 g = raw_palette[palette_index++] * 4;
409 b = raw_palette[palette_index++] * 4;
410 palette32[i] = (r << 16) | (g << 8) | (b);
416 static int vmdvideo_decode_frame(AVCodecContext *avctx,
417 void *data, int *got_frame,
420 const uint8_t *buf = avpkt->data;
421 int buf_size = avpkt->size;
422 VmdVideoContext *s = avctx->priv_data;
423 AVFrame *frame = data;
430 return AVERROR_INVALIDDATA;
432 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
433 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
437 if ((ret = vmd_decode(s, frame)) < 0)
440 /* make the palette available on the way out */
441 memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
444 av_frame_unref(&s->prev_frame);
445 if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0)
450 /* report that the buffer was completely consumed */
454 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
456 VmdVideoContext *s = avctx->priv_data;
458 av_frame_unref(&s->prev_frame);
459 av_free(s->unpack_buffer);
469 #define BLOCK_TYPE_AUDIO 1
470 #define BLOCK_TYPE_INITIAL 2
471 #define BLOCK_TYPE_SILENCE 3
473 typedef struct VmdAudioContext {
478 static const uint16_t vmdaudio_table[128] = {
479 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
480 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
481 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
482 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
483 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
484 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
485 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
486 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
487 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
488 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
489 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
490 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
491 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
494 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
496 VmdAudioContext *s = avctx->priv_data;
498 if (avctx->channels < 1 || avctx->channels > 2) {
499 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
500 return AVERROR(EINVAL);
502 if (avctx->block_align < 1) {
503 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
504 return AVERROR(EINVAL);
507 avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
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 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
519 "block align = %d, sample rate = %d\n",
520 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
526 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
530 const uint8_t *buf_end = buf + buf_size;
532 int st = channels - 1;
534 /* decode initial raw sample */
535 for (ch = 0; ch < channels; ch++) {
536 predictor[ch] = (int16_t)AV_RL16(buf);
538 *out++ = predictor[ch];
541 /* decode DPCM samples */
543 while (buf < buf_end) {
546 predictor[ch] -= vmdaudio_table[b & 0x7F];
548 predictor[ch] += vmdaudio_table[b];
549 predictor[ch] = av_clip_int16(predictor[ch]);
550 *out++ = predictor[ch];
555 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
556 int *got_frame_ptr, AVPacket *avpkt)
558 AVFrame *frame = data;
559 const uint8_t *buf = avpkt->data;
560 const uint8_t *buf_end;
561 int buf_size = avpkt->size;
562 VmdAudioContext *s = avctx->priv_data;
563 int block_type, silent_chunks, audio_chunks;
565 uint8_t *output_samples_u8;
566 int16_t *output_samples_s16;
569 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
575 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
576 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
577 return AVERROR(EINVAL);
582 /* get number of silent chunks */
584 if (block_type == BLOCK_TYPE_INITIAL) {
587 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
588 return AVERROR(EINVAL);
590 flags = AV_RB32(buf);
591 silent_chunks = av_popcount(flags);
594 } else if (block_type == BLOCK_TYPE_SILENCE) {
596 buf_size = 0; // should already be zero but set it just to be sure
599 /* ensure output buffer is large enough */
600 audio_chunks = buf_size / s->chunk_size;
602 /* drop incomplete chunks */
603 buf_size = audio_chunks * s->chunk_size;
605 /* get output buffer */
606 frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
608 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
609 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
612 output_samples_u8 = frame->data[0];
613 output_samples_s16 = (int16_t *)frame->data[0];
615 /* decode silent chunks */
616 if (silent_chunks > 0) {
617 int silent_size = FFMIN(avctx->block_align * silent_chunks,
618 frame->nb_samples * avctx->channels);
619 if (s->out_bps == 2) {
620 memset(output_samples_s16, 0x00, silent_size * 2);
621 output_samples_s16 += silent_size;
623 memset(output_samples_u8, 0x80, silent_size);
624 output_samples_u8 += silent_size;
628 /* decode audio chunks */
629 if (audio_chunks > 0) {
630 buf_end = buf + (buf_size & ~(avctx->channels > 1));
631 while (buf + s->chunk_size <= buf_end) {
632 if (s->out_bps == 2) {
633 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
635 output_samples_s16 += avctx->block_align;
637 memcpy(output_samples_u8, buf, s->chunk_size);
638 output_samples_u8 += avctx->block_align;
640 buf += s->chunk_size;
651 * Public Data Structures
654 AVCodec ff_vmdvideo_decoder = {
656 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
657 .type = AVMEDIA_TYPE_VIDEO,
658 .id = AV_CODEC_ID_VMDVIDEO,
659 .priv_data_size = sizeof(VmdVideoContext),
660 .init = vmdvideo_decode_init,
661 .close = vmdvideo_decode_end,
662 .decode = vmdvideo_decode_frame,
663 .capabilities = CODEC_CAP_DR1,
666 AVCodec ff_vmdaudio_decoder = {
668 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
669 .type = AVMEDIA_TYPE_AUDIO,
670 .id = AV_CODEC_ID_VMDAUDIO,
671 .priv_data_size = sizeof(VmdAudioContext),
672 .init = vmdaudio_decode_init,
673 .decode = vmdaudio_decode_frame,
674 .capabilities = CODEC_CAP_DR1,