Statistics
| Branch: | Revision:

ffmpeg / libavcodec / vmdav.c @ 1574eff3

History | View | Annotate | Download (16.7 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 silent_chunks, int data_size)
481
{
482
    int i;
483
    int silent_size = s->block_align * silent_chunks * 2;
484

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

    
499
    return silent_size + data_size * 2;
500
}
501

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

    
512
    if (buf_size < 16) {
513
        av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
514
        *data_size = 0;
515
        return buf_size;
516
    }
517

    
518
    block_type = buf[6];
519
    if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
520
        av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
521
        return AVERROR(EINVAL);
522
    }
523
    buf      += 16;
524
    buf_size -= 16;
525

    
526
    silent_chunks = 0;
527
    if (block_type == BLOCK_TYPE_INITIAL) {
528
        uint32_t flags = AV_RB32(buf);
529
        silent_chunks  = av_popcount(flags);
530
        buf      += 4;
531
        buf_size -= 4;
532
    } else if (block_type == BLOCK_TYPE_SILENCE) {
533
        silent_chunks = 1;
534
        buf_size = 0; // should already be zero but set it just to be sure
535
    }
536

    
537
    /* ensure output buffer is large enough */
538
    if (*data_size < (s->block_align*silent_chunks + buf_size) * 2)
539
        return -1;
540

    
541
    *data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size);
542

    
543
    return avpkt->size;
544
}
545

    
546

    
547
/*
548
 * Public Data Structures
549
 */
550

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

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