Statistics
| Branch: | Revision:

ffmpeg / libavcodec / vmdav.c @ b4b5e922

History | View | Annotate | Download (17.3 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
#define BLOCK_TYPE_AUDIO    1
418
#define BLOCK_TYPE_INITIAL  2
419
#define BLOCK_TYPE_SILENCE  3
420

    
421
typedef struct VmdAudioContext {
422
    AVCodecContext *avctx;
423
    int channels;
424
    int bits;
425
    int block_align;
426
    int predictors[2];
427
} VmdAudioContext;
428

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

    
445
static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
446
{
447
    VmdAudioContext *s = avctx->priv_data;
448

    
449
    s->avctx = avctx;
450
    s->channels = avctx->channels;
451
    s->bits = avctx->bits_per_coded_sample;
452
    s->block_align = avctx->block_align;
453
    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
454

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

    
458
    return 0;
459
}
460

    
461
static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
462
    const uint8_t *buf, int buf_size, int stereo)
463
{
464
    int i;
465
    int chan = 0;
466
    int16_t *out = (int16_t*)data;
467

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

    
479
static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
480
    const uint8_t *buf, int silence, int data_size)
481
{
482
    int i;
483

    
484
//    if (silence)
485
//        av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
486

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

    
501
    return data_size * 2;
502
}
503

    
504
static int vmdaudio_decode_frame(AVCodecContext *avctx,
505
                                 void *data, int *data_size,
506
                                 AVPacket *avpkt)
507
{
508
    const uint8_t *buf = avpkt->data;
509
    int buf_size = avpkt->size;
510
    VmdAudioContext *s = avctx->priv_data;
511
    int block_type;
512
    unsigned char *output_samples = (unsigned char *)data;
513

    
514
    /* point to the start of the encoded data */
515
    const unsigned char *p = buf + 16;
516

    
517
    if (buf_size < 16) {
518
        av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
519
        *data_size = 0;
520
        return buf_size;
521
    }
522

    
523
    block_type = buf[6];
524
    if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
525
        av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
526
        return AVERROR(EINVAL);
527
    }
528

    
529
    if (block_type == BLOCK_TYPE_AUDIO) {
530
        /* the chunk contains audio */
531
        *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16);
532
    } else if (block_type == BLOCK_TYPE_INITIAL) {
533
        /* initial chunk, may contain audio and silence */
534
        uint32_t flags = AV_RB32(p);
535
        int raw_block_size = s->block_align *
536
                             (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8);
537
        int silent_chunks = av_popcount(flags);
538
        if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2)
539
            return -1;
540
        *data_size = 0;
541
        memset(output_samples, 0, raw_block_size * silent_chunks);
542
        output_samples += raw_block_size * silent_chunks;
543
        *data_size = raw_block_size * silent_chunks;
544
        *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20);
545
    } else if (block_type == BLOCK_TYPE_SILENCE) {
546
        /* silent chunk */
547
        *data_size = vmdaudio_loadsound(s, output_samples, p, 1, s->block_align);
548
    }
549

    
550
    return buf_size;
551
}
552

    
553

    
554
/*
555
 * Public Data Structures
556
 */
557

    
558
AVCodec ff_vmdvideo_decoder = {
559
    "vmdvideo",
560
    AVMEDIA_TYPE_VIDEO,
561
    CODEC_ID_VMDVIDEO,
562
    sizeof(VmdVideoContext),
563
    vmdvideo_decode_init,
564
    NULL,
565
    vmdvideo_decode_end,
566
    vmdvideo_decode_frame,
567
    CODEC_CAP_DR1,
568
    .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
569
};
570

    
571
AVCodec ff_vmdaudio_decoder = {
572
    "vmdaudio",
573
    AVMEDIA_TYPE_AUDIO,
574
    CODEC_ID_VMDAUDIO,
575
    sizeof(VmdAudioContext),
576
    vmdaudio_decode_init,
577
    NULL,
578
    NULL,
579
    vmdaudio_decode_frame,
580
    .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
581
};