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_end(AVCodecContext *avctx)
377 VmdVideoContext *s = avctx->priv_data;
379 av_frame_free(&s->prev_frame);
380 av_free(s->unpack_buffer);
385 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
387 VmdVideoContext *s = avctx->priv_data;
389 unsigned int *palette32;
390 int palette_index = 0;
391 unsigned char r, g, b;
392 unsigned char *vmd_header;
393 unsigned char *raw_palette;
396 avctx->pix_fmt = AV_PIX_FMT_PAL8;
398 /* make sure the VMD header made it */
399 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
400 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
404 vmd_header = (unsigned char *)avctx->extradata;
406 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
407 if (s->unpack_buffer_size) {
408 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
409 if (!s->unpack_buffer)
410 return AVERROR(ENOMEM);
413 /* load up the initial palette */
414 raw_palette = &vmd_header[28];
415 palette32 = (unsigned int *)s->palette;
416 for (i = 0; i < PALETTE_COUNT; i++) {
417 r = raw_palette[palette_index++] * 4;
418 g = raw_palette[palette_index++] * 4;
419 b = raw_palette[palette_index++] * 4;
420 palette32[i] = (r << 16) | (g << 8) | (b);
423 s->prev_frame = av_frame_alloc();
424 if (!s->prev_frame) {
425 vmdvideo_decode_end(avctx);
426 return AVERROR(ENOMEM);
432 static int vmdvideo_decode_frame(AVCodecContext *avctx,
433 void *data, int *got_frame,
436 const uint8_t *buf = avpkt->data;
437 int buf_size = avpkt->size;
438 VmdVideoContext *s = avctx->priv_data;
439 AVFrame *frame = data;
446 return AVERROR_INVALIDDATA;
448 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
449 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
453 if ((ret = vmd_decode(s, frame)) < 0)
456 /* make the palette available on the way out */
457 memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
460 av_frame_unref(s->prev_frame);
461 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
466 /* report that the buffer was completely consumed */
475 #define BLOCK_TYPE_AUDIO 1
476 #define BLOCK_TYPE_INITIAL 2
477 #define BLOCK_TYPE_SILENCE 3
479 typedef struct VmdAudioContext {
484 static const uint16_t vmdaudio_table[128] = {
485 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
486 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
487 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
488 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
489 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
490 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
491 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
492 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
493 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
494 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
495 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
496 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
497 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
500 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
502 VmdAudioContext *s = avctx->priv_data;
504 if (avctx->channels < 1 || avctx->channels > 2) {
505 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
506 return AVERROR(EINVAL);
508 if (avctx->block_align < 1) {
509 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
510 return AVERROR(EINVAL);
513 avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
516 if (avctx->bits_per_coded_sample == 16)
517 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
519 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
520 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
522 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
524 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
525 "block align = %d, sample rate = %d\n",
526 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
532 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
536 const uint8_t *buf_end = buf + buf_size;
538 int st = channels - 1;
540 /* decode initial raw sample */
541 for (ch = 0; ch < channels; ch++) {
542 predictor[ch] = (int16_t)AV_RL16(buf);
544 *out++ = predictor[ch];
547 /* decode DPCM samples */
549 while (buf < buf_end) {
552 predictor[ch] -= vmdaudio_table[b & 0x7F];
554 predictor[ch] += vmdaudio_table[b];
555 predictor[ch] = av_clip_int16(predictor[ch]);
556 *out++ = predictor[ch];
561 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
562 int *got_frame_ptr, AVPacket *avpkt)
564 AVFrame *frame = data;
565 const uint8_t *buf = avpkt->data;
566 const uint8_t *buf_end;
567 int buf_size = avpkt->size;
568 VmdAudioContext *s = avctx->priv_data;
569 int block_type, silent_chunks, audio_chunks;
571 uint8_t *output_samples_u8;
572 int16_t *output_samples_s16;
575 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
581 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
582 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
583 return AVERROR(EINVAL);
588 /* get number of silent chunks */
590 if (block_type == BLOCK_TYPE_INITIAL) {
593 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
594 return AVERROR(EINVAL);
596 flags = AV_RB32(buf);
597 silent_chunks = av_popcount(flags);
600 } else if (block_type == BLOCK_TYPE_SILENCE) {
602 buf_size = 0; // should already be zero but set it just to be sure
605 /* ensure output buffer is large enough */
606 audio_chunks = buf_size / s->chunk_size;
608 /* drop incomplete chunks */
609 buf_size = audio_chunks * s->chunk_size;
611 /* get output buffer */
612 frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
614 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
615 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
618 output_samples_u8 = frame->data[0];
619 output_samples_s16 = (int16_t *)frame->data[0];
621 /* decode silent chunks */
622 if (silent_chunks > 0) {
623 int silent_size = FFMIN(avctx->block_align * silent_chunks,
624 frame->nb_samples * avctx->channels);
625 if (s->out_bps == 2) {
626 memset(output_samples_s16, 0x00, silent_size * 2);
627 output_samples_s16 += silent_size;
629 memset(output_samples_u8, 0x80, silent_size);
630 output_samples_u8 += silent_size;
634 /* decode audio chunks */
635 if (audio_chunks > 0) {
636 buf_end = buf + (buf_size & ~(avctx->channels > 1));
637 while (buf + s->chunk_size <= buf_end) {
638 if (s->out_bps == 2) {
639 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
641 output_samples_s16 += avctx->block_align;
643 memcpy(output_samples_u8, buf, s->chunk_size);
644 output_samples_u8 += avctx->block_align;
646 buf += s->chunk_size;
657 * Public Data Structures
660 AVCodec ff_vmdvideo_decoder = {
662 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
663 .type = AVMEDIA_TYPE_VIDEO,
664 .id = AV_CODEC_ID_VMDVIDEO,
665 .priv_data_size = sizeof(VmdVideoContext),
666 .init = vmdvideo_decode_init,
667 .close = vmdvideo_decode_end,
668 .decode = vmdvideo_decode_frame,
669 .capabilities = CODEC_CAP_DR1,
672 AVCodec ff_vmdaudio_decoder = {
674 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
675 .type = AVMEDIA_TYPE_AUDIO,
676 .id = AV_CODEC_ID_VMDAUDIO,
677 .priv_data_size = sizeof(VmdAudioContext),
678 .init = vmdaudio_decode_init,
679 .decode = vmdaudio_decode_frame,
680 .capabilities = CODEC_CAP_DR1,