Revision fafa0b75

View differences:

libavcodec/Makefile
19 19
      vp3.o asv1.o 4xm.o cabac.o ffv1.o ra144.o ra288.o vcr1.o cljr.o \
20 20
      roqvideo.o dpcm.o interplayvideo.o xan.o rpza.o cinepak.o msrle.o \
21 21
      msvideo1.o vqavideo.o idcinvideo.o adx.o rational.o faandct.o 8bps.o \
22
      smc.o parser.o flicvideo.o truemotion1.o
22
      smc.o parser.o flicvideo.o truemotion1.o vmdav.o
23 23

  
24 24
ifeq ($(AMR_NB),yes)
25 25
ifeq ($(AMR_NB_FIXED),yes)
libavcodec/allcodecs.c
140 140
    register_avcodec(&smc_decoder);
141 141
    register_avcodec(&flic_decoder);
142 142
    register_avcodec(&truemotion1_decoder);
143
    register_avcodec(&vmdvideo_decoder);
144
    register_avcodec(&vmdaudio_decoder);
143 145
#ifdef CONFIG_AC3
144 146
    register_avcodec(&ac3_decoder);
145 147
#endif
libavcodec/avcodec.h
89 89
    CODEC_ID_SMC,
90 90
    CODEC_ID_FLIC,
91 91
    CODEC_ID_TRUEMOTION1,
92
    CODEC_ID_VMDVIDEO,
93
    CODEC_ID_VMDAUDIO,
92 94

  
93 95
    /* various pcm "codecs" */
94 96
    CODEC_ID_PCM_S16LE,
......
1662 1664
extern AVCodec eightbps_decoder;
1663 1665
extern AVCodec smc_decoder;
1664 1666
extern AVCodec flic_decoder;
1667
extern AVCodec vmdvideo_decoder;
1668
extern AVCodec vmdaudio_decoder;
1665 1669
extern AVCodec truemotion1_decoder;
1666 1670
extern AVCodec ra_144_decoder;
1667 1671
extern AVCodec ra_288_decoder;
libavcodec/vmdav.c
1
/*
2
 * Sierra VMD Audio & Video Decoders
3
 * Copyright (C) 2004 the ffmpeg project
4
 *
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.
9
 *
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.
14
 *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 *
19
 */
20

  
21
/**
22
 * @file vmdvideo.c
23
 * Sierra VMD audio & video decoders
24
 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
25
 *
26
 * The video decoder outputs PAL8 colorspace data. The decoder expects
27
 * a 0x330-byte VMD file header to be transmitted via extradata during
28
 * codec initialization. Each encoded frame that is sent to this decoder
29
 * is expected to be prepended with the appropriate 16-byte frame 
30
 * information record from the VMD file.
31
 *
32
 * The audio decoder, like the video decoder, expects each encoded data
33
 * chunk to be prepended with the approriate 16-byte frame information
34
 * record from the VMD file. It does not require the 0x330-byte VMD file
35
 * header, but it does need the audio setup parameters passed in through
36
 * normal libavcodec API means.
37
 */
38

  
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <string.h>
42
#include <unistd.h>
43

  
44
#include "common.h"
45
#include "avcodec.h"
46
#include "dsputil.h"
47

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

  
51
#define LE_16(x)  ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
52
#define LE_32(x)  ((((uint8_t*)(x))[3] << 24) | \
53
                   (((uint8_t*)(x))[2] << 16) | \
54
                   (((uint8_t*)(x))[1] << 8) | \
55
                    ((uint8_t*)(x))[0])
56

  
57
/*
58
 * Video Decoder
59
 */
60

  
61
typedef struct VmdVideoContext {
62

  
63
    AVCodecContext *avctx;
64
    DSPContext dsp;
65
    AVFrame frame;
66
    AVFrame prev_frame;
67

  
68
    unsigned char *buf;
69
    int size;
70

  
71
    unsigned char palette[PALETTE_COUNT * 4];
72
    unsigned char *unpack_buffer;
73

  
74
} VmdVideoContext;
75

  
76
#define QUEUE_SIZE 0x1000
77
#define QUEUE_MASK 0x0FFF
78

  
79
static void lz_unpack(unsigned char *src, unsigned char *dest)
80
{
81
    unsigned char *s;
82
    unsigned char *d;
83
    unsigned char queue[QUEUE_SIZE];
84
    unsigned int qpos;
85
    unsigned int dataleft;
86
    unsigned int chainofs;
87
    unsigned int chainlen;
88
    unsigned int speclen;
89
    unsigned char tag;
90
    unsigned int i, j;
91

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

  
106
    while (dataleft > 0) {
107
        tag = *s++;
108
        if ((tag == 0xFF) && (dataleft > 8)) {
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
                    queue[qpos++] = *d++ = *s++;
120
                    qpos &= QUEUE_MASK;
121
                    dataleft--;
122
                } else {
123
                    chainofs = *s++;
124
                    chainofs |= ((*s & 0xF0) << 4);
125
                    chainlen = (*s++ & 0x0F) + 3;
126
                    if (chainlen == speclen)
127
                        chainlen = *s++ + 0xF + 3;
128
                    for (j = 0; j < chainlen; j++) {
129
                        *d = queue[chainofs++ & QUEUE_MASK];
130
                        queue[qpos++] = *d++;
131
                        qpos &= QUEUE_MASK;
132
                    }
133
                    dataleft -= chainlen;
134
                }
135
                tag >>= 1;
136
            }
137
        }
138
    }
139
}
140

  
141
static int rle_unpack(unsigned char *src, unsigned char *dest, int len)
142
{
143
    unsigned char *ps;
144
    unsigned char *pd;
145
    int i, l;
146

  
147
    ps = src;
148
    pd = dest;
149
    if (len & 1)
150
        *pd++ = *ps++;
151

  
152
    len >>= 1;
153
    i = 0;
154
    do {
155
        l = *ps++;
156
        if (l & 0x80) {
157
            l = (l & 0x7F) * 2;
158
            memcpy(pd, ps, l);
159
            ps += l;
160
            pd += l;
161
        } else {
162
            for (i = 0; i < l; i++) {
163
                *pd++ = ps[0];
164
                *pd++ = ps[1];
165
            }
166
            ps += 2;
167
        }
168
        i += l;
169
    } while (i < len);
170

  
171
    return (ps - src);
172
}
173

  
174
static void vmd_decode(VmdVideoContext *s)
175
{
176
    int i;
177
    unsigned int *palette32;
178
    unsigned char r, g, b;
179

  
180
    /* point to the start of the encoded data */
181
    unsigned char *p = s->buf + 16;
182

  
183
    unsigned char *pb;
184
    unsigned char meth;
185
    unsigned char *dp;   /* pointer to current frame */
186
    unsigned char *pp;   /* pointer to previous frame */
187
    unsigned char len;
188
    int ofs;
189

  
190
    int frame_x, frame_y;
191
    int frame_width, frame_height;
192

  
193
    frame_x = LE_16(&s->buf[6]);
194
    frame_y = LE_16(&s->buf[8]);
195
    frame_width = LE_16(&s->buf[10]) - frame_x + 1;
196
    frame_height = LE_16(&s->buf[12]) - frame_y + 1;
197

  
198
    /* if only a certain region will be updated, copy the entire previous
199
     * frame before the decode */
200
    if (frame_x || frame_y || (frame_width != s->avctx->width) ||
201
        (frame_height != s->avctx->height)) {
202

  
203
        memcpy(s->frame.data[0], s->prev_frame.data[0], 
204
            s->avctx->height * s->frame.linesize[0]);
205
    }
206

  
207
    /* check if there is a new palette */
208
    if (s->buf[15] & 0x02) {
209
        p += 2;
210
        palette32 = (unsigned int *)s->palette;
211
        for (i = 0; i < PALETTE_COUNT; i++) {
212
            r = *p++ * 4;
213
            g = *p++ * 4;
214
            b = *p++ * 4;
215
            palette32[i] = (r << 16) | (g << 8) | (b);
216
        }
217
        s->size -= (256 * 3 + 2);
218
    }
219
    if (s->size >= 0) {
220
        /* originally UnpackFrame in VAG's code */
221
        pb = p;
222
        meth = *pb++;
223
        if (meth & 0x80) {
224
            lz_unpack(pb, s->unpack_buffer);
225
            meth &= 0x7F;
226
            pb = s->unpack_buffer;
227
        }
228

  
229
        dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
230
        pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
231
        switch (meth) {
232
        case 1:
233
            for (i = 0; i < frame_height; i++) {
234
                ofs = 0;
235
                do {
236
                    len = *pb++;
237
                    if (len & 0x80) {
238
                        len = (len & 0x7F) + 1;
239
                        memcpy(&dp[ofs], pb, len);
240
                        pb += len;
241
                        ofs += len;
242
                    } else {
243
                        /* interframe pixel copy */
244
                        memcpy(&dp[ofs], &pp[ofs], len + 1);
245
                        ofs += len + 1;
246
                    }
247
                } while (ofs < frame_width);
248
                if (ofs > frame_width) {
249
                    printf (" VMD video: offset > width (%d > %d)\n",
250
                        ofs, frame_width);
251
                    break;
252
                }
253
                dp += s->frame.linesize[0];
254
                pp += s->prev_frame.linesize[0];
255
            }
256
            break;
257

  
258
        case 2:
259
            for (i = 0; i < frame_height; i++) {
260
                memcpy(dp, pb, frame_width);
261
                pb += frame_width;
262
                dp += s->frame.linesize[0];
263
                pp += s->prev_frame.linesize[0];
264
            }
265
            break;
266

  
267
        case 3:
268
            for (i = 0; i < frame_height; i++) {
269
                ofs = 0;
270
                do {
271
                    len = *pb++;
272
                    if (len & 0x80) {
273
                        len = (len & 0x7F) + 1;
274
                        if (*pb++ == 0xFF)
275
                            len = rle_unpack(pb, dp, len);
276
                        else
277
                            memcpy(&dp[ofs], pb, len);
278
                        pb += len;
279
                        ofs += len;
280
                    } else {
281
                        /* interframe pixel copy */
282
                        memcpy(&dp[ofs], &pp[ofs], len + 1);
283
                        ofs += len + 1;
284
                    }
285
                } while (ofs < frame_width);
286
                if (ofs > frame_width) {
287
                    printf (" VMD video: offset > width (%d > %d)\n",
288
                        ofs, frame_width);
289
                }
290
                dp += s->frame.linesize[0];
291
                pp += s->prev_frame.linesize[0];
292
            }
293
            break;
294
        }
295
    }
296
}
297

  
298
static int vmdvideo_decode_init(AVCodecContext *avctx)
299
{
300
    VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
301
    int i;
302
    unsigned int *palette32;
303
    int palette_index = 0;
304
    unsigned char r, g, b;
305
    unsigned char *vmd_header;
306
    unsigned char *raw_palette;
307

  
308
    s->avctx = avctx;
309
    avctx->pix_fmt = PIX_FMT_PAL8;
310
    avctx->has_b_frames = 0;
311
    dsputil_init(&s->dsp, avctx);
312

  
313
    /* make sure the VMD header made it */
314
    if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
315
        printf("  VMD video: expected extradata size of %d\n", 
316
            VMD_HEADER_SIZE);
317
        return -1;
318
    }
319
    vmd_header = (unsigned char *)avctx->extradata;
320

  
321
    s->unpack_buffer = av_malloc(LE_32(&vmd_header[800]));
322
    if (!s->unpack_buffer)
323
        return -1;
324

  
325
    /* load up the initial palette */
326
    raw_palette = &vmd_header[28];
327
    palette32 = (unsigned int *)s->palette;
328
    for (i = 0; i < PALETTE_COUNT; i++) {
329
        r = raw_palette[palette_index++] * 4;
330
        g = raw_palette[palette_index++] * 4;
331
        b = raw_palette[palette_index++] * 4;
332
        palette32[i] = (r << 16) | (g << 8) | (b);
333
    }
334

  
335
    s->frame.data[0] = s->prev_frame.data[0] = NULL;
336

  
337
    return 0;
338
}
339

  
340
static int vmdvideo_decode_frame(AVCodecContext *avctx,
341
                                 void *data, int *data_size,
342
                                 uint8_t *buf, int buf_size)
343
{
344
    VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
345

  
346
    s->buf = buf;
347
    s->size = buf_size;
348

  
349
    s->frame.reference = 1;
350
    if (avctx->get_buffer(avctx, &s->frame)) {
351
        printf ("  VMD Video: get_buffer() failed\n");
352
        return -1;
353
    }
354

  
355
    vmd_decode(s);
356

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

  
360
    if (s->prev_frame.data[0])
361
        avctx->release_buffer(avctx, &s->prev_frame);
362

  
363
    /* shuffle frames */
364
    s->prev_frame = s->frame;
365

  
366
    *data_size = sizeof(AVFrame);
367
    *(AVFrame*)data = s->frame;
368

  
369
    /* report that the buffer was completely consumed */
370
    return buf_size;
371
}
372

  
373
static int vmdvideo_decode_end(AVCodecContext *avctx)
374
{
375
    VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
376

  
377
    if (s->prev_frame.data[0])
378
        avctx->release_buffer(avctx, &s->prev_frame);
379
    av_free(s->unpack_buffer);
380

  
381
    return 0;
382
}
383

  
384

  
385
/*
386
 * Audio Decoder
387
 */
388

  
389
typedef struct VmdAudioContext {
390
    int channels;
391
    int bits;
392
    int block_align;
393
    unsigned char steps8[16];
394
    unsigned short steps16[16];
395
    unsigned short steps128[256];
396
    short predictors[2];
397
} VmdAudioContext;
398

  
399
static int vmdaudio_decode_init(AVCodecContext *avctx)
400
{
401
    VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
402
    int i;
403

  
404
    s->channels = avctx->channels;
405
    s->bits = avctx->bits_per_sample;
406
    s->block_align = avctx->block_align;
407

  
408
printf ("  %d channels, %d bits/sample, block align = %d\n",
409
  s->channels, s->bits, s->block_align);
410

  
411
    /* set up the steps8 and steps16 tables */
412
    for (i = 0; i < 8; i++) {
413
        if (i < 4)
414
            s->steps8[i] = i;
415
        else
416
            s->steps8[i] = s->steps8[i - 1] + i - 1;
417

  
418
        if (i == 0)
419
            s->steps16[i] = 0;
420
        else if (i == 1)
421
            s->steps16[i] = 4;
422
        else if (i == 2)
423
            s->steps16[i] = 16;
424
        else
425
            s->steps16[i] = 1 << (i + 4);
426
    }
427

  
428
    /* set up the step128 table */
429
    s->steps128[0] = 0;
430
    s->steps128[1] = 8;
431
    for (i = 0x02; i <= 0x20; i++)
432
        s->steps128[i] = (i - 1) << 4;
433
    for (i = 0x21; i <= 0x60; i++)
434
        s->steps128[i] = (i + 0x1F) << 3;
435
    for (i = 0x61; i <= 0x70; i++)
436
        s->steps128[i] = (i - 0x51) << 6;
437
    for (i = 0x71; i <= 0x78; i++)
438
        s->steps128[i] = (i - 0x69) << 8;
439
    for (i = 0x79; i <= 0x7D; i++)
440
        s->steps128[i] = (i - 0x75) << 10;
441
    s->steps128[0x7E] = 0x3000;
442
    s->steps128[0x7F] = 0x4000;
443

  
444
    /* set up the negative half of each table */
445
    for (i = 0; i < 8; i++) {
446
        s->steps8[i + 8] = -s->steps8[i];
447
        s->steps16[i + 8] = -s->steps16[i];
448
    }
449
    for (i = 0; i < 128; i++)
450
      s->steps128[i + 128] = -s->steps128[i];
451

  
452
    return 0;
453
}
454

  
455
static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
456
    uint8_t *buf, int ratio) {
457

  
458
}
459

  
460
static void vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
461
    uint8_t *buf, int silence)
462
{
463
    if (s->channels == 2) {
464
        if ((s->block_align & 0x01) == 0) {
465
            if (silence)
466
                memset(data, 0, s->block_align * 2);
467
            else
468
                vmdaudio_decode_audio(s, data, buf, 1);
469
        } else {
470
            if (silence)
471
                memset(data, 0, s->block_align * 2);
472
//            else
473
//                vmdaudio_decode_audio(s, data, buf, 1);
474
        }
475
    } else {
476
    }
477
}
478

  
479
static int vmdaudio_decode_frame(AVCodecContext *avctx,
480
                                 void *data, int *data_size,
481
                                 uint8_t *buf, int buf_size)
482
{
483
    VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
484
    unsigned int sound_flags;
485
    unsigned char *output_samples = (unsigned char *)data;
486

  
487
    /* point to the start of the encoded data */
488
    unsigned char *p = buf + 16;
489
    unsigned char *p_end = buf + buf_size;
490

  
491
    if (buf[6] == 1) {
492
        /* the chunk contains audio */
493
        vmdaudio_loadsound(s, output_samples, p, 0);
494
    } else if (buf[6] == 2) {
495
        /* the chunk contains audio and silence mixed together */
496
        sound_flags = LE_32(p);
497
        p += 4;
498

  
499
        /* do something with extrabufs here? */
500

  
501
        while (p < p_end) {
502
            if (sound_flags & 0x01)
503
                /* audio */
504
                vmdaudio_loadsound(s, output_samples, p, 1);
505
            else
506
                /* silence */
507
                vmdaudio_loadsound(s, output_samples, p, 0);
508
            p += s->block_align;
509
            output_samples += (s->block_align * s->bits / 8);
510
            sound_flags >>= 1;
511
        }
512
    } else if (buf[6] == 3) {
513
        /* silent chunk */
514
        vmdaudio_loadsound(s, output_samples, p, 1);
515
    }
516

  
517

  
518
//    *datasize = ;
519
    return buf_size;
520
}
521

  
522

  
523
/*
524
 * Public Data Structures
525
 */
526

  
527
AVCodec vmdvideo_decoder = {
528
    "vmdvideo",
529
    CODEC_TYPE_VIDEO,
530
    CODEC_ID_VMDVIDEO,
531
    sizeof(VmdVideoContext),
532
    vmdvideo_decode_init,
533
    NULL,
534
    vmdvideo_decode_end,
535
    vmdvideo_decode_frame,
536
    CODEC_CAP_DR1,
537
};
538

  
539
AVCodec vmdaudio_decoder = {
540
    "vmdaudio",
541
    CODEC_TYPE_AUDIO,
542
    CODEC_ID_VMDAUDIO,
543
    sizeof(VmdAudioContext),
544
    vmdaudio_decode_init,
545
    NULL,
546
    NULL,
547
    vmdaudio_decode_frame,
548
};

Also available in: Unified diff