2
* Sierra VMD Audio & Video Decoders
3
* Copyright (C) 2004 the ffmpeg project
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
* Sierra VMD audio & video decoders
24
* by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
25
* for more information on the Sierra VMD format, visit:
26
* http://www.pcisys.net/~melanson/codecs/
28
* The video decoder outputs PAL8 colorspace data. The decoder expects
29
* a 0x330-byte VMD file header to be transmitted via extradata during
30
* codec initialization. Each encoded frame that is sent to this decoder
31
* is expected to be prepended with the appropriate 16-byte frame
32
* information record from the VMD file.
34
* The audio decoder, like the video decoder, expects each encoded data
35
* chunk to be prepended with the appropriate 16-byte frame information
36
* record from the VMD file. It does not require the 0x330-byte VMD file
37
* header, but it does need the audio setup parameters passed in through
38
* 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;
95
memset(queue, QUEUE_SIZE, 0x20);
96
if (LE_32(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 = LE_16(&s->buf[6]);
206
frame_y = LE_16(&s->buf[8]);
207
frame_width = LE_16(&s->buf[10]) - frame_x + 1;
208
frame_height = LE_16(&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 = (VmdVideoContext *)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
avctx->has_b_frames = 0;
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 = LE_32(&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 = (VmdVideoContext *)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);
383
if (s->prev_frame.data[0])
384
avctx->release_buffer(avctx, &s->prev_frame);
387
s->prev_frame = s->frame;
389
*data_size = sizeof(AVFrame);
390
*(AVFrame*)data = s->frame;
392
/* report that the buffer was completely consumed */
396
static int vmdvideo_decode_end(AVCodecContext *avctx)
398
VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
400
if (s->prev_frame.data[0])
401
avctx->release_buffer(avctx, &s->prev_frame);
402
av_free(s->unpack_buffer);
412
typedef struct VmdAudioContext {
413
AVCodecContext *avctx;
420
static uint16_t vmdaudio_table[128] = {
421
0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
422
0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
423
0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
424
0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
425
0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
426
0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
427
0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
428
0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
429
0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
430
0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
431
0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
432
0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
433
0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
436
static int vmdaudio_decode_init(AVCodecContext *avctx)
438
VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
441
s->channels = avctx->channels;
442
s->bits = avctx->bits_per_sample;
443
s->block_align = avctx->block_align;
445
av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
446
s->channels, s->bits, s->block_align, avctx->sample_rate);
451
static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
452
uint8_t *buf, int stereo)
456
int16_t *out = (int16_t*)data;
458
for(i = 0; i < s->block_align; i++) {
460
s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
462
s->predictors[chan] += vmdaudio_table[buf[i]];
463
s->predictors[chan] = clip(s->predictors[chan], -32768, 32767);
464
out[i] = s->predictors[chan];
469
static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
470
uint8_t *buf, int silence)
472
int bytes_decoded = 0;
476
// av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
477
if (s->channels == 2) {
479
/* stereo handling */
481
memset(data, 0, s->block_align * 2);
484
vmdaudio_decode_audio(s, data, buf, 1);
486
/* copy the data but convert it to signed */
487
for (i = 0; i < s->block_align; i++)
488
data[i * 2 + 1] = buf[i] + 0x80;
491
bytes_decoded = s->block_align * 2;
495
memset(data, 0, s->block_align * 2);
498
vmdaudio_decode_audio(s, data, buf, 0);
500
/* copy the data but convert it to signed */
501
for (i = 0; i < s->block_align; i++)
502
data[i * 2 + 1] = buf[i] + 0x80;
507
return s->block_align * 2;
510
static int vmdaudio_decode_frame(AVCodecContext *avctx,
511
void *data, int *data_size,
512
uint8_t *buf, int buf_size)
514
VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
515
unsigned int sound_flags;
516
unsigned char *output_samples = (unsigned char *)data;
518
/* point to the start of the encoded data */
519
unsigned char *p = buf + 16;
520
unsigned char *p_end = buf + buf_size;
526
/* the chunk contains audio */
527
*data_size = vmdaudio_loadsound(s, output_samples, p, 0);
528
} else if (buf[6] == 2) {
529
/* the chunk contains audio and silence mixed together */
530
sound_flags = LE_32(p);
533
/* do something with extrabufs here? */
536
if (sound_flags & 0x01)
538
*data_size += vmdaudio_loadsound(s, output_samples, p, 1);
541
*data_size += vmdaudio_loadsound(s, output_samples, p, 0);
544
output_samples += (s->block_align * s->bits / 8);
547
} else if (buf[6] == 3) {
549
*data_size = vmdaudio_loadsound(s, output_samples, p, 1);
557
* Public Data Structures
560
AVCodec vmdvideo_decoder = {
564
sizeof(VmdVideoContext),
565
vmdvideo_decode_init,
568
vmdvideo_decode_frame,
572
AVCodec vmdaudio_decoder = {
576
sizeof(VmdAudioContext),
577
vmdaudio_decode_init,
580
vmdaudio_decode_frame,