aud: support Westwood SND1 audio in AUD files.
[ffmpeg.git] / libavformat / westwood_aud.c
1 /*
2  * Westwood Studios AUD Format Demuxer
3  * Copyright (c) 2003 The ffmpeg Project
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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 AUD file demuxer
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 #include "internal.h"
39
40 #define AUD_HEADER_SIZE 12
41 #define AUD_CHUNK_PREAMBLE_SIZE 8
42 #define AUD_CHUNK_SIGNATURE 0x0000DEAF
43
44 typedef struct WsAudDemuxContext {
45     int audio_samplerate;
46     int audio_channels;
47     int audio_bits;
48     enum CodecID audio_type;
49     int audio_stream_index;
50     int64_t audio_frame_counter;
51 } WsAudDemuxContext;
52
53 static int wsaud_probe(AVProbeData *p)
54 {
55     int field;
56
57     /* Probabilistic content detection strategy: There is no file signature
58      * so perform sanity checks on various header parameters:
59      *   8000 <= sample rate (16 bits) <= 48000  ==> 40001 acceptable numbers
60      *   flags <= 0x03 (2 LSBs are used)         ==> 4 acceptable numbers
61      *   compression type (8 bits) = 1 or 99     ==> 2 acceptable numbers
62      *   first audio chunk signature (32 bits)   ==> 1 acceptable number
63      * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 =
64      * 320008 acceptable number combinations.
65      */
66
67     if (p->buf_size < AUD_HEADER_SIZE + AUD_CHUNK_PREAMBLE_SIZE)
68         return 0;
69
70     /* check sample rate */
71     field = AV_RL16(&p->buf[0]);
72     if ((field < 8000) || (field > 48000))
73         return 0;
74
75     /* enforce the rule that the top 6 bits of this flags field are reserved (0);
76      * this might not be true, but enforce it until deemed unnecessary */
77     if (p->buf[10] & 0xFC)
78         return 0;
79
80     /* note: only check for WS IMA (type 99) right now since there is no
81      * support for type 1 */
82     if (p->buf[11] != 99 && p->buf[11] != 1)
83         return 0;
84
85     /* read ahead to the first audio chunk and validate the first header signature */
86     if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE)
87         return 0;
88
89     /* return 1/2 certainty since this file check is a little sketchy */
90     return AVPROBE_SCORE_MAX / 2;
91 }
92
93 static int wsaud_read_header(AVFormatContext *s,
94                              AVFormatParameters *ap)
95 {
96     WsAudDemuxContext *wsaud = s->priv_data;
97     AVIOContext *pb = s->pb;
98     AVStream *st;
99     unsigned char header[AUD_HEADER_SIZE];
100
101     if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE)
102         return AVERROR(EIO);
103     wsaud->audio_samplerate = AV_RL16(&header[0]);
104     if (header[11] == 99)
105         wsaud->audio_type = CODEC_ID_ADPCM_IMA_WS;
106     else if (header[11] == 1)
107         wsaud->audio_type = CODEC_ID_WESTWOOD_SND1;
108     else
109         return AVERROR_INVALIDDATA;
110
111     /* flag 0 indicates stereo */
112     wsaud->audio_channels = (header[10] & 0x1) + 1;
113     /* flag 1 indicates 16 bit audio */
114     wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8;
115
116     /* initialize the audio decoder stream */
117     st = avformat_new_stream(s, NULL);
118     if (!st)
119         return AVERROR(ENOMEM);
120     avpriv_set_pts_info(st, 33, 1, wsaud->audio_samplerate);
121     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
122     st->codec->codec_id = wsaud->audio_type;
123     st->codec->codec_tag = 0;  /* no tag */
124     st->codec->channels = wsaud->audio_channels;
125     st->codec->sample_rate = wsaud->audio_samplerate;
126     if (st->codec->codec_id == CODEC_ID_ADPCM_IMA_WS) {
127         st->codec->bits_per_coded_sample = 4;
128         st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 4;
129     }
130
131     wsaud->audio_stream_index = st->index;
132     wsaud->audio_frame_counter = 0;
133
134     return 0;
135 }
136
137 static int wsaud_read_packet(AVFormatContext *s,
138                              AVPacket *pkt)
139 {
140     WsAudDemuxContext *wsaud = s->priv_data;
141     AVIOContext *pb = s->pb;
142     unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
143     unsigned int chunk_size;
144     int ret = 0;
145     AVStream *st = s->streams[wsaud->audio_stream_index];
146
147     if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
148         AUD_CHUNK_PREAMBLE_SIZE)
149         return AVERROR(EIO);
150
151     /* validate the chunk */
152     if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE)
153         return AVERROR_INVALIDDATA;
154
155     chunk_size = AV_RL16(&preamble[0]);
156
157     if (st->codec->codec_id == CODEC_ID_WESTWOOD_SND1) {
158         /* For Westwood SND1 audio we need to add the output size and input
159            size to the start of the packet to match what is in VQA.
160            Specifically, this is needed to signal when a packet should be
161            decoding as raw 8-bit pcm or variable-size ADPCM. */
162         int out_size = AV_RL16(&preamble[2]);
163         if ((ret = av_new_packet(pkt, chunk_size + 4)))
164             return ret;
165         if ((ret = avio_read(pb, &pkt->data[4], chunk_size)) != chunk_size)
166             return ret < 0 ? ret : AVERROR(EIO);
167         AV_WL16(&pkt->data[0], out_size);
168         AV_WL16(&pkt->data[2], chunk_size);
169
170         pkt->duration = out_size;
171     } else {
172     ret= av_get_packet(pb, pkt, chunk_size);
173     if (ret != chunk_size)
174         return AVERROR(EIO);
175     pkt->pts = wsaud->audio_frame_counter;
176     pkt->pts /= wsaud->audio_samplerate;
177
178     /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
179     wsaud->audio_frame_counter += (chunk_size * 2) / wsaud->audio_channels;
180     }
181     pkt->stream_index = st->index;
182
183     return ret;
184 }
185
186 AVInputFormat ff_wsaud_demuxer = {
187     .name           = "wsaud",
188     .long_name      = NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
189     .priv_data_size = sizeof(WsAudDemuxContext),
190     .read_probe     = wsaud_probe,
191     .read_header    = wsaud_read_header,
192     .read_packet    = wsaud_read_packet,
193 };