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;
204 frame_x = AV_RL16(&s->buf[6]);
205 frame_y = AV_RL16(&s->buf[8]);
206 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
207 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
209 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
210 (frame_x || frame_y)) {
218 /* if only a certain region will be updated, copy the entire previous
219 * frame before the decode */
220 if (frame_x || frame_y || (frame_width != s->avctx->width) ||
221 (frame_height != s->avctx->height)) {
223 memcpy(s->frame.data[0], s->prev_frame.data[0],
224 s->avctx->height * s->frame.linesize[0]);
227 /* check if there is a new palette */
228 if (s->buf[15] & 0x02) {
230 palette32 = (unsigned int *)s->palette;
231 for (i = 0; i < PALETTE_COUNT; i++) {
235 palette32[i] = (r << 16) | (g << 8) | (b);
237 s->size -= (256 * 3 + 2);
240 /* originally UnpackFrame in VAG's code */
244 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
246 pb = s->unpack_buffer;
249 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
250 dp_size = s->frame.linesize[0] * s->avctx->height;
251 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
254 for (i = 0; i < frame_height; i++) {
259 len = (len & 0x7F) + 1;
260 if (ofs + len > frame_width)
262 memcpy(&dp[ofs], pb, len);
266 /* interframe pixel copy */
267 if (ofs + len + 1 > frame_width)
269 memcpy(&dp[ofs], &pp[ofs], len + 1);
272 } while (ofs < frame_width);
273 if (ofs > frame_width) {
274 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
278 dp += s->frame.linesize[0];
279 pp += s->prev_frame.linesize[0];
284 for (i = 0; i < frame_height; i++) {
285 memcpy(dp, pb, frame_width);
287 dp += s->frame.linesize[0];
288 pp += s->prev_frame.linesize[0];
293 for (i = 0; i < frame_height; i++) {
298 len = (len & 0x7F) + 1;
300 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
302 memcpy(&dp[ofs], pb, len);
306 /* interframe pixel copy */
307 if (ofs + len + 1 > frame_width)
309 memcpy(&dp[ofs], &pp[ofs], len + 1);
312 } while (ofs < frame_width);
313 if (ofs > frame_width) {
314 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
317 dp += s->frame.linesize[0];
318 pp += s->prev_frame.linesize[0];
325 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
327 VmdVideoContext *s = avctx->priv_data;
329 unsigned int *palette32;
330 int palette_index = 0;
331 unsigned char r, g, b;
332 unsigned char *vmd_header;
333 unsigned char *raw_palette;
336 avctx->pix_fmt = PIX_FMT_PAL8;
338 /* make sure the VMD header made it */
339 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
340 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
344 vmd_header = (unsigned char *)avctx->extradata;
346 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
347 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
348 if (!s->unpack_buffer)
351 /* load up the initial palette */
352 raw_palette = &vmd_header[28];
353 palette32 = (unsigned int *)s->palette;
354 for (i = 0; i < PALETTE_COUNT; i++) {
355 r = raw_palette[palette_index++] * 4;
356 g = raw_palette[palette_index++] * 4;
357 b = raw_palette[palette_index++] * 4;
358 palette32[i] = (r << 16) | (g << 8) | (b);
364 static int vmdvideo_decode_frame(AVCodecContext *avctx,
365 void *data, int *data_size,
368 const uint8_t *buf = avpkt->data;
369 int buf_size = avpkt->size;
370 VmdVideoContext *s = avctx->priv_data;
378 s->frame.reference = 1;
379 if (avctx->get_buffer(avctx, &s->frame)) {
380 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
386 /* make the palette available on the way out */
387 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
390 FFSWAP(AVFrame, s->frame, s->prev_frame);
391 if (s->frame.data[0])
392 avctx->release_buffer(avctx, &s->frame);
394 *data_size = sizeof(AVFrame);
395 *(AVFrame*)data = s->prev_frame;
397 /* report that the buffer was completely consumed */
401 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
403 VmdVideoContext *s = avctx->priv_data;
405 if (s->prev_frame.data[0])
406 avctx->release_buffer(avctx, &s->prev_frame);
407 av_free(s->unpack_buffer);
417 #define BLOCK_TYPE_AUDIO 1
418 #define BLOCK_TYPE_INITIAL 2
419 #define BLOCK_TYPE_SILENCE 3
421 typedef struct VmdAudioContext {
422 AVCodecContext *avctx;
427 static const uint16_t vmdaudio_table[128] = {
428 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
429 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
430 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
431 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
432 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
433 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
434 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
435 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
436 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
437 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
438 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
439 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
440 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
443 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
445 VmdAudioContext *s = avctx->priv_data;
448 if (avctx->bits_per_coded_sample == 16)
449 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
451 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
452 s->out_bps = av_get_bits_per_sample_fmt(avctx->sample_fmt) >> 3;
454 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
455 "block align = %d, sample rate = %d\n",
456 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
462 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
463 const uint8_t *buf, int buf_size, int stereo)
467 int16_t *out = (int16_t*)data;
469 for(i = 0; i < buf_size; i++) {
471 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
473 s->predictors[chan] += vmdaudio_table[buf[i]];
474 s->predictors[chan] = av_clip_int16(s->predictors[chan]);
475 out[i] = s->predictors[chan];
480 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
481 const uint8_t *buf, int silent_chunks, int data_size)
483 int silent_size = s->avctx->block_align * silent_chunks * s->out_bps;
486 memset(data, s->out_bps == 2 ? 0x00 : 0x80, silent_size);
489 if (s->avctx->bits_per_coded_sample == 16)
490 vmdaudio_decode_audio(s, data, buf, data_size, s->avctx->channels == 2);
492 /* just copy the data */
493 memcpy(data, buf, data_size);
496 return silent_size + data_size * s->out_bps;
499 static int vmdaudio_decode_frame(AVCodecContext *avctx,
500 void *data, int *data_size,
503 const uint8_t *buf = avpkt->data;
504 int buf_size = avpkt->size;
505 VmdAudioContext *s = avctx->priv_data;
506 int block_type, silent_chunks;
507 unsigned char *output_samples = (unsigned char *)data;
510 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
516 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
517 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
518 return AVERROR(EINVAL);
524 if (block_type == BLOCK_TYPE_INITIAL) {
525 uint32_t flags = AV_RB32(buf);
526 silent_chunks = av_popcount(flags);
529 } else if (block_type == BLOCK_TYPE_SILENCE) {
531 buf_size = 0; // should already be zero but set it just to be sure
534 /* ensure output buffer is large enough */
535 if (*data_size < (avctx->block_align*silent_chunks + buf_size) * s->out_bps)
538 *data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size);
545 * Public Data Structures
548 AVCodec ff_vmdvideo_decoder = {
552 sizeof(VmdVideoContext),
553 vmdvideo_decode_init,
556 vmdvideo_decode_frame,
558 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
561 AVCodec ff_vmdaudio_decoder = {
565 sizeof(VmdAudioContext),
566 vmdaudio_decode_init,
569 vmdaudio_decode_frame,
570 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),