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.
50 #define VMD_HEADER_SIZE 0x330
51 #define PALETTE_COUNT 256
57 typedef struct VmdVideoContext {
59 AVCodecContext *avctx;
67 unsigned char palette[PALETTE_COUNT * 4];
68 unsigned char *unpack_buffer;
69 int unpack_buffer_size;
74 #define QUEUE_SIZE 0x1000
75 #define QUEUE_MASK 0x0FFF
77 static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len)
82 unsigned char queue[QUEUE_SIZE];
84 unsigned int dataleft;
85 unsigned int chainofs;
86 unsigned int chainlen;
94 dataleft = AV_RL32(s);
96 memset(queue, 0x20, QUEUE_SIZE);
97 if (AV_RL32(s) == 0x56781234) {
103 speclen = 100; /* no speclen */
106 while (dataleft > 0) {
108 if ((tag == 0xFF) && (dataleft > 8)) {
111 for (i = 0; i < 8; i++) {
112 queue[qpos++] = *d++ = *s++;
117 for (i = 0; i < 8; i++) {
123 queue[qpos++] = *d++ = *s++;
128 chainofs |= ((*s & 0xF0) << 4);
129 chainlen = (*s++ & 0x0F) + 3;
130 if (chainlen == speclen)
131 chainlen = *s++ + 0xF + 3;
132 if (d + chainlen > d_end)
134 for (j = 0; j < chainlen; j++) {
135 *d = queue[chainofs++ & QUEUE_MASK];
136 queue[qpos++] = *d++;
139 dataleft -= chainlen;
147 static int rle_unpack(unsigned char *src, unsigned char *dest,
148 int src_len, int dest_len)
153 unsigned char *dest_end = dest + dest_len;
166 if (pd + l > dest_end)
172 if (pd + i > dest_end)
174 for (i = 0; i < l; i++) {
181 } while (i < src_len);
186 static void vmd_decode(VmdVideoContext *s)
189 unsigned int *palette32;
190 unsigned char r, g, b;
192 /* point to the start of the encoded data */
193 unsigned char *p = s->buf + 16;
197 unsigned char *dp; /* pointer to current frame */
198 unsigned char *pp; /* pointer to previous frame */
202 int frame_x, frame_y;
203 int frame_width, frame_height;
206 frame_x = AV_RL16(&s->buf[6]);
207 frame_y = AV_RL16(&s->buf[8]);
208 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
209 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
211 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
212 (frame_x || frame_y)) {
220 /* if only a certain region will be updated, copy the entire previous
221 * frame before the decode */
222 if (frame_x || frame_y || (frame_width != s->avctx->width) ||
223 (frame_height != s->avctx->height)) {
225 memcpy(s->frame.data[0], s->prev_frame.data[0],
226 s->avctx->height * s->frame.linesize[0]);
229 /* check if there is a new palette */
230 if (s->buf[15] & 0x02) {
232 palette32 = (unsigned int *)s->palette;
233 for (i = 0; i < PALETTE_COUNT; i++) {
237 palette32[i] = (r << 16) | (g << 8) | (b);
239 s->size -= (256 * 3 + 2);
242 /* originally UnpackFrame in VAG's code */
246 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
248 pb = s->unpack_buffer;
251 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
252 dp_size = s->frame.linesize[0] * s->avctx->height;
253 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
256 for (i = 0; i < frame_height; i++) {
261 len = (len & 0x7F) + 1;
262 if (ofs + len > frame_width)
264 memcpy(&dp[ofs], pb, len);
268 /* interframe pixel copy */
269 if (ofs + len + 1 > frame_width)
271 memcpy(&dp[ofs], &pp[ofs], len + 1);
274 } while (ofs < frame_width);
275 if (ofs > frame_width) {
276 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
280 dp += s->frame.linesize[0];
281 pp += s->prev_frame.linesize[0];
286 for (i = 0; i < frame_height; i++) {
287 memcpy(dp, pb, frame_width);
289 dp += s->frame.linesize[0];
290 pp += s->prev_frame.linesize[0];
295 for (i = 0; i < frame_height; i++) {
300 len = (len & 0x7F) + 1;
302 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
304 memcpy(&dp[ofs], pb, len);
308 /* interframe pixel copy */
309 if (ofs + len + 1 > frame_width)
311 memcpy(&dp[ofs], &pp[ofs], len + 1);
314 } while (ofs < frame_width);
315 if (ofs > frame_width) {
316 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
319 dp += s->frame.linesize[0];
320 pp += s->prev_frame.linesize[0];
327 static int vmdvideo_decode_init(AVCodecContext *avctx)
329 VmdVideoContext *s = avctx->priv_data;
331 unsigned int *palette32;
332 int palette_index = 0;
333 unsigned char r, g, b;
334 unsigned char *vmd_header;
335 unsigned char *raw_palette;
338 avctx->pix_fmt = PIX_FMT_PAL8;
339 dsputil_init(&s->dsp, avctx);
341 /* make sure the VMD header made it */
342 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
343 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
347 vmd_header = (unsigned char *)avctx->extradata;
349 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
350 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
351 if (!s->unpack_buffer)
354 /* load up the initial palette */
355 raw_palette = &vmd_header[28];
356 palette32 = (unsigned int *)s->palette;
357 for (i = 0; i < PALETTE_COUNT; i++) {
358 r = raw_palette[palette_index++] * 4;
359 g = raw_palette[palette_index++] * 4;
360 b = raw_palette[palette_index++] * 4;
361 palette32[i] = (r << 16) | (g << 8) | (b);
364 s->frame.data[0] = s->prev_frame.data[0] = NULL;
369 static int vmdvideo_decode_frame(AVCodecContext *avctx,
370 void *data, int *data_size,
371 uint8_t *buf, int buf_size)
373 VmdVideoContext *s = avctx->priv_data;
381 s->frame.reference = 1;
382 if (avctx->get_buffer(avctx, &s->frame)) {
383 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
389 /* make the palette available on the way out */
390 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
393 FFSWAP(AVFrame, s->frame, s->prev_frame);
394 if (s->frame.data[0])
395 avctx->release_buffer(avctx, &s->frame);
397 *data_size = sizeof(AVFrame);
398 *(AVFrame*)data = s->prev_frame;
400 /* report that the buffer was completely consumed */
404 static int vmdvideo_decode_end(AVCodecContext *avctx)
406 VmdVideoContext *s = avctx->priv_data;
408 if (s->prev_frame.data[0])
409 avctx->release_buffer(avctx, &s->prev_frame);
410 av_free(s->unpack_buffer);
420 typedef struct VmdAudioContext {
421 AVCodecContext *avctx;
428 static uint16_t vmdaudio_table[128] = {
429 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
430 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
431 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
432 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
433 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
434 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
435 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
436 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
437 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
438 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
439 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
440 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
441 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
444 static int vmdaudio_decode_init(AVCodecContext *avctx)
446 VmdAudioContext *s = avctx->priv_data;
449 s->channels = avctx->channels;
450 s->bits = avctx->bits_per_sample;
451 s->block_align = avctx->block_align;
453 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
454 s->channels, s->bits, s->block_align, avctx->sample_rate);
459 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
460 uint8_t *buf, int stereo)
464 int16_t *out = (int16_t*)data;
466 for(i = 0; i < s->block_align; i++) {
468 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
470 s->predictors[chan] += vmdaudio_table[buf[i]];
471 s->predictors[chan] = av_clip_int16(s->predictors[chan]);
472 out[i] = s->predictors[chan];
477 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
478 uint8_t *buf, int silence)
480 int bytes_decoded = 0;
484 // av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
485 if (s->channels == 2) {
487 /* stereo handling */
489 memset(data, 0, s->block_align * 2);
492 vmdaudio_decode_audio(s, data, buf, 1);
494 /* copy the data but convert it to signed */
495 for (i = 0; i < s->block_align; i++){
496 *data++ = buf[i] + 0x80;
497 *data++ = buf[i] + 0x80;
502 bytes_decoded = s->block_align * 2;
506 memset(data, 0, s->block_align * 2);
509 vmdaudio_decode_audio(s, data, buf, 0);
511 /* copy the data but convert it to signed */
512 for (i = 0; i < s->block_align; i++){
513 *data++ = buf[i] + 0x80;
514 *data++ = buf[i] + 0x80;
520 return s->block_align * 2;
523 static int vmdaudio_decode_frame(AVCodecContext *avctx,
524 void *data, int *data_size,
525 uint8_t *buf, int buf_size)
527 VmdAudioContext *s = avctx->priv_data;
528 unsigned char *output_samples = (unsigned char *)data;
530 /* point to the start of the encoded data */
531 unsigned char *p = buf + 16;
537 /* the chunk contains audio */
538 *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
539 } else if (buf[6] == 2) {
540 /* the chunk may contain audio */
542 *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
543 output_samples += (s->block_align * s->bits / 8);
544 } else if (buf[6] == 3) {
546 *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
554 * Public Data Structures
557 AVCodec vmdvideo_decoder = {
561 sizeof(VmdVideoContext),
562 vmdvideo_decode_init,
565 vmdvideo_decode_frame,
569 AVCodec vmdaudio_decoder = {
573 sizeof(VmdAudioContext),
574 vmdaudio_decode_init,
577 vmdaudio_decode_frame,