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;
73 #define QUEUE_SIZE 0x1000
74 #define QUEUE_MASK 0x0FFF
76 static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len)
81 unsigned char queue[QUEUE_SIZE];
83 unsigned int dataleft;
84 unsigned int chainofs;
85 unsigned int chainlen;
93 dataleft = AV_RL32(s);
95 memset(queue, 0x20, QUEUE_SIZE);
96 if (AV_RL32(s) == 0x56781234) {
102 speclen = 100; /* no speclen */
105 while (dataleft > 0) {
107 if ((tag == 0xFF) && (dataleft > 8)) {
110 for (i = 0; i < 8; i++) {
111 queue[qpos++] = *d++ = *s++;
116 for (i = 0; i < 8; i++) {
122 queue[qpos++] = *d++ = *s++;
127 chainofs |= ((*s & 0xF0) << 4);
128 chainlen = (*s++ & 0x0F) + 3;
129 if (chainlen == speclen)
130 chainlen = *s++ + 0xF + 3;
131 if (d + chainlen > d_end)
133 for (j = 0; j < chainlen; j++) {
134 *d = queue[chainofs++ & QUEUE_MASK];
135 queue[qpos++] = *d++;
138 dataleft -= chainlen;
146 static int rle_unpack(unsigned char *src, unsigned char *dest,
147 int src_len, int dest_len)
152 unsigned char *dest_end = dest + dest_len;
165 if (pd + l > dest_end)
171 if (pd + i > dest_end)
173 for (i = 0; i < l; i++) {
180 } while (i < src_len);
185 static void vmd_decode(VmdVideoContext *s)
188 unsigned int *palette32;
189 unsigned char r, g, b;
191 /* point to the start of the encoded data */
192 unsigned char *p = s->buf + 16;
196 unsigned char *dp; /* pointer to current frame */
197 unsigned char *pp; /* pointer to previous frame */
201 int frame_x, frame_y;
202 int frame_width, frame_height;
205 frame_x = AV_RL16(&s->buf[6]);
206 frame_y = AV_RL16(&s->buf[8]);
207 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
208 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
210 /* if only a certain region will be updated, copy the entire previous
211 * frame before the decode */
212 if (frame_x || frame_y || (frame_width != s->avctx->width) ||
213 (frame_height != s->avctx->height)) {
215 memcpy(s->frame.data[0], s->prev_frame.data[0],
216 s->avctx->height * s->frame.linesize[0]);
219 /* check if there is a new palette */
220 if (s->buf[15] & 0x02) {
222 palette32 = (unsigned int *)s->palette;
223 for (i = 0; i < PALETTE_COUNT; i++) {
227 palette32[i] = (r << 16) | (g << 8) | (b);
229 s->size -= (256 * 3 + 2);
232 /* originally UnpackFrame in VAG's code */
236 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
238 pb = s->unpack_buffer;
241 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
242 dp_size = s->frame.linesize[0] * s->avctx->height;
243 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
246 for (i = 0; i < frame_height; i++) {
251 len = (len & 0x7F) + 1;
252 if (ofs + len > frame_width)
254 memcpy(&dp[ofs], pb, len);
258 /* interframe pixel copy */
259 if (ofs + len + 1 > frame_width)
261 memcpy(&dp[ofs], &pp[ofs], len + 1);
264 } while (ofs < frame_width);
265 if (ofs > frame_width) {
266 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
270 dp += s->frame.linesize[0];
271 pp += s->prev_frame.linesize[0];
276 for (i = 0; i < frame_height; i++) {
277 memcpy(dp, pb, frame_width);
279 dp += s->frame.linesize[0];
280 pp += s->prev_frame.linesize[0];
285 for (i = 0; i < frame_height; i++) {
290 len = (len & 0x7F) + 1;
292 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
294 memcpy(&dp[ofs], pb, len);
298 /* interframe pixel copy */
299 if (ofs + len + 1 > frame_width)
301 memcpy(&dp[ofs], &pp[ofs], len + 1);
304 } while (ofs < frame_width);
305 if (ofs > frame_width) {
306 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
309 dp += s->frame.linesize[0];
310 pp += s->prev_frame.linesize[0];
317 static int vmdvideo_decode_init(AVCodecContext *avctx)
319 VmdVideoContext *s = avctx->priv_data;
321 unsigned int *palette32;
322 int palette_index = 0;
323 unsigned char r, g, b;
324 unsigned char *vmd_header;
325 unsigned char *raw_palette;
328 avctx->pix_fmt = PIX_FMT_PAL8;
329 dsputil_init(&s->dsp, avctx);
331 /* make sure the VMD header made it */
332 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
333 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
337 vmd_header = (unsigned char *)avctx->extradata;
339 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
340 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
341 if (!s->unpack_buffer)
344 /* load up the initial palette */
345 raw_palette = &vmd_header[28];
346 palette32 = (unsigned int *)s->palette;
347 for (i = 0; i < PALETTE_COUNT; i++) {
348 r = raw_palette[palette_index++] * 4;
349 g = raw_palette[palette_index++] * 4;
350 b = raw_palette[palette_index++] * 4;
351 palette32[i] = (r << 16) | (g << 8) | (b);
354 s->frame.data[0] = s->prev_frame.data[0] = NULL;
359 static int vmdvideo_decode_frame(AVCodecContext *avctx,
360 void *data, int *data_size,
361 uint8_t *buf, int buf_size)
363 VmdVideoContext *s = avctx->priv_data;
371 s->frame.reference = 1;
372 if (avctx->get_buffer(avctx, &s->frame)) {
373 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
379 /* make the palette available on the way out */
380 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
383 FFSWAP(AVFrame, s->frame, s->prev_frame);
384 if (s->frame.data[0])
385 avctx->release_buffer(avctx, &s->frame);
387 *data_size = sizeof(AVFrame);
388 *(AVFrame*)data = s->prev_frame;
390 /* report that the buffer was completely consumed */
394 static int vmdvideo_decode_end(AVCodecContext *avctx)
396 VmdVideoContext *s = avctx->priv_data;
398 if (s->prev_frame.data[0])
399 avctx->release_buffer(avctx, &s->prev_frame);
400 av_free(s->unpack_buffer);
410 typedef struct VmdAudioContext {
411 AVCodecContext *avctx;
418 static uint16_t vmdaudio_table[128] = {
419 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
420 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
421 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
422 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
423 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
424 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
425 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
426 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
427 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
428 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
429 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
430 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
431 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
434 static int vmdaudio_decode_init(AVCodecContext *avctx)
436 VmdAudioContext *s = avctx->priv_data;
439 s->channels = avctx->channels;
440 s->bits = avctx->bits_per_sample;
441 s->block_align = avctx->block_align;
443 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
444 s->channels, s->bits, s->block_align, avctx->sample_rate);
449 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
450 uint8_t *buf, int stereo)
454 int16_t *out = (int16_t*)data;
456 for(i = 0; i < s->block_align; i++) {
458 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
460 s->predictors[chan] += vmdaudio_table[buf[i]];
461 s->predictors[chan] = av_clip(s->predictors[chan], -32768, 32767);
462 out[i] = s->predictors[chan];
467 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
468 uint8_t *buf, int silence)
470 int bytes_decoded = 0;
474 // av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
475 if (s->channels == 2) {
477 /* stereo handling */
479 memset(data, 0, s->block_align * 2);
482 vmdaudio_decode_audio(s, data, buf, 1);
484 /* copy the data but convert it to signed */
485 for (i = 0; i < s->block_align; i++){
486 *data++ = buf[i] + 0x80;
487 *data++ = buf[i] + 0x80;
492 bytes_decoded = s->block_align * 2;
496 memset(data, 0, s->block_align * 2);
499 vmdaudio_decode_audio(s, data, buf, 0);
501 /* copy the data but convert it to signed */
502 for (i = 0; i < s->block_align; i++){
503 *data++ = buf[i] + 0x80;
504 *data++ = buf[i] + 0x80;
510 return s->block_align * 2;
513 static int vmdaudio_decode_frame(AVCodecContext *avctx,
514 void *data, int *data_size,
515 uint8_t *buf, int buf_size)
517 VmdAudioContext *s = avctx->priv_data;
518 unsigned char *output_samples = (unsigned char *)data;
520 /* point to the start of the encoded data */
521 unsigned char *p = buf + 16;
527 /* the chunk contains audio */
528 *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
529 } else if (buf[6] == 2) {
530 /* the chunk may contain audio */
532 *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
533 output_samples += (s->block_align * s->bits / 8);
534 } else if (buf[6] == 3) {
536 *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
544 * Public Data Structures
547 AVCodec vmdvideo_decoder = {
551 sizeof(VmdVideoContext),
552 vmdvideo_decode_init,
555 vmdvideo_decode_frame,
559 AVCodec vmdaudio_decoder = {
563 sizeof(VmdAudioContext),
564 vmdaudio_decode_init,
567 vmdaudio_decode_frame,