~siretart/ffmpeg/ffmpeg.jaunty

« back to all changes in this revision

Viewing changes to libavformat/westwood.c

  • Committer: Reinhard Tartler
  • Date: 2008-11-15 18:42:09 UTC
  • Revision ID: siretart@tauware.de-20081115184209-jqjykvfs6wwwb3qp
Tags: upstream-debian-0.svn20081115
ImportĀ upstreamĀ versionĀ 0.svn20081115

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Westwood Studios Multimedia Formats Demuxer (VQA, AUD)
 
3
 * Copyright (c) 2003 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 westwood.c
 
24
 * Westwood Studios VQA & AUD file demuxers
 
25
 * by Mike Melanson (melanson@pcisys.net)
 
26
 * for more information on the Westwood file formats, visit:
 
27
 *   http://www.pcisys.net/~melanson/codecs/
 
28
 *   http://www.geocities.com/SiliconValley/8682/aud3.txt
 
29
 *
 
30
 * Implementation note: There is no definite file signature for AUD files.
 
31
 * The demuxer uses a probabilistic strategy for content detection. This
 
32
 * entails performing sanity checks on certain header values in order to
 
33
 * qualify a file. Refer to wsaud_probe() for the precise parameters.
 
34
 */
 
35
 
 
36
#include "avformat.h"
 
37
 
 
38
#define AUD_HEADER_SIZE 12
 
39
#define AUD_CHUNK_PREAMBLE_SIZE 8
 
40
#define AUD_CHUNK_SIGNATURE 0x0000DEAF
 
41
 
 
42
#define FORM_TAG MKBETAG('F', 'O', 'R', 'M')
 
43
#define WVQA_TAG MKBETAG('W', 'V', 'Q', 'A')
 
44
#define VQHD_TAG MKBETAG('V', 'Q', 'H', 'D')
 
45
#define FINF_TAG MKBETAG('F', 'I', 'N', 'F')
 
46
#define SND0_TAG MKBETAG('S', 'N', 'D', '0')
 
47
#define SND1_TAG MKBETAG('S', 'N', 'D', '1')
 
48
#define SND2_TAG MKBETAG('S', 'N', 'D', '2')
 
49
#define VQFR_TAG MKBETAG('V', 'Q', 'F', 'R')
 
50
 
 
51
/* don't know what these tags are for, but acknowledge their existence */
 
52
#define CINF_TAG MKBETAG('C', 'I', 'N', 'F')
 
53
#define CINH_TAG MKBETAG('C', 'I', 'N', 'H')
 
54
#define CIND_TAG MKBETAG('C', 'I', 'N', 'D')
 
55
#define PINF_TAG MKBETAG('P', 'I', 'N', 'F')
 
56
#define PINH_TAG MKBETAG('P', 'I', 'N', 'H')
 
57
#define PIND_TAG MKBETAG('P', 'I', 'N', 'D')
 
58
#define CMDS_TAG MKBETAG('C', 'M', 'D', 'S')
 
59
 
 
60
#define VQA_HEADER_SIZE 0x2A
 
61
#define VQA_FRAMERATE 15
 
62
#define VQA_VIDEO_PTS_INC (90000 / VQA_FRAMERATE)
 
63
#define VQA_PREAMBLE_SIZE 8
 
64
 
 
65
typedef struct WsAudDemuxContext {
 
66
    int audio_samplerate;
 
67
    int audio_channels;
 
68
    int audio_bits;
 
69
    enum CodecID audio_type;
 
70
    int audio_stream_index;
 
71
    int64_t audio_frame_counter;
 
72
} WsAudDemuxContext;
 
73
 
 
74
typedef struct WsVqaDemuxContext {
 
75
    int audio_samplerate;
 
76
    int audio_channels;
 
77
    int audio_bits;
 
78
 
 
79
    int audio_stream_index;
 
80
    int video_stream_index;
 
81
 
 
82
    int64_t audio_frame_counter;
 
83
    int64_t video_pts;
 
84
} WsVqaDemuxContext;
 
85
 
 
86
static int wsaud_probe(AVProbeData *p)
 
87
{
 
88
    int field;
 
89
 
 
90
    /* Probabilistic content detection strategy: There is no file signature
 
91
     * so perform sanity checks on various header parameters:
 
92
     *   8000 <= sample rate (16 bits) <= 48000  ==> 40001 acceptable numbers
 
93
     *   flags <= 0x03 (2 LSBs are used)         ==> 4 acceptable numbers
 
94
     *   compression type (8 bits) = 1 or 99     ==> 2 acceptable numbers
 
95
     *   first audio chunk signature (32 bits)   ==> 1 acceptable number
 
96
     * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 =
 
97
     * 320008 acceptable number combinations.
 
98
     */
 
99
 
 
100
    if (p->buf_size < AUD_HEADER_SIZE + AUD_CHUNK_PREAMBLE_SIZE)
 
101
        return 0;
 
102
 
 
103
    /* check sample rate */
 
104
    field = AV_RL16(&p->buf[0]);
 
105
    if ((field < 8000) || (field > 48000))
 
106
        return 0;
 
107
 
 
108
    /* enforce the rule that the top 6 bits of this flags field are reserved (0);
 
109
     * this might not be true, but enforce it until deemed unnecessary */
 
110
    if (p->buf[10] & 0xFC)
 
111
        return 0;
 
112
 
 
113
    /* note: only check for WS IMA (type 99) right now since there is no
 
114
     * support for type 1 */
 
115
    if (p->buf[11] != 99)
 
116
        return 0;
 
117
 
 
118
    /* read ahead to the first audio chunk and validate the first header signature */
 
119
    if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE)
 
120
        return 0;
 
121
 
 
122
    /* return 1/2 certainty since this file check is a little sketchy */
 
123
    return AVPROBE_SCORE_MAX / 2;
 
124
}
 
125
 
 
126
static int wsaud_read_header(AVFormatContext *s,
 
127
                             AVFormatParameters *ap)
 
128
{
 
129
    WsAudDemuxContext *wsaud = s->priv_data;
 
130
    ByteIOContext *pb = s->pb;
 
131
    AVStream *st;
 
132
    unsigned char header[AUD_HEADER_SIZE];
 
133
 
 
134
    if (get_buffer(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE)
 
135
        return AVERROR(EIO);
 
136
    wsaud->audio_samplerate = AV_RL16(&header[0]);
 
137
    if (header[11] == 99)
 
138
        wsaud->audio_type = CODEC_ID_ADPCM_IMA_WS;
 
139
    else
 
140
        return AVERROR_INVALIDDATA;
 
141
 
 
142
    /* flag 0 indicates stereo */
 
143
    wsaud->audio_channels = (header[10] & 0x1) + 1;
 
144
    /* flag 1 indicates 16 bit audio */
 
145
    wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8;
 
146
 
 
147
    /* initialize the audio decoder stream */
 
148
    st = av_new_stream(s, 0);
 
149
    if (!st)
 
150
        return AVERROR(ENOMEM);
 
151
    av_set_pts_info(st, 33, 1, wsaud->audio_samplerate);
 
152
    st->codec->codec_type = CODEC_TYPE_AUDIO;
 
153
    st->codec->codec_id = wsaud->audio_type;
 
154
    st->codec->codec_tag = 0;  /* no tag */
 
155
    st->codec->channels = wsaud->audio_channels;
 
156
    st->codec->sample_rate = wsaud->audio_samplerate;
 
157
    st->codec->bits_per_coded_sample = wsaud->audio_bits;
 
158
    st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
 
159
        st->codec->bits_per_coded_sample / 4;
 
160
    st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
 
161
 
 
162
    wsaud->audio_stream_index = st->index;
 
163
    wsaud->audio_frame_counter = 0;
 
164
 
 
165
    return 0;
 
166
}
 
167
 
 
168
static int wsaud_read_packet(AVFormatContext *s,
 
169
                             AVPacket *pkt)
 
170
{
 
171
    WsAudDemuxContext *wsaud = s->priv_data;
 
172
    ByteIOContext *pb = s->pb;
 
173
    unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
 
174
    unsigned int chunk_size;
 
175
    int ret = 0;
 
176
 
 
177
    if (get_buffer(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
 
178
        AUD_CHUNK_PREAMBLE_SIZE)
 
179
        return AVERROR(EIO);
 
180
 
 
181
    /* validate the chunk */
 
182
    if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE)
 
183
        return AVERROR_INVALIDDATA;
 
184
 
 
185
    chunk_size = AV_RL16(&preamble[0]);
 
186
    ret= av_get_packet(pb, pkt, chunk_size);
 
187
    if (ret != chunk_size)
 
188
        return AVERROR(EIO);
 
189
    pkt->stream_index = wsaud->audio_stream_index;
 
190
    pkt->pts = wsaud->audio_frame_counter;
 
191
    pkt->pts /= wsaud->audio_samplerate;
 
192
 
 
193
    /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
 
194
    wsaud->audio_frame_counter += (chunk_size * 2) / wsaud->audio_channels;
 
195
 
 
196
    return ret;
 
197
}
 
198
 
 
199
static int wsvqa_probe(AVProbeData *p)
 
200
{
 
201
    /* need 12 bytes to qualify */
 
202
    if (p->buf_size < 12)
 
203
        return 0;
 
204
 
 
205
    /* check for the VQA signatures */
 
206
    if ((AV_RB32(&p->buf[0]) != FORM_TAG) ||
 
207
        (AV_RB32(&p->buf[8]) != WVQA_TAG))
 
208
        return 0;
 
209
 
 
210
    return AVPROBE_SCORE_MAX;
 
211
}
 
212
 
 
213
static int wsvqa_read_header(AVFormatContext *s,
 
214
                             AVFormatParameters *ap)
 
215
{
 
216
    WsVqaDemuxContext *wsvqa = s->priv_data;
 
217
    ByteIOContext *pb = s->pb;
 
218
    AVStream *st;
 
219
    unsigned char *header;
 
220
    unsigned char scratch[VQA_PREAMBLE_SIZE];
 
221
    unsigned int chunk_tag;
 
222
    unsigned int chunk_size;
 
223
 
 
224
    /* initialize the video decoder stream */
 
225
    st = av_new_stream(s, 0);
 
226
    if (!st)
 
227
        return AVERROR(ENOMEM);
 
228
    av_set_pts_info(st, 33, 1, VQA_FRAMERATE);
 
229
    wsvqa->video_stream_index = st->index;
 
230
    st->codec->codec_type = CODEC_TYPE_VIDEO;
 
231
    st->codec->codec_id = CODEC_ID_WS_VQA;
 
232
    st->codec->codec_tag = 0;  /* no fourcc */
 
233
 
 
234
    /* skip to the start of the VQA header */
 
235
    url_fseek(pb, 20, SEEK_SET);
 
236
 
 
237
    /* the VQA header needs to go to the decoder */
 
238
    st->codec->extradata_size = VQA_HEADER_SIZE;
 
239
    st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
 
240
    header = (unsigned char *)st->codec->extradata;
 
241
    if (get_buffer(pb, st->codec->extradata, VQA_HEADER_SIZE) !=
 
242
        VQA_HEADER_SIZE) {
 
243
        av_free(st->codec->extradata);
 
244
        return AVERROR(EIO);
 
245
    }
 
246
    st->codec->width = AV_RL16(&header[6]);
 
247
    st->codec->height = AV_RL16(&header[8]);
 
248
 
 
249
    /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
 
250
    if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) {
 
251
        st = av_new_stream(s, 0);
 
252
        if (!st)
 
253
            return AVERROR(ENOMEM);
 
254
        av_set_pts_info(st, 33, 1, VQA_FRAMERATE);
 
255
        st->codec->codec_type = CODEC_TYPE_AUDIO;
 
256
        if (AV_RL16(&header[0]) == 1)
 
257
            st->codec->codec_id = CODEC_ID_WESTWOOD_SND1;
 
258
        else
 
259
            st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS;
 
260
        st->codec->codec_tag = 0;  /* no tag */
 
261
        st->codec->sample_rate = AV_RL16(&header[24]);
 
262
        if (!st->codec->sample_rate)
 
263
            st->codec->sample_rate = 22050;
 
264
        st->codec->channels = header[26];
 
265
        if (!st->codec->channels)
 
266
            st->codec->channels = 1;
 
267
        st->codec->bits_per_coded_sample = 16;
 
268
        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
 
269
            st->codec->bits_per_coded_sample / 4;
 
270
        st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
 
271
 
 
272
        wsvqa->audio_stream_index = st->index;
 
273
        wsvqa->audio_samplerate = st->codec->sample_rate;
 
274
        wsvqa->audio_channels = st->codec->channels;
 
275
        wsvqa->audio_frame_counter = 0;
 
276
    }
 
277
 
 
278
    /* there are 0 or more chunks before the FINF chunk; iterate until
 
279
     * FINF has been skipped and the file will be ready to be demuxed */
 
280
    do {
 
281
        if (get_buffer(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) {
 
282
            av_free(st->codec->extradata);
 
283
            return AVERROR(EIO);
 
284
        }
 
285
        chunk_tag = AV_RB32(&scratch[0]);
 
286
        chunk_size = AV_RB32(&scratch[4]);
 
287
 
 
288
        /* catch any unknown header tags, for curiousity */
 
289
        switch (chunk_tag) {
 
290
        case CINF_TAG:
 
291
        case CINH_TAG:
 
292
        case CIND_TAG:
 
293
        case PINF_TAG:
 
294
        case PINH_TAG:
 
295
        case PIND_TAG:
 
296
        case FINF_TAG:
 
297
        case CMDS_TAG:
 
298
            break;
 
299
 
 
300
        default:
 
301
            av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n",
 
302
                scratch[0], scratch[1],
 
303
                scratch[2], scratch[3]);
 
304
            break;
 
305
        }
 
306
 
 
307
        url_fseek(pb, chunk_size, SEEK_CUR);
 
308
    } while (chunk_tag != FINF_TAG);
 
309
 
 
310
    wsvqa->video_pts = wsvqa->audio_frame_counter = 0;
 
311
 
 
312
    return 0;
 
313
}
 
314
 
 
315
static int wsvqa_read_packet(AVFormatContext *s,
 
316
                             AVPacket *pkt)
 
317
{
 
318
    WsVqaDemuxContext *wsvqa = s->priv_data;
 
319
    ByteIOContext *pb = s->pb;
 
320
    int ret = -1;
 
321
    unsigned char preamble[VQA_PREAMBLE_SIZE];
 
322
    unsigned int chunk_type;
 
323
    unsigned int chunk_size;
 
324
    int skip_byte;
 
325
 
 
326
    while (get_buffer(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) {
 
327
        chunk_type = AV_RB32(&preamble[0]);
 
328
        chunk_size = AV_RB32(&preamble[4]);
 
329
        skip_byte = chunk_size & 0x01;
 
330
 
 
331
        if ((chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) {
 
332
 
 
333
            if (av_new_packet(pkt, chunk_size))
 
334
                return AVERROR(EIO);
 
335
            ret = get_buffer(pb, pkt->data, chunk_size);
 
336
            if (ret != chunk_size) {
 
337
                av_free_packet(pkt);
 
338
                return AVERROR(EIO);
 
339
            }
 
340
 
 
341
            if (chunk_type == SND2_TAG) {
 
342
                pkt->stream_index = wsvqa->audio_stream_index;
 
343
                /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
 
344
                wsvqa->audio_frame_counter += (chunk_size * 2) / wsvqa->audio_channels;
 
345
            } else if(chunk_type == SND1_TAG) {
 
346
                pkt->stream_index = wsvqa->audio_stream_index;
 
347
                /* unpacked size is stored in header */
 
348
                wsvqa->audio_frame_counter += AV_RL16(pkt->data) / wsvqa->audio_channels;
 
349
            } else {
 
350
                pkt->stream_index = wsvqa->video_stream_index;
 
351
                wsvqa->video_pts += VQA_VIDEO_PTS_INC;
 
352
            }
 
353
            /* stay on 16-bit alignment */
 
354
            if (skip_byte)
 
355
                url_fseek(pb, 1, SEEK_CUR);
 
356
 
 
357
            return ret;
 
358
        } else {
 
359
            switch(chunk_type){
 
360
            case CMDS_TAG:
 
361
            case SND0_TAG:
 
362
                break;
 
363
            default:
 
364
                av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type);
 
365
            }
 
366
            url_fseek(pb, chunk_size + skip_byte, SEEK_CUR);
 
367
        }
 
368
    }
 
369
 
 
370
    return ret;
 
371
}
 
372
 
 
373
#ifdef CONFIG_WSAUD_DEMUXER
 
374
AVInputFormat wsaud_demuxer = {
 
375
    "wsaud",
 
376
    NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
 
377
    sizeof(WsAudDemuxContext),
 
378
    wsaud_probe,
 
379
    wsaud_read_header,
 
380
    wsaud_read_packet,
 
381
};
 
382
#endif
 
383
#ifdef CONFIG_WSVQA_DEMUXER
 
384
AVInputFormat wsvqa_demuxer = {
 
385
    "wsvqa",
 
386
    NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
 
387
    sizeof(WsVqaDemuxContext),
 
388
    wsvqa_probe,
 
389
    wsvqa_read_header,
 
390
    wsvqa_read_packet,
 
391
};
 
392
#endif