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.
51 #define VMD_HEADER_SIZE 0x330
52 #define PALETTE_COUNT 256
58 typedef struct VmdVideoContext {
60 AVCodecContext *avctx;
68 unsigned char palette[PALETTE_COUNT * 4];
69 unsigned char *unpack_buffer;
70 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 only a certain region will be updated, copy the entire previous
212 * frame before the decode */
213 if (frame_x || frame_y || (frame_width != s->avctx->width) ||
214 (frame_height != s->avctx->height)) {
216 memcpy(s->frame.data[0], s->prev_frame.data[0],
217 s->avctx->height * s->frame.linesize[0]);
220 /* check if there is a new palette */
221 if (s->buf[15] & 0x02) {
223 palette32 = (unsigned int *)s->palette;
224 for (i = 0; i < PALETTE_COUNT; i++) {
228 palette32[i] = (r << 16) | (g << 8) | (b);
230 s->size -= (256 * 3 + 2);
233 /* originally UnpackFrame in VAG's code */
237 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
239 pb = s->unpack_buffer;
242 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
243 dp_size = s->frame.linesize[0] * s->avctx->height;
244 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
247 for (i = 0; i < frame_height; i++) {
252 len = (len & 0x7F) + 1;
253 if (ofs + len > frame_width)
255 memcpy(&dp[ofs], pb, len);
259 /* interframe pixel copy */
260 if (ofs + len + 1 > frame_width)
262 memcpy(&dp[ofs], &pp[ofs], len + 1);
265 } while (ofs < frame_width);
266 if (ofs > frame_width) {
267 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
271 dp += s->frame.linesize[0];
272 pp += s->prev_frame.linesize[0];
277 for (i = 0; i < frame_height; i++) {
278 memcpy(dp, pb, frame_width);
280 dp += s->frame.linesize[0];
281 pp += s->prev_frame.linesize[0];
286 for (i = 0; i < frame_height; i++) {
291 len = (len & 0x7F) + 1;
293 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
295 memcpy(&dp[ofs], pb, len);
299 /* interframe pixel copy */
300 if (ofs + len + 1 > frame_width)
302 memcpy(&dp[ofs], &pp[ofs], len + 1);
305 } while (ofs < frame_width);
306 if (ofs > frame_width) {
307 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
310 dp += s->frame.linesize[0];
311 pp += s->prev_frame.linesize[0];
318 static int vmdvideo_decode_init(AVCodecContext *avctx)
320 VmdVideoContext *s = avctx->priv_data;
322 unsigned int *palette32;
323 int palette_index = 0;
324 unsigned char r, g, b;
325 unsigned char *vmd_header;
326 unsigned char *raw_palette;
329 avctx->pix_fmt = PIX_FMT_PAL8;
330 dsputil_init(&s->dsp, avctx);
332 /* make sure the VMD header made it */
333 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
334 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
338 vmd_header = (unsigned char *)avctx->extradata;
340 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
341 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
342 if (!s->unpack_buffer)
345 /* load up the initial palette */
346 raw_palette = &vmd_header[28];
347 palette32 = (unsigned int *)s->palette;
348 for (i = 0; i < PALETTE_COUNT; i++) {
349 r = raw_palette[palette_index++] * 4;
350 g = raw_palette[palette_index++] * 4;
351 b = raw_palette[palette_index++] * 4;
352 palette32[i] = (r << 16) | (g << 8) | (b);
355 s->frame.data[0] = s->prev_frame.data[0] = NULL;
360 static int vmdvideo_decode_frame(AVCodecContext *avctx,
361 void *data, int *data_size,
362 uint8_t *buf, int buf_size)
364 VmdVideoContext *s = avctx->priv_data;
372 s->frame.reference = 1;
373 if (avctx->get_buffer(avctx, &s->frame)) {
374 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
380 /* make the palette available on the way out */
381 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
384 FFSWAP(AVFrame, s->frame, s->prev_frame);
385 if (s->frame.data[0])
386 avctx->release_buffer(avctx, &s->frame);
388 *data_size = sizeof(AVFrame);
389 *(AVFrame*)data = s->prev_frame;
391 /* report that the buffer was completely consumed */
395 static int vmdvideo_decode_end(AVCodecContext *avctx)
397 VmdVideoContext *s = avctx->priv_data;
399 if (s->prev_frame.data[0])
400 avctx->release_buffer(avctx, &s->prev_frame);
401 av_free(s->unpack_buffer);
411 typedef struct VmdAudioContext {
412 AVCodecContext *avctx;
419 static uint16_t vmdaudio_table[128] = {
420 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
421 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
422 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
423 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
424 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
425 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
426 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
427 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
428 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
429 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
430 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
431 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
432 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
435 static int vmdaudio_decode_init(AVCodecContext *avctx)
437 VmdAudioContext *s = avctx->priv_data;
440 s->channels = avctx->channels;
441 s->bits = avctx->bits_per_sample;
442 s->block_align = avctx->block_align;
444 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
445 s->channels, s->bits, s->block_align, avctx->sample_rate);
450 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
451 uint8_t *buf, int stereo)
455 int16_t *out = (int16_t*)data;
457 for(i = 0; i < s->block_align; i++) {
459 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
461 s->predictors[chan] += vmdaudio_table[buf[i]];
462 s->predictors[chan] = av_clip(s->predictors[chan], -32768, 32767);
463 out[i] = s->predictors[chan];
468 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
469 uint8_t *buf, int silence)
471 int bytes_decoded = 0;
475 // av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
476 if (s->channels == 2) {
478 /* stereo handling */
480 memset(data, 0, s->block_align * 2);
483 vmdaudio_decode_audio(s, data, buf, 1);
485 /* copy the data but convert it to signed */
486 for (i = 0; i < s->block_align; i++){
487 *data++ = buf[i] + 0x80;
488 *data++ = buf[i] + 0x80;
493 bytes_decoded = s->block_align * 2;
497 memset(data, 0, s->block_align * 2);
500 vmdaudio_decode_audio(s, data, buf, 0);
502 /* copy the data but convert it to signed */
503 for (i = 0; i < s->block_align; i++){
504 *data++ = buf[i] + 0x80;
505 *data++ = buf[i] + 0x80;
511 return s->block_align * 2;
514 static int vmdaudio_decode_frame(AVCodecContext *avctx,
515 void *data, int *data_size,
516 uint8_t *buf, int buf_size)
518 VmdAudioContext *s = avctx->priv_data;
519 unsigned char *output_samples = (unsigned char *)data;
521 /* point to the start of the encoded data */
522 unsigned char *p = buf + 16;
528 /* the chunk contains audio */
529 *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
530 } else if (buf[6] == 2) {
531 /* the chunk may contain audio */
533 *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
534 output_samples += (s->block_align * s->bits / 8);
535 } else if (buf[6] == 3) {
537 *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
545 * Public Data Structures
548 AVCodec vmdvideo_decoder = {
552 sizeof(VmdVideoContext),
553 vmdvideo_decode_init,
556 vmdvideo_decode_frame,
560 AVCodec vmdaudio_decoder = {
564 sizeof(VmdAudioContext),
565 vmdaudio_decode_init,
568 vmdaudio_decode_frame,