Statistics
| Branch: | Revision:

ffmpeg / libavcodec / vmdav.c @ 2ac19b75

History | View | Annotate | Download (16.9 KB)

1
/*
2
 * Sierra VMD Audio & Video Decoders
3
 * Copyright (C) 2004 the ffmpeg project
4
 *
5
 * This file is part of FFmpeg.
6
 *
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.
11
 *
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.
16
 *
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
20
 */
21

    
22
/**
23
 * @file
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/
28
 *
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.
34
 *
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.
40
 */
41

    
42
#include <stdio.h>
43
#include <stdlib.h>
44
#include <string.h>
45

    
46
#include "libavutil/intreadwrite.h"
47
#include "avcodec.h"
48

    
49
#define VMD_HEADER_SIZE 0x330
50
#define PALETTE_COUNT 256
51

    
52
/*
53
 * Video Decoder
54
 */
55

    
56
typedef struct VmdVideoContext {
57

    
58
    AVCodecContext *avctx;
59
    AVFrame frame;
60
    AVFrame prev_frame;
61

    
62
    const unsigned char *buf;
63
    int size;
64

    
65
    unsigned char palette[PALETTE_COUNT * 4];
66
    unsigned char *unpack_buffer;
67
    int unpack_buffer_size;
68

    
69
    int x_off, y_off;
70
} VmdVideoContext;
71

    
72
#define QUEUE_SIZE 0x1000
73
#define QUEUE_MASK 0x0FFF
74

    
75
static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len)
76
{
77
    const unsigned char *s;
78
    unsigned char *d;
79
    unsigned char *d_end;
80
    unsigned char queue[QUEUE_SIZE];
81
    unsigned int qpos;
82
    unsigned int dataleft;
83
    unsigned int chainofs;
84
    unsigned int chainlen;
85
    unsigned int speclen;
86
    unsigned char tag;
87
    unsigned int i, j;
88

    
89
    s = src;
90
    d = dest;
91
    d_end = d + dest_len;
92
    dataleft = AV_RL32(s);
93
    s += 4;
94
    memset(queue, 0x20, QUEUE_SIZE);
95
    if (AV_RL32(s) == 0x56781234) {
96
        s += 4;
97
        qpos = 0x111;
98
        speclen = 0xF + 3;
99
    } else {
100
        qpos = 0xFEE;
101
        speclen = 100;  /* no speclen */
102
    }
103

    
104
    while (dataleft > 0) {
105
        tag = *s++;
106
        if ((tag == 0xFF) && (dataleft > 8)) {
107
            if (d + 8 > d_end)
108
                return;
109
            for (i = 0; i < 8; i++) {
110
                queue[qpos++] = *d++ = *s++;
111
                qpos &= QUEUE_MASK;
112
            }
113
            dataleft -= 8;
114
        } else {
115
            for (i = 0; i < 8; i++) {
116
                if (dataleft == 0)
117
                    break;
118
                if (tag & 0x01) {
119
                    if (d + 1 > d_end)
120
                        return;
121
                    queue[qpos++] = *d++ = *s++;
122
                    qpos &= QUEUE_MASK;
123
                    dataleft--;
124
                } else {
125
                    chainofs = *s++;
126
                    chainofs |= ((*s & 0xF0) << 4);
127
                    chainlen = (*s++ & 0x0F) + 3;
128
                    if (chainlen == speclen)
129
                        chainlen = *s++ + 0xF + 3;
130
                    if (d + chainlen > d_end)
131
                        return;
132
                    for (j = 0; j < chainlen; j++) {
133
                        *d = queue[chainofs++ & QUEUE_MASK];
134
                        queue[qpos++] = *d++;
135
                        qpos &= QUEUE_MASK;
136
                    }
137
                    dataleft -= chainlen;
138
                }
139
                tag >>= 1;
140
            }
141
        }
142
    }
143
}
144

    
145
static int rle_unpack(const unsigned char *src, unsigned char *dest,
146
    int src_len, int dest_len)
147
{
148
    const unsigned char *ps;
149
    unsigned char *pd;
150
    int i, l;
151
    unsigned char *dest_end = dest + dest_len;
152

    
153
    ps = src;
154
    pd = dest;
155
    if (src_len & 1)
156
        *pd++ = *ps++;
157

    
158
    src_len >>= 1;
159
    i = 0;
160
    do {
161
        l = *ps++;
162
        if (l & 0x80) {
163
            l = (l & 0x7F) * 2;
164
            if (pd + l > dest_end)
165
                return ps - src;
166
            memcpy(pd, ps, l);
167
            ps += l;
168
            pd += l;
169
        } else {
170
            if (pd + i > dest_end)
171
                return ps - src;
172
            for (i = 0; i < l; i++) {
173
                *pd++ = ps[0];
174
                *pd++ = ps[1];
175
            }
176
            ps += 2;
177
        }
178
        i += l;
179
    } while (i < src_len);
180

    
181
    return ps - src;
182
}
183

    
184
static void vmd_decode(VmdVideoContext *s)
185
{
186
    int i;
187
    unsigned int *palette32;
188
    unsigned char r, g, b;
189

    
190
    /* point to the start of the encoded data */
191
    const unsigned char *p = s->buf + 16;
192

    
193
    const unsigned char *pb;
194
    unsigned char meth;
195
    unsigned char *dp;   /* pointer to current frame */
196
    unsigned char *pp;   /* pointer to previous frame */
197
    unsigned char len;
198
    int ofs;
199

    
200
    int frame_x, frame_y;
201
    int frame_width, frame_height;
202
    int dp_size;
203

    
204
    frame_x = AV_RL16(&s->buf[6]);
205
    frame_y = AV_RL16(&s->buf[8]);
206
    frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
207
    frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
208

    
209
    if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
210
        (frame_x || frame_y)) {
211

    
212
        s->x_off = frame_x;
213
        s->y_off = frame_y;
214
    }
215
    frame_x -= s->x_off;
216
    frame_y -= s->y_off;
217

    
218
    /* if only a certain region will be updated, copy the entire previous
219
     * frame before the decode */
220
    if (frame_x || frame_y || (frame_width != s->avctx->width) ||
221
        (frame_height != s->avctx->height)) {
222

    
223
        memcpy(s->frame.data[0], s->prev_frame.data[0],
224
            s->avctx->height * s->frame.linesize[0]);
225
    }
226

    
227
    /* check if there is a new palette */
228
    if (s->buf[15] & 0x02) {
229
        p += 2;
230
        palette32 = (unsigned int *)s->palette;
231
        for (i = 0; i < PALETTE_COUNT; i++) {
232
            r = *p++ * 4;
233
            g = *p++ * 4;
234
            b = *p++ * 4;
235
            palette32[i] = (r << 16) | (g << 8) | (b);
236
        }
237
        s->size -= (256 * 3 + 2);
238
    }
239
    if (s->size >= 0) {
240
        /* originally UnpackFrame in VAG's code */
241
        pb = p;
242
        meth = *pb++;
243
        if (meth & 0x80) {
244
            lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
245
            meth &= 0x7F;
246
            pb = s->unpack_buffer;
247
        }
248

    
249
        dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
250
        dp_size = s->frame.linesize[0] * s->avctx->height;
251
        pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
252
        switch (meth) {
253
        case 1:
254
            for (i = 0; i < frame_height; i++) {
255
                ofs = 0;
256
                do {
257
                    len = *pb++;
258
                    if (len & 0x80) {
259
                        len = (len & 0x7F) + 1;
260
                        if (ofs + len > frame_width)
261
                            return;
262
                        memcpy(&dp[ofs], pb, len);
263
                        pb += len;
264
                        ofs += len;
265
                    } else {
266
                        /* interframe pixel copy */
267
                        if (ofs + len + 1 > frame_width)
268
                            return;
269
                        memcpy(&dp[ofs], &pp[ofs], len + 1);
270
                        ofs += len + 1;
271
                    }
272
                } while (ofs < frame_width);
273
                if (ofs > frame_width) {
274
                    av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
275
                        ofs, frame_width);
276
                    break;
277
                }
278
                dp += s->frame.linesize[0];
279
                pp += s->prev_frame.linesize[0];
280
            }
281
            break;
282

    
283
        case 2:
284
            for (i = 0; i < frame_height; i++) {
285
                memcpy(dp, pb, frame_width);
286
                pb += frame_width;
287
                dp += s->frame.linesize[0];
288
                pp += s->prev_frame.linesize[0];
289
            }
290
            break;
291

    
292
        case 3:
293
            for (i = 0; i < frame_height; i++) {
294
                ofs = 0;
295
                do {
296
                    len = *pb++;
297
                    if (len & 0x80) {
298
                        len = (len & 0x7F) + 1;
299
                        if (*pb++ == 0xFF)
300
                            len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
301
                        else
302
                            memcpy(&dp[ofs], pb, len);
303
                        pb += len;
304
                        ofs += len;
305
                    } else {
306
                        /* interframe pixel copy */
307
                        if (ofs + len + 1 > frame_width)
308
                            return;
309
                        memcpy(&dp[ofs], &pp[ofs], len + 1);
310
                        ofs += len + 1;
311
                    }
312
                } while (ofs < frame_width);
313
                if (ofs > frame_width) {
314
                    av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
315
                        ofs, frame_width);
316
                }
317
                dp += s->frame.linesize[0];
318
                pp += s->prev_frame.linesize[0];
319
            }
320
            break;
321
        }
322
    }
323
}
324

    
325
static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
326
{
327
    VmdVideoContext *s = avctx->priv_data;
328
    int i;
329
    unsigned int *palette32;
330
    int palette_index = 0;
331
    unsigned char r, g, b;
332
    unsigned char *vmd_header;
333
    unsigned char *raw_palette;
334

    
335
    s->avctx = avctx;
336
    avctx->pix_fmt = PIX_FMT_PAL8;
337

    
338
    /* make sure the VMD header made it */
339
    if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
340
        av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
341
            VMD_HEADER_SIZE);
342
        return -1;
343
    }
344
    vmd_header = (unsigned char *)avctx->extradata;
345

    
346
    s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
347
    s->unpack_buffer = av_malloc(s->unpack_buffer_size);
348
    if (!s->unpack_buffer)
349
        return -1;
350

    
351
    /* load up the initial palette */
352
    raw_palette = &vmd_header[28];
353
    palette32 = (unsigned int *)s->palette;
354
    for (i = 0; i < PALETTE_COUNT; i++) {
355
        r = raw_palette[palette_index++] * 4;
356
        g = raw_palette[palette_index++] * 4;
357
        b = raw_palette[palette_index++] * 4;
358
        palette32[i] = (r << 16) | (g << 8) | (b);
359
    }
360

    
361
    return 0;
362
}
363

    
364
static int vmdvideo_decode_frame(AVCodecContext *avctx,
365
                                 void *data, int *data_size,
366
                                 AVPacket *avpkt)
367
{
368
    const uint8_t *buf = avpkt->data;
369
    int buf_size = avpkt->size;
370
    VmdVideoContext *s = avctx->priv_data;
371

    
372
    s->buf = buf;
373
    s->size = buf_size;
374

    
375
    if (buf_size < 16)
376
        return buf_size;
377

    
378
    s->frame.reference = 1;
379
    if (avctx->get_buffer(avctx, &s->frame)) {
380
        av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
381
        return -1;
382
    }
383

    
384
    vmd_decode(s);
385

    
386
    /* make the palette available on the way out */
387
    memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
388

    
389
    /* shuffle frames */
390
    FFSWAP(AVFrame, s->frame, s->prev_frame);
391
    if (s->frame.data[0])
392
        avctx->release_buffer(avctx, &s->frame);
393

    
394
    *data_size = sizeof(AVFrame);
395
    *(AVFrame*)data = s->prev_frame;
396

    
397
    /* report that the buffer was completely consumed */
398
    return buf_size;
399
}
400

    
401
static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
402
{
403
    VmdVideoContext *s = avctx->priv_data;
404

    
405
    if (s->prev_frame.data[0])
406
        avctx->release_buffer(avctx, &s->prev_frame);
407
    av_free(s->unpack_buffer);
408

    
409
    return 0;
410
}
411

    
412

    
413
/*
414
 * Audio Decoder
415
 */
416

    
417
typedef struct VmdAudioContext {
418
    AVCodecContext *avctx;
419
    int channels;
420
    int bits;
421
    int block_align;
422
    int predictors[2];
423
} VmdAudioContext;
424

    
425
static const uint16_t vmdaudio_table[128] = {
426
    0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
427
    0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
428
    0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
429
    0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
430
    0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
431
    0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
432
    0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
433
    0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
434
    0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
435
    0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
436
    0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
437
    0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
438
    0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
439
};
440

    
441
static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
442
{
443
    VmdAudioContext *s = avctx->priv_data;
444

    
445
    s->avctx = avctx;
446
    s->channels = avctx->channels;
447
    s->bits = avctx->bits_per_coded_sample;
448
    s->block_align = avctx->block_align;
449
    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
450

    
451
    av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
452
            s->channels, s->bits, s->block_align, avctx->sample_rate);
453

    
454
    return 0;
455
}
456

    
457
static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
458
    const uint8_t *buf, int buf_size, int stereo)
459
{
460
    int i;
461
    int chan = 0;
462
    int16_t *out = (int16_t*)data;
463

    
464
    for(i = 0; i < buf_size; i++) {
465
        if(buf[i] & 0x80)
466
            s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
467
        else
468
            s->predictors[chan] += vmdaudio_table[buf[i]];
469
        s->predictors[chan] = av_clip_int16(s->predictors[chan]);
470
        out[i] = s->predictors[chan];
471
        chan ^= stereo;
472
    }
473
}
474

    
475
static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
476
    const uint8_t *buf, int silence, int data_size)
477
{
478
    int i;
479

    
480
//    if (silence)
481
//        av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
482

    
483
        if (silence) {
484
            memset(data, 0, data_size * 2);
485
        } else {
486
            if (s->bits == 16)
487
                vmdaudio_decode_audio(s, data, buf, data_size, s->channels == 2);
488
            else {
489
                /* copy the data but convert it to signed */
490
                for (i = 0; i < data_size; i++){
491
                    *data++ = buf[i] + 0x80;
492
                    *data++ = buf[i] + 0x80;
493
                }
494
            }
495
        }
496

    
497
    return data_size * 2;
498
}
499

    
500
static int vmdaudio_decode_frame(AVCodecContext *avctx,
501
                                 void *data, int *data_size,
502
                                 AVPacket *avpkt)
503
{
504
    const uint8_t *buf = avpkt->data;
505
    int buf_size = avpkt->size;
506
    VmdAudioContext *s = avctx->priv_data;
507
    unsigned char *output_samples = (unsigned char *)data;
508

    
509
    /* point to the start of the encoded data */
510
    const unsigned char *p = buf + 16;
511

    
512
    if (buf_size < 16)
513
        return buf_size;
514

    
515
    if (buf[6] == 1) {
516
        /* the chunk contains audio */
517
        *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16);
518
    } else if (buf[6] == 2) {
519
        /* initial chunk, may contain audio and silence */
520
        uint32_t flags = AV_RB32(p);
521
        int raw_block_size = s->block_align *
522
                             (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8);
523
        int silent_chunks;
524
        if(flags == 0xFFFFFFFF)
525
            silent_chunks = 32;
526
        else
527
            silent_chunks = av_log2(flags + 1);
528
        if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2)
529
            return -1;
530
        *data_size = 0;
531
        memset(output_samples, 0, raw_block_size * silent_chunks);
532
        output_samples += raw_block_size * silent_chunks;
533
        *data_size = raw_block_size * silent_chunks;
534
        *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20);
535
    } else if (buf[6] == 3) {
536
        /* silent chunk */
537
        *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0);
538
    }
539

    
540
    return buf_size;
541
}
542

    
543

    
544
/*
545
 * Public Data Structures
546
 */
547

    
548
AVCodec ff_vmdvideo_decoder = {
549
    "vmdvideo",
550
    AVMEDIA_TYPE_VIDEO,
551
    CODEC_ID_VMDVIDEO,
552
    sizeof(VmdVideoContext),
553
    vmdvideo_decode_init,
554
    NULL,
555
    vmdvideo_decode_end,
556
    vmdvideo_decode_frame,
557
    CODEC_CAP_DR1,
558
    .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
559
};
560

    
561
AVCodec ff_vmdaudio_decoder = {
562
    "vmdaudio",
563
    AVMEDIA_TYPE_AUDIO,
564
    CODEC_ID_VMDAUDIO,
565
    sizeof(VmdAudioContext),
566
    vmdaudio_decode_init,
567
    NULL,
568
    NULL,
569
    vmdaudio_decode_frame,
570
    .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
571
};