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, unsigned char *dest, int dest_len)
77 const unsigned char *s;
80 unsigned char queue[QUEUE_SIZE];
82 unsigned int dataleft;
83 unsigned int chainofs;
84 unsigned int chainlen;
92 dataleft = AV_RL32(s);
94 memset(queue, 0x20, QUEUE_SIZE);
95 if (AV_RL32(s) == 0x56781234) {
101 speclen = 100; /* no speclen */
104 while (dataleft > 0) {
106 if ((tag == 0xFF) && (dataleft > 8)) {
109 for (i = 0; i < 8; i++) {
110 queue[qpos++] = *d++ = *s++;
115 for (i = 0; i < 8; i++) {
121 queue[qpos++] = *d++ = *s++;
126 chainofs |= ((*s & 0xF0) << 4);
127 chainlen = (*s++ & 0x0F) + 3;
128 if (chainlen == speclen)
129 chainlen = *s++ + 0xF + 3;
130 if (d + chainlen > d_end)
132 for (j = 0; j < chainlen; j++) {
133 *d = queue[chainofs++ & QUEUE_MASK];
134 queue[qpos++] = *d++;
137 dataleft -= chainlen;
145 static int rle_unpack(const unsigned char *src, unsigned char *dest,
146 int src_len, int dest_len)
148 const unsigned char *ps;
151 unsigned char *dest_end = dest + dest_len;
164 if (pd + l > dest_end)
170 if (pd + i > dest_end)
172 for (i = 0; i < l; i++) {
179 } while (i < src_len);
184 static void vmd_decode(VmdVideoContext *s)
187 unsigned int *palette32;
188 unsigned char r, g, b;
190 /* point to the start of the encoded data */
191 const unsigned char *p = s->buf + 16;
193 const unsigned char *pb;
195 unsigned char *dp; /* pointer to current frame */
196 unsigned char *pp; /* pointer to previous frame */
200 int frame_x, frame_y;
201 int frame_width, frame_height;
203 frame_x = AV_RL16(&s->buf[6]);
204 frame_y = AV_RL16(&s->buf[8]);
205 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
206 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
208 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
209 (frame_x || frame_y)) {
217 /* if only a certain region will be updated, copy the entire previous
218 * frame before the decode */
219 if (frame_x || frame_y || (frame_width != s->avctx->width) ||
220 (frame_height != s->avctx->height)) {
222 memcpy(s->frame.data[0], s->prev_frame.data[0],
223 s->avctx->height * s->frame.linesize[0]);
226 /* check if there is a new palette */
227 if (s->buf[15] & 0x02) {
229 palette32 = (unsigned int *)s->palette;
230 for (i = 0; i < PALETTE_COUNT; i++) {
234 palette32[i] = (r << 16) | (g << 8) | (b);
236 s->size -= (256 * 3 + 2);
239 /* originally UnpackFrame in VAG's code */
243 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
245 pb = s->unpack_buffer;
248 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
249 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
252 for (i = 0; i < frame_height; i++) {
257 len = (len & 0x7F) + 1;
258 if (ofs + len > frame_width)
260 memcpy(&dp[ofs], pb, len);
264 /* interframe pixel copy */
265 if (ofs + len + 1 > frame_width)
267 memcpy(&dp[ofs], &pp[ofs], len + 1);
270 } while (ofs < frame_width);
271 if (ofs > frame_width) {
272 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
276 dp += s->frame.linesize[0];
277 pp += s->prev_frame.linesize[0];
282 for (i = 0; i < frame_height; i++) {
283 memcpy(dp, pb, frame_width);
285 dp += s->frame.linesize[0];
286 pp += s->prev_frame.linesize[0];
291 for (i = 0; i < frame_height; i++) {
296 len = (len & 0x7F) + 1;
298 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
300 memcpy(&dp[ofs], pb, len);
304 /* interframe pixel copy */
305 if (ofs + len + 1 > frame_width)
307 memcpy(&dp[ofs], &pp[ofs], len + 1);
310 } while (ofs < frame_width);
311 if (ofs > frame_width) {
312 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
315 dp += s->frame.linesize[0];
316 pp += s->prev_frame.linesize[0];
323 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
325 VmdVideoContext *s = avctx->priv_data;
327 unsigned int *palette32;
328 int palette_index = 0;
329 unsigned char r, g, b;
330 unsigned char *vmd_header;
331 unsigned char *raw_palette;
334 avctx->pix_fmt = PIX_FMT_PAL8;
336 /* make sure the VMD header made it */
337 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
338 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
342 vmd_header = (unsigned char *)avctx->extradata;
344 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
345 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
346 if (!s->unpack_buffer)
349 /* load up the initial palette */
350 raw_palette = &vmd_header[28];
351 palette32 = (unsigned int *)s->palette;
352 for (i = 0; i < PALETTE_COUNT; i++) {
353 r = raw_palette[palette_index++] * 4;
354 g = raw_palette[palette_index++] * 4;
355 b = raw_palette[palette_index++] * 4;
356 palette32[i] = (r << 16) | (g << 8) | (b);
362 static int vmdvideo_decode_frame(AVCodecContext *avctx,
363 void *data, int *data_size,
366 const uint8_t *buf = avpkt->data;
367 int buf_size = avpkt->size;
368 VmdVideoContext *s = avctx->priv_data;
376 s->frame.reference = 1;
377 if (avctx->get_buffer(avctx, &s->frame)) {
378 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
384 /* make the palette available on the way out */
385 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
388 FFSWAP(AVFrame, s->frame, s->prev_frame);
389 if (s->frame.data[0])
390 avctx->release_buffer(avctx, &s->frame);
392 *data_size = sizeof(AVFrame);
393 *(AVFrame*)data = s->prev_frame;
395 /* report that the buffer was completely consumed */
399 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
401 VmdVideoContext *s = avctx->priv_data;
403 if (s->prev_frame.data[0])
404 avctx->release_buffer(avctx, &s->prev_frame);
405 av_free(s->unpack_buffer);
415 #define BLOCK_TYPE_AUDIO 1
416 #define BLOCK_TYPE_INITIAL 2
417 #define BLOCK_TYPE_SILENCE 3
419 typedef struct VmdAudioContext {
424 static const uint16_t vmdaudio_table[128] = {
425 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
426 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
427 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
428 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
429 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
430 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
431 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
432 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
433 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
434 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
435 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
436 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
437 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
440 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
442 VmdAudioContext *s = avctx->priv_data;
444 if (avctx->channels < 1 || avctx->channels > 2) {
445 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
446 return AVERROR(EINVAL);
448 if (avctx->block_align < 1) {
449 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
450 return AVERROR(EINVAL);
453 if (avctx->bits_per_coded_sample == 16)
454 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
456 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
457 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
459 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
461 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
462 "block align = %d, sample rate = %d\n",
463 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
469 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
473 const uint8_t *buf_end = buf + buf_size;
475 int st = channels - 1;
477 /* decode initial raw sample */
478 for (ch = 0; ch < channels; ch++) {
479 predictor[ch] = (int16_t)AV_RL16(buf);
481 *out++ = predictor[ch];
484 /* decode DPCM samples */
486 while (buf < buf_end) {
489 predictor[ch] -= vmdaudio_table[b & 0x7F];
491 predictor[ch] += vmdaudio_table[b];
492 predictor[ch] = av_clip_int16(predictor[ch]);
493 *out++ = predictor[ch];
498 static int vmdaudio_decode_frame(AVCodecContext *avctx,
499 void *data, int *data_size,
502 const uint8_t *buf = avpkt->data;
503 const uint8_t *buf_end;
504 int buf_size = avpkt->size;
505 VmdAudioContext *s = avctx->priv_data;
506 int block_type, silent_chunks, audio_chunks;
507 int nb_samples, out_size;
508 uint8_t *output_samples_u8 = data;
509 int16_t *output_samples_s16 = data;
512 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
518 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
519 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
520 return AVERROR(EINVAL);
525 /* get number of silent chunks */
527 if (block_type == BLOCK_TYPE_INITIAL) {
530 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
531 return AVERROR(EINVAL);
533 flags = AV_RB32(buf);
534 silent_chunks = av_popcount(flags);
537 } else if (block_type == BLOCK_TYPE_SILENCE) {
539 buf_size = 0; // should already be zero but set it just to be sure
542 /* ensure output buffer is large enough */
543 audio_chunks = buf_size / s->chunk_size;
544 nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
545 out_size = nb_samples * avctx->channels * s->out_bps;
546 if (*data_size < out_size)
549 /* decode silent chunks */
550 if (silent_chunks > 0) {
551 int silent_size = avctx->block_align * silent_chunks;
552 if (s->out_bps == 2) {
553 memset(output_samples_s16, 0x00, silent_size * 2);
554 output_samples_s16 += silent_size;
556 memset(output_samples_u8, 0x80, silent_size);
557 output_samples_u8 += silent_size;
561 /* decode audio chunks */
562 if (audio_chunks > 0) {
563 buf_end = buf + buf_size;
564 while (buf < buf_end) {
565 if (s->out_bps == 2) {
566 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
568 output_samples_s16 += avctx->block_align;
570 memcpy(output_samples_u8, buf, s->chunk_size);
571 output_samples_u8 += avctx->block_align;
573 buf += s->chunk_size;
577 *data_size = out_size;
583 * Public Data Structures
586 AVCodec ff_vmdvideo_decoder = {
588 .type = AVMEDIA_TYPE_VIDEO,
589 .id = CODEC_ID_VMDVIDEO,
590 .priv_data_size = sizeof(VmdVideoContext),
591 .init = vmdvideo_decode_init,
592 .close = vmdvideo_decode_end,
593 .decode = vmdvideo_decode_frame,
594 .capabilities = CODEC_CAP_DR1,
595 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
598 AVCodec ff_vmdaudio_decoder = {
600 .type = AVMEDIA_TYPE_AUDIO,
601 .id = CODEC_ID_VMDAUDIO,
602 .priv_data_size = sizeof(VmdAudioContext),
603 .init = vmdaudio_decode_init,
604 .decode = vmdaudio_decode_frame,
605 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),