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
25 * Sierra VMD audio & video decoders
26 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
27 * for more information on the Sierra VMD format, visit:
28 * http://www.pcisys.net/~melanson/codecs/
30 * The video decoder outputs PAL8 colorspace data. The decoder expects
31 * a 0x330-byte VMD file header to be transmitted via extradata during
32 * codec initialization. Each encoded frame that is sent to this decoder
33 * is expected to be prepended with the appropriate 16-byte frame
34 * information record from the VMD file.
36 * The audio decoder, like the video decoder, expects each encoded data
37 * chunk to be prepended with the appropriate 16-byte frame information
38 * record from the VMD file. It does not require the 0x330-byte VMD file
39 * header, but it does need the audio setup parameters passed in through
40 * normal libavcodec API means.
52 #define VMD_HEADER_SIZE 0x330
53 #define PALETTE_COUNT 256
59 typedef struct VmdVideoContext {
61 AVCodecContext *avctx;
69 unsigned char palette[PALETTE_COUNT * 4];
70 unsigned char *unpack_buffer;
71 int unpack_buffer_size;
75 #define QUEUE_SIZE 0x1000
76 #define QUEUE_MASK 0x0FFF
78 static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len)
83 unsigned char queue[QUEUE_SIZE];
85 unsigned int dataleft;
86 unsigned int chainofs;
87 unsigned int chainlen;
97 memset(queue, 0x20, QUEUE_SIZE);
98 if (LE_32(s) == 0x56781234) {
104 speclen = 100; /* no speclen */
107 while (dataleft > 0) {
109 if ((tag == 0xFF) && (dataleft > 8)) {
112 for (i = 0; i < 8; i++) {
113 queue[qpos++] = *d++ = *s++;
118 for (i = 0; i < 8; i++) {
124 queue[qpos++] = *d++ = *s++;
129 chainofs |= ((*s & 0xF0) << 4);
130 chainlen = (*s++ & 0x0F) + 3;
131 if (chainlen == speclen)
132 chainlen = *s++ + 0xF + 3;
133 if (d + chainlen > d_end)
135 for (j = 0; j < chainlen; j++) {
136 *d = queue[chainofs++ & QUEUE_MASK];
137 queue[qpos++] = *d++;
140 dataleft -= chainlen;
148 static int rle_unpack(unsigned char *src, unsigned char *dest,
149 int src_len, int dest_len)
154 unsigned char *dest_end = dest + dest_len;
167 if (pd + l > dest_end)
173 if (pd + i > dest_end)
175 for (i = 0; i < l; i++) {
182 } while (i < src_len);
187 static void vmd_decode(VmdVideoContext *s)
190 unsigned int *palette32;
191 unsigned char r, g, b;
193 /* point to the start of the encoded data */
194 unsigned char *p = s->buf + 16;
198 unsigned char *dp; /* pointer to current frame */
199 unsigned char *pp; /* pointer to previous frame */
203 int frame_x, frame_y;
204 int frame_width, frame_height;
207 frame_x = LE_16(&s->buf[6]);
208 frame_y = LE_16(&s->buf[8]);
209 frame_width = LE_16(&s->buf[10]) - frame_x + 1;
210 frame_height = LE_16(&s->buf[12]) - frame_y + 1;
212 /* if only a certain region will be updated, copy the entire previous
213 * frame before the decode */
214 if (frame_x || frame_y || (frame_width != s->avctx->width) ||
215 (frame_height != s->avctx->height)) {
217 memcpy(s->frame.data[0], s->prev_frame.data[0],
218 s->avctx->height * s->frame.linesize[0]);
221 /* check if there is a new palette */
222 if (s->buf[15] & 0x02) {
224 palette32 = (unsigned int *)s->palette;
225 for (i = 0; i < PALETTE_COUNT; i++) {
229 palette32[i] = (r << 16) | (g << 8) | (b);
231 s->size -= (256 * 3 + 2);
234 /* originally UnpackFrame in VAG's code */
238 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
240 pb = s->unpack_buffer;
243 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
244 dp_size = s->frame.linesize[0] * s->avctx->height;
245 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
248 for (i = 0; i < frame_height; i++) {
253 len = (len & 0x7F) + 1;
254 if (ofs + len > frame_width)
256 memcpy(&dp[ofs], pb, len);
260 /* interframe pixel copy */
261 if (ofs + len + 1 > frame_width)
263 memcpy(&dp[ofs], &pp[ofs], len + 1);
266 } while (ofs < frame_width);
267 if (ofs > frame_width) {
268 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
272 dp += s->frame.linesize[0];
273 pp += s->prev_frame.linesize[0];
278 for (i = 0; i < frame_height; i++) {
279 memcpy(dp, pb, frame_width);
281 dp += s->frame.linesize[0];
282 pp += s->prev_frame.linesize[0];
287 for (i = 0; i < frame_height; i++) {
292 len = (len & 0x7F) + 1;
294 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
296 memcpy(&dp[ofs], pb, len);
300 /* interframe pixel copy */
301 if (ofs + len + 1 > frame_width)
303 memcpy(&dp[ofs], &pp[ofs], len + 1);
306 } while (ofs < frame_width);
307 if (ofs > frame_width) {
308 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
311 dp += s->frame.linesize[0];
312 pp += s->prev_frame.linesize[0];
319 static int vmdvideo_decode_init(AVCodecContext *avctx)
321 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
323 unsigned int *palette32;
324 int palette_index = 0;
325 unsigned char r, g, b;
326 unsigned char *vmd_header;
327 unsigned char *raw_palette;
330 avctx->pix_fmt = PIX_FMT_PAL8;
331 avctx->has_b_frames = 0;
332 dsputil_init(&s->dsp, avctx);
334 /* make sure the VMD header made it */
335 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
336 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
340 vmd_header = (unsigned char *)avctx->extradata;
342 s->unpack_buffer_size = LE_32(&vmd_header[800]);
343 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
344 if (!s->unpack_buffer)
347 /* load up the initial palette */
348 raw_palette = &vmd_header[28];
349 palette32 = (unsigned int *)s->palette;
350 for (i = 0; i < PALETTE_COUNT; i++) {
351 r = raw_palette[palette_index++] * 4;
352 g = raw_palette[palette_index++] * 4;
353 b = raw_palette[palette_index++] * 4;
354 palette32[i] = (r << 16) | (g << 8) | (b);
357 s->frame.data[0] = s->prev_frame.data[0] = NULL;
362 static int vmdvideo_decode_frame(AVCodecContext *avctx,
363 void *data, int *data_size,
364 uint8_t *buf, int buf_size)
366 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
374 s->frame.reference = 1;
375 if (avctx->get_buffer(avctx, &s->frame)) {
376 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
382 /* make the palette available on the way out */
383 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
385 if (s->prev_frame.data[0])
386 avctx->release_buffer(avctx, &s->prev_frame);
389 s->prev_frame = s->frame;
391 *data_size = sizeof(AVFrame);
392 *(AVFrame*)data = s->frame;
394 /* report that the buffer was completely consumed */
398 static int vmdvideo_decode_end(AVCodecContext *avctx)
400 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
402 if (s->prev_frame.data[0])
403 avctx->release_buffer(avctx, &s->prev_frame);
404 av_free(s->unpack_buffer);
414 typedef struct VmdAudioContext {
415 AVCodecContext *avctx;
422 static uint16_t vmdaudio_table[128] = {
423 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
424 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
425 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
426 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
427 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
428 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
429 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
430 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
431 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
432 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
433 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
434 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
435 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
438 static int vmdaudio_decode_init(AVCodecContext *avctx)
440 VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
443 s->channels = avctx->channels;
444 s->bits = avctx->bits_per_sample;
445 s->block_align = avctx->block_align;
447 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
448 s->channels, s->bits, s->block_align, avctx->sample_rate);
453 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
454 uint8_t *buf, int stereo)
458 int16_t *out = (int16_t*)data;
460 for(i = 0; i < s->block_align; i++) {
462 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
464 s->predictors[chan] += vmdaudio_table[buf[i]];
465 s->predictors[chan] = clip(s->predictors[chan], -32768, 32767);
466 out[i] = s->predictors[chan];
471 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
472 uint8_t *buf, int silence)
474 int bytes_decoded = 0;
478 // av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
479 if (s->channels == 2) {
481 /* stereo handling */
483 memset(data, 0, s->block_align * 2);
486 vmdaudio_decode_audio(s, data, buf, 1);
488 /* copy the data but convert it to signed */
489 for (i = 0; i < s->block_align; i++){
490 *data++ = buf[i] + 0x80;
491 *data++ = buf[i] + 0x80;
496 bytes_decoded = s->block_align * 2;
500 memset(data, 0, s->block_align * 2);
503 vmdaudio_decode_audio(s, data, buf, 0);
505 /* copy the data but convert it to signed */
506 for (i = 0; i < s->block_align; i++){
507 *data++ = buf[i] + 0x80;
508 *data++ = buf[i] + 0x80;
514 return s->block_align * 2;
517 static int vmdaudio_decode_frame(AVCodecContext *avctx,
518 void *data, int *data_size,
519 uint8_t *buf, int buf_size)
521 VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
522 unsigned char *output_samples = (unsigned char *)data;
524 /* point to the start of the encoded data */
525 unsigned char *p = buf + 16;
531 /* the chunk contains audio */
532 *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
533 } else if (buf[6] == 2) {
534 /* the chunk may contain audio */
536 *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
537 output_samples += (s->block_align * s->bits / 8);
538 } else if (buf[6] == 3) {
540 *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
548 * Public Data Structures
551 AVCodec vmdvideo_decoder = {
555 sizeof(VmdVideoContext),
556 vmdvideo_decode_init,
559 vmdvideo_decode_frame,
563 AVCodec vmdaudio_decoder = {
567 sizeof(VmdAudioContext),
568 vmdaudio_decode_init,
571 vmdaudio_decode_frame,