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