2 * Sierra VMD Audio & Video Decoders
3 * Copyright (C) 2004 the ffmpeg project
5 * This file is part of FFmpeg.
7 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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/avassert.h"
47 #include "libavutil/channel_layout.h"
48 #include "libavutil/common.h"
49 #include "libavutil/intreadwrite.h"
52 #include "bytestream.h"
54 #define VMD_HEADER_SIZE 0x330
55 #define PALETTE_COUNT 256
61 typedef struct VmdVideoContext {
63 AVCodecContext *avctx;
66 const unsigned char *buf;
69 unsigned char palette[PALETTE_COUNT * 4];
70 unsigned char *unpack_buffer;
71 int unpack_buffer_size;
76 #define QUEUE_SIZE 0x1000
77 #define QUEUE_MASK 0x0FFF
79 static void lz_unpack(const unsigned char *src, int src_len,
80 unsigned char *dest, int dest_len)
84 unsigned char queue[QUEUE_SIZE];
86 unsigned int dataleft;
87 unsigned int chainofs;
88 unsigned int chainlen;
94 bytestream2_init(&gb, src, src_len);
97 dataleft = bytestream2_get_le32(&gb);
98 memset(queue, 0x20, QUEUE_SIZE);
99 if (bytestream2_get_bytes_left(&gb) < 4)
101 if (bytestream2_peek_le32(&gb) == 0x56781234) {
102 bytestream2_skipu(&gb, 4);
107 speclen = 100; /* no speclen */
110 while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) {
111 tag = bytestream2_get_byteu(&gb);
112 if ((tag == 0xFF) && (dataleft > 8)) {
113 if (d_end - d < 8 || bytestream2_get_bytes_left(&gb) < 8)
115 for (i = 0; i < 8; i++) {
116 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
121 for (i = 0; i < 8; i++) {
125 if (d_end - d < 1 || bytestream2_get_bytes_left(&gb) < 1)
127 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
131 chainofs = bytestream2_get_byte(&gb);
132 chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4);
133 chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3;
134 if (chainlen == speclen) {
135 chainlen = bytestream2_get_byte(&gb) + 0xF + 3;
137 if (d_end - d < chainlen)
139 for (j = 0; j < chainlen; j++) {
140 *d = queue[chainofs++ & QUEUE_MASK];
141 queue[qpos++] = *d++;
144 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 (dest_end - pd < l || bytestream2_get_bytes_left(&gb) < l)
176 return bytestream2_tell(&gb);
177 bytestream2_get_bufferu(&gb, pd, l);
180 if (dest_end - pd < 2*l || 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;
217 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
218 (frame_x || frame_y)) {
226 if (frame_x < 0 || frame_width < 0 ||
227 frame_x >= s->avctx->width ||
228 frame_width > s->avctx->width ||
229 frame_x + frame_width > s->avctx->width) {
230 av_log(s->avctx, AV_LOG_ERROR,
231 "Invalid horizontal range %d-%d\n",
232 frame_x, frame_width);
233 return AVERROR_INVALIDDATA;
235 if (frame_y < 0 || frame_height < 0 ||
236 frame_y >= s->avctx->height ||
237 frame_height > s->avctx->height ||
238 frame_y + frame_height > s->avctx->height) {
239 av_log(s->avctx, AV_LOG_ERROR,
240 "Invalid vertical range %d-%d\n",
241 frame_x, frame_width);
242 return AVERROR_INVALIDDATA;
245 /* if only a certain region will be updated, copy the entire previous
246 * frame before the decode */
247 if (s->prev_frame->data[0] &&
248 (frame_x || frame_y || (frame_width != s->avctx->width) ||
249 (frame_height != s->avctx->height))) {
251 memcpy(frame->data[0], s->prev_frame->data[0],
252 s->avctx->height * frame->linesize[0]);
255 /* check if there is a new palette */
256 bytestream2_init(&gb, s->buf + 16, s->size - 16);
257 if (s->buf[15] & 0x02) {
258 bytestream2_skip(&gb, 2);
259 palette32 = (unsigned int *)s->palette;
260 if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) {
261 for (i = 0; i < PALETTE_COUNT; i++) {
262 r = bytestream2_get_byteu(&gb) * 4;
263 g = bytestream2_get_byteu(&gb) * 4;
264 b = bytestream2_get_byteu(&gb) * 4;
265 palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b);
266 palette32[i] |= palette32[i] >> 6 & 0x30303;
269 av_log(s->avctx, AV_LOG_ERROR, "Incomplete palette\n");
270 return AVERROR_INVALIDDATA;
277 /* originally UnpackFrame in VAG's code */
278 if (bytestream2_get_bytes_left(&gb) < 1)
279 return AVERROR_INVALIDDATA;
280 meth = bytestream2_get_byteu(&gb);
282 if (!s->unpack_buffer_size) {
283 av_log(s->avctx, AV_LOG_ERROR,
284 "Trying to unpack LZ-compressed frame with no LZ buffer\n");
285 return AVERROR_INVALIDDATA;
287 lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
288 s->unpack_buffer, s->unpack_buffer_size);
290 bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
293 dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
294 pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x];
297 for (i = 0; i < frame_height; i++) {
300 len = bytestream2_get_byte(&gb);
302 len = (len & 0x7F) + 1;
303 if (ofs + len > frame_width ||
304 bytestream2_get_bytes_left(&gb) < len)
305 return AVERROR_INVALIDDATA;
306 bytestream2_get_bufferu(&gb, &dp[ofs], len);
309 /* interframe pixel copy */
310 if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
311 return AVERROR_INVALIDDATA;
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,
318 "offset > width (%d > %d)\n",
320 return AVERROR_INVALIDDATA;
322 dp += frame->linesize[0];
323 pp += s->prev_frame->linesize[0];
328 for (i = 0; i < frame_height; i++) {
329 bytestream2_get_buffer(&gb, dp, frame_width);
330 dp += frame->linesize[0];
331 pp += s->prev_frame->linesize[0];
336 for (i = 0; i < frame_height; i++) {
339 len = bytestream2_get_byte(&gb);
341 len = (len & 0x7F) + 1;
342 if (bytestream2_peek_byte(&gb) == 0xFF) {
344 bytestream2_get_byte(&gb);
345 len = rle_unpack(gb.buffer, &dp[ofs],
346 len, bytestream2_get_bytes_left(&gb),
349 bytestream2_skip(&gb, len);
351 bytestream2_get_buffer(&gb, &dp[ofs], len);
355 /* interframe pixel copy */
356 if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
357 return AVERROR_INVALIDDATA;
358 memcpy(&dp[ofs], &pp[ofs], len + 1);
361 } while (ofs < frame_width);
362 if (ofs > frame_width) {
363 av_log(s->avctx, AV_LOG_ERROR,
364 "offset > width (%d > %d)\n",
366 return AVERROR_INVALIDDATA;
368 dp += frame->linesize[0];
369 pp += s->prev_frame->linesize[0];
376 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
378 VmdVideoContext *s = avctx->priv_data;
380 av_frame_free(&s->prev_frame);
381 av_freep(&s->unpack_buffer);
382 s->unpack_buffer_size = 0;
387 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
389 VmdVideoContext *s = avctx->priv_data;
391 unsigned int *palette32;
392 int palette_index = 0;
393 unsigned char r, g, b;
394 unsigned char *vmd_header;
395 unsigned char *raw_palette;
398 avctx->pix_fmt = AV_PIX_FMT_PAL8;
400 /* make sure the VMD header made it */
401 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
402 av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n",
404 return AVERROR_INVALIDDATA;
406 vmd_header = (unsigned char *)avctx->extradata;
408 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
409 if (s->unpack_buffer_size) {
410 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
411 if (!s->unpack_buffer)
412 return AVERROR(ENOMEM);
415 /* load up the initial palette */
416 raw_palette = &vmd_header[28];
417 palette32 = (unsigned int *)s->palette;
418 for (i = 0; i < PALETTE_COUNT; i++) {
419 r = raw_palette[palette_index++] * 4;
420 g = raw_palette[palette_index++] * 4;
421 b = raw_palette[palette_index++] * 4;
422 palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b);
423 palette32[i] |= palette32[i] >> 6 & 0x30303;
426 s->prev_frame = av_frame_alloc();
427 if (!s->prev_frame) {
428 vmdvideo_decode_end(avctx);
429 return AVERROR(ENOMEM);
435 static int vmdvideo_decode_frame(AVCodecContext *avctx,
436 void *data, int *got_frame,
439 const uint8_t *buf = avpkt->data;
440 int buf_size = avpkt->size;
441 VmdVideoContext *s = avctx->priv_data;
442 AVFrame *frame = data;
449 return AVERROR_INVALIDDATA;
451 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
454 if ((ret = vmd_decode(s, frame)) < 0)
457 /* make the palette available on the way out */
458 memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
461 av_frame_unref(s->prev_frame);
462 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
467 /* 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 || avctx->block_align % avctx->channels) {
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)
616 output_samples_u8 = frame->data[0];
617 output_samples_s16 = (int16_t *)frame->data[0];
619 /* decode silent chunks */
620 if (silent_chunks > 0) {
621 int silent_size = avctx->block_align * silent_chunks;
622 av_assert0(avctx->block_align * silent_chunks <= frame->nb_samples * avctx->channels);
624 if (s->out_bps == 2) {
625 memset(output_samples_s16, 0x00, silent_size * 2);
626 output_samples_s16 += silent_size;
628 memset(output_samples_u8, 0x80, silent_size);
629 output_samples_u8 += silent_size;
633 /* decode audio chunks */
634 if (audio_chunks > 0) {
635 buf_end = buf + buf_size;
636 av_assert0((buf_size & (avctx->channels > 1)) == 0);
637 while (buf_end - buf >= s->chunk_size) {
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,