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 int 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)
100 return AVERROR_INVALIDDATA;
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)
114 return AVERROR_INVALIDDATA;
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)
126 return AVERROR_INVALIDDATA;
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)
138 return AVERROR_INVALIDDATA;
139 for (j = 0; j < chainlen; j++) {
140 *d = queue[chainofs++ & QUEUE_MASK];
141 queue[qpos++] = *d++;
144 dataleft -= chainlen;
152 static int rle_unpack(const unsigned char *src, unsigned char *dest,
153 int src_count, int src_size, int dest_len)
157 unsigned char *dest_end = dest + dest_len;
161 bytestream2_init(&gb, src, src_size);
164 if (bytestream2_get_bytes_left(&gb) < 1)
166 *pd++ = bytestream2_get_byteu(&gb);
171 if (bytestream2_get_bytes_left(&gb) < 1)
173 l = bytestream2_get_byteu(&gb);
176 if (dest_end - pd < l || bytestream2_get_bytes_left(&gb) < l)
177 return bytestream2_tell(&gb);
178 bytestream2_get_bufferu(&gb, pd, l);
181 if (dest_end - pd < 2*l || bytestream2_get_bytes_left(&gb) < 2)
182 return bytestream2_tell(&gb);
183 run_val = bytestream2_get_ne16(&gb);
184 for (i = 0; i < l; i++) {
185 AV_WN16(pd, run_val);
191 } while (used < src_count);
193 return bytestream2_tell(&gb);
196 static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
199 unsigned int *palette32;
200 unsigned char r, g, b;
205 unsigned char *dp; /* pointer to current frame */
206 unsigned char *pp; /* pointer to previous frame */
210 int frame_x, frame_y;
211 int frame_width, frame_height;
213 frame_x = AV_RL16(&s->buf[6]);
214 frame_y = AV_RL16(&s->buf[8]);
215 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
216 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
218 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
219 (frame_x || frame_y)) {
227 if (frame_x < 0 || frame_width < 0 ||
228 frame_x >= s->avctx->width ||
229 frame_width > s->avctx->width ||
230 frame_x + frame_width > s->avctx->width) {
231 av_log(s->avctx, AV_LOG_ERROR,
232 "Invalid horizontal range %d-%d\n",
233 frame_x, frame_width);
234 return AVERROR_INVALIDDATA;
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) {
240 av_log(s->avctx, AV_LOG_ERROR,
241 "Invalid vertical range %d-%d\n",
242 frame_x, frame_width);
243 return AVERROR_INVALIDDATA;
246 /* if only a certain region will be updated, copy the entire previous
247 * frame before the decode */
248 if (s->prev_frame->data[0] &&
249 (frame_x || frame_y || (frame_width != s->avctx->width) ||
250 (frame_height != s->avctx->height))) {
252 memcpy(frame->data[0], s->prev_frame->data[0],
253 s->avctx->height * frame->linesize[0]);
256 /* check if there is a new palette */
257 bytestream2_init(&gb, s->buf + 16, s->size - 16);
258 if (s->buf[15] & 0x02) {
259 bytestream2_skip(&gb, 2);
260 palette32 = (unsigned int *)s->palette;
261 if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) {
262 for (i = 0; i < PALETTE_COUNT; i++) {
263 r = bytestream2_get_byteu(&gb) * 4;
264 g = bytestream2_get_byteu(&gb) * 4;
265 b = bytestream2_get_byteu(&gb) * 4;
266 palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b);
267 palette32[i] |= palette32[i] >> 6 & 0x30303;
270 av_log(s->avctx, AV_LOG_ERROR, "Incomplete palette\n");
271 return AVERROR_INVALIDDATA;
278 /* originally UnpackFrame in VAG's code */
279 if (bytestream2_get_bytes_left(&gb) < 1)
280 return AVERROR_INVALIDDATA;
281 meth = bytestream2_get_byteu(&gb);
284 if (!s->unpack_buffer_size) {
285 av_log(s->avctx, AV_LOG_ERROR,
286 "Trying to unpack LZ-compressed frame with no LZ buffer\n");
287 return AVERROR_INVALIDDATA;
289 size = lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
290 s->unpack_buffer, s->unpack_buffer_size);
294 bytestream2_init(&gb, s->unpack_buffer, size);
297 dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
298 pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x];
301 for (i = 0; i < frame_height; i++) {
304 len = bytestream2_get_byte(&gb);
306 len = (len & 0x7F) + 1;
307 if (ofs + len > frame_width ||
308 bytestream2_get_bytes_left(&gb) < len)
309 return AVERROR_INVALIDDATA;
310 bytestream2_get_bufferu(&gb, &dp[ofs], len);
313 /* interframe pixel copy */
314 if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
315 return AVERROR_INVALIDDATA;
316 memcpy(&dp[ofs], &pp[ofs], len + 1);
319 } while (ofs < frame_width);
320 if (ofs > frame_width) {
321 av_log(s->avctx, AV_LOG_ERROR,
322 "offset > width (%d > %d)\n",
324 return AVERROR_INVALIDDATA;
326 dp += frame->linesize[0];
327 pp += s->prev_frame->linesize[0];
332 for (i = 0; i < frame_height; i++) {
333 bytestream2_get_buffer(&gb, dp, frame_width);
334 dp += frame->linesize[0];
335 pp += s->prev_frame->linesize[0];
340 for (i = 0; i < frame_height; i++) {
343 len = bytestream2_get_byte(&gb);
345 len = (len & 0x7F) + 1;
346 if (bytestream2_peek_byte(&gb) == 0xFF) {
348 bytestream2_get_byte(&gb);
349 len = rle_unpack(gb.buffer, &dp[ofs],
350 len, bytestream2_get_bytes_left(&gb),
353 bytestream2_skip(&gb, len);
355 bytestream2_get_buffer(&gb, &dp[ofs], len);
359 /* interframe pixel copy */
360 if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
361 return AVERROR_INVALIDDATA;
362 memcpy(&dp[ofs], &pp[ofs], len + 1);
365 } while (ofs < frame_width);
366 if (ofs > frame_width) {
367 av_log(s->avctx, AV_LOG_ERROR,
368 "offset > width (%d > %d)\n",
370 return AVERROR_INVALIDDATA;
372 dp += frame->linesize[0];
373 pp += s->prev_frame->linesize[0];
380 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
382 VmdVideoContext *s = avctx->priv_data;
384 av_frame_free(&s->prev_frame);
385 av_freep(&s->unpack_buffer);
386 s->unpack_buffer_size = 0;
391 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
393 VmdVideoContext *s = avctx->priv_data;
395 unsigned int *palette32;
396 int palette_index = 0;
397 unsigned char r, g, b;
398 unsigned char *vmd_header;
399 unsigned char *raw_palette;
402 avctx->pix_fmt = AV_PIX_FMT_PAL8;
404 /* make sure the VMD header made it */
405 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
406 av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n",
408 return AVERROR_INVALIDDATA;
410 vmd_header = (unsigned char *)avctx->extradata;
412 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
413 if (s->unpack_buffer_size) {
414 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
415 if (!s->unpack_buffer)
416 return AVERROR(ENOMEM);
419 /* load up the initial palette */
420 raw_palette = &vmd_header[28];
421 palette32 = (unsigned int *)s->palette;
422 for (i = 0; i < PALETTE_COUNT; i++) {
423 r = raw_palette[palette_index++] * 4;
424 g = raw_palette[palette_index++] * 4;
425 b = raw_palette[palette_index++] * 4;
426 palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b);
427 palette32[i] |= palette32[i] >> 6 & 0x30303;
430 s->prev_frame = av_frame_alloc();
431 if (!s->prev_frame) {
432 vmdvideo_decode_end(avctx);
433 return AVERROR(ENOMEM);
439 static int vmdvideo_decode_frame(AVCodecContext *avctx,
440 void *data, int *got_frame,
443 const uint8_t *buf = avpkt->data;
444 int buf_size = avpkt->size;
445 VmdVideoContext *s = avctx->priv_data;
446 AVFrame *frame = data;
453 return AVERROR_INVALIDDATA;
455 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
458 if ((ret = vmd_decode(s, frame)) < 0)
461 /* make the palette available on the way out */
462 memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
465 av_frame_unref(s->prev_frame);
466 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
471 /* report that the buffer was completely consumed */
479 #define BLOCK_TYPE_AUDIO 1
480 #define BLOCK_TYPE_INITIAL 2
481 #define BLOCK_TYPE_SILENCE 3
483 typedef struct VmdAudioContext {
488 static const uint16_t vmdaudio_table[128] = {
489 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
490 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
491 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
492 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
493 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
494 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
495 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
496 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
497 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
498 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
499 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
500 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
501 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
504 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
506 VmdAudioContext *s = avctx->priv_data;
508 if (avctx->channels < 1 || avctx->channels > 2) {
509 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
510 return AVERROR(EINVAL);
512 if (avctx->block_align < 1 || avctx->block_align % avctx->channels) {
513 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
514 return AVERROR(EINVAL);
517 avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
520 if (avctx->bits_per_coded_sample == 16)
521 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
523 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
524 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
526 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
528 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
529 "block align = %d, sample rate = %d\n",
530 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
536 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
540 const uint8_t *buf_end = buf + buf_size;
542 int st = channels - 1;
544 /* decode initial raw sample */
545 for (ch = 0; ch < channels; ch++) {
546 predictor[ch] = (int16_t)AV_RL16(buf);
548 *out++ = predictor[ch];
551 /* decode DPCM samples */
553 while (buf < buf_end) {
556 predictor[ch] -= vmdaudio_table[b & 0x7F];
558 predictor[ch] += vmdaudio_table[b];
559 predictor[ch] = av_clip_int16(predictor[ch]);
560 *out++ = predictor[ch];
565 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
566 int *got_frame_ptr, AVPacket *avpkt)
568 AVFrame *frame = data;
569 const uint8_t *buf = avpkt->data;
570 const uint8_t *buf_end;
571 int buf_size = avpkt->size;
572 VmdAudioContext *s = avctx->priv_data;
573 int block_type, silent_chunks, audio_chunks;
575 uint8_t *output_samples_u8;
576 int16_t *output_samples_s16;
579 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
585 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
586 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
587 return AVERROR(EINVAL);
592 /* get number of silent chunks */
594 if (block_type == BLOCK_TYPE_INITIAL) {
597 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
598 return AVERROR(EINVAL);
600 flags = AV_RB32(buf);
601 silent_chunks = av_popcount(flags);
604 } else if (block_type == BLOCK_TYPE_SILENCE) {
606 buf_size = 0; // should already be zero but set it just to be sure
609 /* ensure output buffer is large enough */
610 audio_chunks = buf_size / s->chunk_size;
612 /* drop incomplete chunks */
613 buf_size = audio_chunks * s->chunk_size;
615 /* get output buffer */
616 frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
618 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
620 output_samples_u8 = frame->data[0];
621 output_samples_s16 = (int16_t *)frame->data[0];
623 /* decode silent chunks */
624 if (silent_chunks > 0) {
625 int silent_size = avctx->block_align * silent_chunks;
626 av_assert0(avctx->block_align * silent_chunks <= frame->nb_samples * avctx->channels);
628 if (s->out_bps == 2) {
629 memset(output_samples_s16, 0x00, silent_size * 2);
630 output_samples_s16 += silent_size;
632 memset(output_samples_u8, 0x80, silent_size);
633 output_samples_u8 += silent_size;
637 /* decode audio chunks */
638 if (audio_chunks > 0) {
639 buf_end = buf + buf_size;
640 av_assert0((buf_size & (avctx->channels > 1)) == 0);
641 while (buf_end - buf >= s->chunk_size) {
642 if (s->out_bps == 2) {
643 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
645 output_samples_s16 += avctx->block_align;
647 memcpy(output_samples_u8, buf, s->chunk_size);
648 output_samples_u8 += avctx->block_align;
650 buf += s->chunk_size;
661 * Public Data Structures
664 AVCodec ff_vmdvideo_decoder = {
666 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
667 .type = AVMEDIA_TYPE_VIDEO,
668 .id = AV_CODEC_ID_VMDVIDEO,
669 .priv_data_size = sizeof(VmdVideoContext),
670 .init = vmdvideo_decode_init,
671 .close = vmdvideo_decode_end,
672 .decode = vmdvideo_decode_frame,
673 .capabilities = CODEC_CAP_DR1,
676 AVCodec ff_vmdaudio_decoder = {
678 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
679 .type = AVMEDIA_TYPE_AUDIO,
680 .id = AV_CODEC_ID_VMDAUDIO,
681 .priv_data_size = sizeof(VmdAudioContext),
682 .init = vmdaudio_decode_init,
683 .decode = vmdaudio_decode_frame,
684 .capabilities = CODEC_CAP_DR1,