~ubuntu-branches/ubuntu/hardy/avidemux/hardy

« back to all changes in this revision

Viewing changes to avidemux/ADM_lavcodec/vmdav.c

  • Committer: Bazaar Package Importer
  • Author(s): Matvey Kozhev
  • Date: 2007-12-18 13:53:04 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071218135304-cdqec2lg2bglyz15
Tags: 1:2.4~preview3-0.0ubuntu1
* Upload to Ubuntu. (LP: #163287, LP: #126572)
* debian/changelog: re-added Ubuntu releases.
* debian/control:
  - Require debhelper >= 5.0.51 (for dh_icons) and imagemagick.
  - Build-depend on libsdl1.2-dev instead of libsdl-dev.
  - Build against newer libx264-dev. (LP: #138854)
  - Removed libamrnb-dev, not in Ubuntu yet.
* debian/rules:
  - Install all icon sizes, using convert (upstream installs none).
  - Added missing calls to dh_installmenu, dh_installman, dh_icons and
    dh_desktop.
* debian/menu, debian/avidemux-qt.menu:
  - Corrected package and executable names.
* debian/avidemux-common.install: Install icons.
* debian/avidemux.common.manpages: Install man/avidemux.1.
* debian/links, debian/avidemux-cli.links, debian/avidemux-gtk.links:
  - Link manpages to avidemux.1.gz.
* debian/install, debian/avidemux-qt.install, debian/avidemux-gtk.desktop,
  debian/avidemux-qt.desktop: Install desktop files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
 
 * for more information on the Sierra VMD format, visit:
26
 
 *   http://www.pcisys.net/~melanson/codecs/
27
 
 *
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.
33
 
 *
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.
39
 
 */
40
 
 
41
 
#include <stdio.h>
42
 
#include <stdlib.h>
43
 
#include <string.h>
44
 
#include <unistd.h>
45
 
 
46
 
#include "common.h"
47
 
#include "avcodec.h"
48
 
#include "dsputil.h"
49
 
 
50
 
#define VMD_HEADER_SIZE 0x330
51
 
#define PALETTE_COUNT 256
52
 
 
53
 
/*
54
 
 * Video Decoder
55
 
 */
56
 
 
57
 
typedef struct VmdVideoContext {
58
 
 
59
 
    AVCodecContext *avctx;
60
 
    DSPContext dsp;
61
 
    AVFrame frame;
62
 
    AVFrame prev_frame;
63
 
 
64
 
    unsigned char *buf;
65
 
    int size;
66
 
 
67
 
    unsigned char palette[PALETTE_COUNT * 4];
68
 
    unsigned char *unpack_buffer;
69
 
    int unpack_buffer_size;
70
 
 
71
 
} VmdVideoContext;
72
 
 
73
 
#define QUEUE_SIZE 0x1000
74
 
#define QUEUE_MASK 0x0FFF
75
 
 
76
 
static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len)
77
 
{
78
 
    unsigned char *s;
79
 
    unsigned char *d;
80
 
    unsigned char *d_end;
81
 
    unsigned char queue[QUEUE_SIZE];
82
 
    unsigned int qpos;
83
 
    unsigned int dataleft;
84
 
    unsigned int chainofs;
85
 
    unsigned int chainlen;
86
 
    unsigned int speclen;
87
 
    unsigned char tag;
88
 
    unsigned int i, j;
89
 
 
90
 
    s = src;
91
 
    d = dest;
92
 
    d_end = d + dest_len;
93
 
    dataleft = LE_32(s);
94
 
    s += 4;
95
 
    memset(queue, QUEUE_SIZE, 0x20);
96
 
    if (LE_32(s) == 0x56781234) {
97
 
        s += 4;
98
 
        qpos = 0x111;
99
 
        speclen = 0xF + 3;
100
 
    } else {
101
 
        qpos = 0xFEE;
102
 
        speclen = 100;  /* no speclen */
103
 
    }
104
 
 
105
 
    while (dataleft > 0) {
106
 
        tag = *s++;
107
 
        if ((tag == 0xFF) && (dataleft > 8)) {
108
 
            if (d + 8 > d_end)
109
 
                return;
110
 
            for (i = 0; i < 8; i++) {
111
 
                queue[qpos++] = *d++ = *s++;
112
 
                qpos &= QUEUE_MASK;
113
 
            }
114
 
            dataleft -= 8;
115
 
        } else {
116
 
            for (i = 0; i < 8; i++) {
117
 
                if (dataleft == 0)
118
 
                    break;
119
 
                if (tag & 0x01) {
120
 
                    if (d + 1 > d_end)
121
 
                        return;
122
 
                    queue[qpos++] = *d++ = *s++;
123
 
                    qpos &= QUEUE_MASK;
124
 
                    dataleft--;
125
 
                } else {
126
 
                    chainofs = *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)
132
 
                        return;
133
 
                    for (j = 0; j < chainlen; j++) {
134
 
                        *d = queue[chainofs++ & QUEUE_MASK];
135
 
                        queue[qpos++] = *d++;
136
 
                        qpos &= QUEUE_MASK;
137
 
                    }
138
 
                    dataleft -= chainlen;
139
 
                }
140
 
                tag >>= 1;
141
 
            }
142
 
        }
143
 
    }
144
 
}
145
 
 
146
 
static int rle_unpack(unsigned char *src, unsigned char *dest,
147
 
    int src_len, int dest_len)
148
 
{
149
 
    unsigned char *ps;
150
 
    unsigned char *pd;
151
 
    int i, l;
152
 
    unsigned char *dest_end = dest + dest_len;
153
 
 
154
 
    ps = src;
155
 
    pd = dest;
156
 
    if (src_len & 1)
157
 
        *pd++ = *ps++;
158
 
 
159
 
    src_len >>= 1;
160
 
    i = 0;
161
 
    do {
162
 
        l = *ps++;
163
 
        if (l & 0x80) {
164
 
            l = (l & 0x7F) * 2;
165
 
            if (pd + l > dest_end)
166
 
                return (ps - src);
167
 
            memcpy(pd, ps, l);
168
 
            ps += l;
169
 
            pd += l;
170
 
        } else {
171
 
            if (pd + i > dest_end)
172
 
                return (ps - src);
173
 
            for (i = 0; i < l; i++) {
174
 
                *pd++ = ps[0];
175
 
                *pd++ = ps[1];
176
 
            }
177
 
            ps += 2;
178
 
        }
179
 
        i += l;
180
 
    } while (i < src_len);
181
 
 
182
 
    return (ps - src);
183
 
}
184
 
 
185
 
static void vmd_decode(VmdVideoContext *s)
186
 
{
187
 
    int i;
188
 
    unsigned int *palette32;
189
 
    unsigned char r, g, b;
190
 
 
191
 
    /* point to the start of the encoded data */
192
 
    unsigned char *p = s->buf + 16;
193
 
 
194
 
    unsigned char *pb;
195
 
    unsigned char meth;
196
 
    unsigned char *dp;   /* pointer to current frame */
197
 
    unsigned char *pp;   /* pointer to previous frame */
198
 
    unsigned char len;
199
 
    int ofs;
200
 
 
201
 
    int frame_x, frame_y;
202
 
    int frame_width, frame_height;
203
 
    int dp_size;
204
 
 
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;
209
 
 
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)) {
214
 
 
215
 
        memcpy(s->frame.data[0], s->prev_frame.data[0],
216
 
            s->avctx->height * s->frame.linesize[0]);
217
 
    }
218
 
 
219
 
    /* check if there is a new palette */
220
 
    if (s->buf[15] & 0x02) {
221
 
        p += 2;
222
 
        palette32 = (unsigned int *)s->palette;
223
 
        for (i = 0; i < PALETTE_COUNT; i++) {
224
 
            r = *p++ * 4;
225
 
            g = *p++ * 4;
226
 
            b = *p++ * 4;
227
 
            palette32[i] = (r << 16) | (g << 8) | (b);
228
 
        }
229
 
        s->size -= (256 * 3 + 2);
230
 
    }
231
 
    if (s->size >= 0) {
232
 
        /* originally UnpackFrame in VAG's code */
233
 
        pb = p;
234
 
        meth = *pb++;
235
 
        if (meth & 0x80) {
236
 
            lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
237
 
            meth &= 0x7F;
238
 
            pb = s->unpack_buffer;
239
 
        }
240
 
 
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];
244
 
        switch (meth) {
245
 
        case 1:
246
 
            for (i = 0; i < frame_height; i++) {
247
 
                ofs = 0;
248
 
                do {
249
 
                    len = *pb++;
250
 
                    if (len & 0x80) {
251
 
                        len = (len & 0x7F) + 1;
252
 
                        if (ofs + len > frame_width)
253
 
                            return;
254
 
                        memcpy(&dp[ofs], pb, len);
255
 
                        pb += len;
256
 
                        ofs += len;
257
 
                    } else {
258
 
                        /* interframe pixel copy */
259
 
                        if (ofs + len + 1 > frame_width)
260
 
                            return;
261
 
                        memcpy(&dp[ofs], &pp[ofs], len + 1);
262
 
                        ofs += len + 1;
263
 
                    }
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",
267
 
                        ofs, frame_width);
268
 
                    break;
269
 
                }
270
 
                dp += s->frame.linesize[0];
271
 
                pp += s->prev_frame.linesize[0];
272
 
            }
273
 
            break;
274
 
 
275
 
        case 2:
276
 
            for (i = 0; i < frame_height; i++) {
277
 
                memcpy(dp, pb, frame_width);
278
 
                pb += frame_width;
279
 
                dp += s->frame.linesize[0];
280
 
                pp += s->prev_frame.linesize[0];
281
 
            }
282
 
            break;
283
 
 
284
 
        case 3:
285
 
            for (i = 0; i < frame_height; i++) {
286
 
                ofs = 0;
287
 
                do {
288
 
                    len = *pb++;
289
 
                    if (len & 0x80) {
290
 
                        len = (len & 0x7F) + 1;
291
 
                        if (*pb++ == 0xFF)
292
 
                            len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
293
 
                        else
294
 
                            memcpy(&dp[ofs], pb, len);
295
 
                        pb += len;
296
 
                        ofs += len;
297
 
                    } else {
298
 
                        /* interframe pixel copy */
299
 
                        if (ofs + len + 1 > frame_width)
300
 
                            return;
301
 
                        memcpy(&dp[ofs], &pp[ofs], len + 1);
302
 
                        ofs += len + 1;
303
 
                    }
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",
307
 
                        ofs, frame_width);
308
 
                }
309
 
                dp += s->frame.linesize[0];
310
 
                pp += s->prev_frame.linesize[0];
311
 
            }
312
 
            break;
313
 
        }
314
 
    }
315
 
}
316
 
 
317
 
static int vmdvideo_decode_init(AVCodecContext *avctx)
318
 
{
319
 
    VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
320
 
    int i;
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;
326
 
 
327
 
    s->avctx = avctx;
328
 
    avctx->pix_fmt = PIX_FMT_PAL8;
329
 
    avctx->has_b_frames = 0;
330
 
    dsputil_init(&s->dsp, avctx);
331
 
 
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",
335
 
            VMD_HEADER_SIZE);
336
 
        return -1;
337
 
    }
338
 
    vmd_header = (unsigned char *)avctx->extradata;
339
 
 
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)
343
 
        return -1;
344
 
 
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);
353
 
    }
354
 
 
355
 
    s->frame.data[0] = s->prev_frame.data[0] = NULL;
356
 
 
357
 
    return 0;
358
 
}
359
 
 
360
 
static int vmdvideo_decode_frame(AVCodecContext *avctx,
361
 
                                 void *data, int *data_size,
362
 
                                 uint8_t *buf, int buf_size)
363
 
{
364
 
    VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
365
 
 
366
 
    s->buf = buf;
367
 
    s->size = buf_size;
368
 
 
369
 
    if (buf_size < 16)
370
 
        return buf_size;
371
 
 
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");
375
 
        return -1;
376
 
    }
377
 
 
378
 
    vmd_decode(s);
379
 
 
380
 
    /* make the palette available on the way out */
381
 
    memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
382
 
 
383
 
    if (s->prev_frame.data[0])
384
 
        avctx->release_buffer(avctx, &s->prev_frame);
385
 
 
386
 
    /* shuffle frames */
387
 
    s->prev_frame = s->frame;
388
 
 
389
 
    *data_size = sizeof(AVFrame);
390
 
    *(AVFrame*)data = s->frame;
391
 
 
392
 
    /* report that the buffer was completely consumed */
393
 
    return buf_size;
394
 
}
395
 
 
396
 
static int vmdvideo_decode_end(AVCodecContext *avctx)
397
 
{
398
 
    VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
399
 
 
400
 
    if (s->prev_frame.data[0])
401
 
        avctx->release_buffer(avctx, &s->prev_frame);
402
 
    av_free(s->unpack_buffer);
403
 
 
404
 
    return 0;
405
 
}
406
 
 
407
 
 
408
 
/*
409
 
 * Audio Decoder
410
 
 */
411
 
 
412
 
typedef struct VmdAudioContext {
413
 
    AVCodecContext *avctx;
414
 
    int channels;
415
 
    int bits;
416
 
    int block_align;
417
 
    int predictors[2];
418
 
} VmdAudioContext;
419
 
 
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
434
 
};
435
 
 
436
 
static int vmdaudio_decode_init(AVCodecContext *avctx)
437
 
{
438
 
    VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
439
 
 
440
 
    s->avctx = avctx;
441
 
    s->channels = avctx->channels;
442
 
    s->bits = avctx->bits_per_sample;
443
 
    s->block_align = avctx->block_align;
444
 
 
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);
447
 
 
448
 
    return 0;
449
 
}
450
 
 
451
 
static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
452
 
    uint8_t *buf, int stereo)
453
 
{
454
 
    int i;
455
 
    int chan = 0;
456
 
    int16_t *out = (int16_t*)data;
457
 
 
458
 
    for(i = 0; i < s->block_align; i++) {
459
 
        if(buf[i] & 0x80)
460
 
            s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
461
 
        else
462
 
            s->predictors[chan] += vmdaudio_table[buf[i]];
463
 
        s->predictors[chan] = clip(s->predictors[chan], -32768, 32767);
464
 
        out[i] = s->predictors[chan];
465
 
        chan ^= stereo;
466
 
    }
467
 
}
468
 
 
469
 
static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
470
 
    uint8_t *buf, int silence)
471
 
{
472
 
    int bytes_decoded = 0;
473
 
    int i;
474
 
 
475
 
//    if (silence)
476
 
//        av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
477
 
    if (s->channels == 2) {
478
 
 
479
 
        /* stereo handling */
480
 
        if (silence) {
481
 
            memset(data, 0, s->block_align * 2);
482
 
        } else {
483
 
            if (s->bits == 16)
484
 
                vmdaudio_decode_audio(s, data, buf, 1);
485
 
            else
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;
489
 
        }
490
 
    } else {
491
 
        bytes_decoded = s->block_align * 2;
492
 
 
493
 
        /* mono handling */
494
 
        if (silence) {
495
 
            memset(data, 0, s->block_align * 2);
496
 
        } else {
497
 
            if (s->bits == 16) {
498
 
                vmdaudio_decode_audio(s, data, buf, 0);
499
 
            } else {
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;
503
 
            }
504
 
        }
505
 
    }
506
 
 
507
 
    return s->block_align * 2;
508
 
}
509
 
 
510
 
static int vmdaudio_decode_frame(AVCodecContext *avctx,
511
 
                                 void *data, int *data_size,
512
 
                                 uint8_t *buf, int buf_size)
513
 
{
514
 
    VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
515
 
    unsigned int sound_flags;
516
 
    unsigned char *output_samples = (unsigned char *)data;
517
 
 
518
 
    /* point to the start of the encoded data */
519
 
    unsigned char *p = buf + 16;
520
 
    unsigned char *p_end = buf + buf_size;
521
 
 
522
 
    if (buf_size < 16)
523
 
        return buf_size;
524
 
 
525
 
    if (buf[6] == 1) {
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);
531
 
        p += 4;
532
 
 
533
 
        /* do something with extrabufs here? */
534
 
 
535
 
        while (p < p_end) {
536
 
            if (sound_flags & 0x01)
537
 
                /* silence */
538
 
                *data_size += vmdaudio_loadsound(s, output_samples, p, 1);
539
 
            else {
540
 
                /* audio */
541
 
                *data_size += vmdaudio_loadsound(s, output_samples, p, 0);
542
 
                p += s->block_align;
543
 
            }
544
 
            output_samples += (s->block_align * s->bits / 8);
545
 
            sound_flags >>= 1;
546
 
        }
547
 
    } else if (buf[6] == 3) {
548
 
        /* silent chunk */
549
 
        *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
550
 
    }
551
 
 
552
 
    return buf_size;
553
 
}
554
 
 
555
 
 
556
 
/*
557
 
 * Public Data Structures
558
 
 */
559
 
 
560
 
AVCodec vmdvideo_decoder = {
561
 
    "vmdvideo",
562
 
    CODEC_TYPE_VIDEO,
563
 
    CODEC_ID_VMDVIDEO,
564
 
    sizeof(VmdVideoContext),
565
 
    vmdvideo_decode_init,
566
 
    NULL,
567
 
    vmdvideo_decode_end,
568
 
    vmdvideo_decode_frame,
569
 
    CODEC_CAP_DR1,
570
 
};
571
 
 
572
 
AVCodec vmdaudio_decoder = {
573
 
    "vmdaudio",
574
 
    CODEC_TYPE_AUDIO,
575
 
    CODEC_ID_VMDAUDIO,
576
 
    sizeof(VmdAudioContext),
577
 
    vmdaudio_decode_init,
578
 
    NULL,
579
 
    NULL,
580
 
    vmdaudio_decode_frame,
581
 
};