2 * Westwood Studios Multimedia Formats Demuxer (VQA, AUD)
3 * Copyright (c) 2003 The ffmpeg Project
5 * This file is part of FFmpeg.
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.
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.
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
23 * @file libavformat/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
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.
36 #include "libavutil/intreadwrite.h"
39 #define AUD_HEADER_SIZE 12
40 #define AUD_CHUNK_PREAMBLE_SIZE 8
41 #define AUD_CHUNK_SIGNATURE 0x0000DEAF
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')
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')
61 #define VQA_HEADER_SIZE 0x2A
62 #define VQA_FRAMERATE 15
63 #define VQA_VIDEO_PTS_INC (90000 / VQA_FRAMERATE)
64 #define VQA_PREAMBLE_SIZE 8
66 typedef struct WsAudDemuxContext
{
70 enum CodecID audio_type
;
71 int audio_stream_index
;
72 int64_t audio_frame_counter
;
75 typedef struct WsVqaDemuxContext
{
80 int audio_stream_index
;
81 int video_stream_index
;
83 int64_t audio_frame_counter
;
87 static int wsaud_probe(AVProbeData
*p
)
91 /* Probabilistic content detection strategy: There is no file signature
92 * so perform sanity checks on various header parameters:
93 * 8000 <= sample rate (16 bits) <= 48000 ==> 40001 acceptable numbers
94 * flags <= 0x03 (2 LSBs are used) ==> 4 acceptable numbers
95 * compression type (8 bits) = 1 or 99 ==> 2 acceptable numbers
96 * first audio chunk signature (32 bits) ==> 1 acceptable number
97 * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 =
98 * 320008 acceptable number combinations.
101 if (p
->buf_size
< AUD_HEADER_SIZE
+ AUD_CHUNK_PREAMBLE_SIZE
)
104 /* check sample rate */
105 field
= AV_RL16(&p
->buf
[0]);
106 if ((field
< 8000) || (field
> 48000))
109 /* enforce the rule that the top 6 bits of this flags field are reserved (0);
110 * this might not be true, but enforce it until deemed unnecessary */
111 if (p
->buf
[10] & 0xFC)
114 /* note: only check for WS IMA (type 99) right now since there is no
115 * support for type 1 */
116 if (p
->buf
[11] != 99)
119 /* read ahead to the first audio chunk and validate the first header signature */
120 if (AV_RL32(&p
->buf
[16]) != AUD_CHUNK_SIGNATURE
)
123 /* return 1/2 certainty since this file check is a little sketchy */
124 return AVPROBE_SCORE_MAX
/ 2;
127 static int wsaud_read_header(AVFormatContext
*s
,
128 AVFormatParameters
*ap
)
130 WsAudDemuxContext
*wsaud
= s
->priv_data
;
131 ByteIOContext
*pb
= s
->pb
;
133 unsigned char header
[AUD_HEADER_SIZE
];
135 if (get_buffer(pb
, header
, AUD_HEADER_SIZE
) != AUD_HEADER_SIZE
)
137 wsaud
->audio_samplerate
= AV_RL16(&header
[0]);
138 if (header
[11] == 99)
139 wsaud
->audio_type
= CODEC_ID_ADPCM_IMA_WS
;
141 return AVERROR_INVALIDDATA
;
143 /* flag 0 indicates stereo */
144 wsaud
->audio_channels
= (header
[10] & 0x1) + 1;
145 /* flag 1 indicates 16 bit audio */
146 wsaud
->audio_bits
= (((header
[10] & 0x2) >> 1) + 1) * 8;
148 /* initialize the audio decoder stream */
149 st
= av_new_stream(s
, 0);
151 return AVERROR(ENOMEM
);
152 av_set_pts_info(st
, 33, 1, wsaud
->audio_samplerate
);
153 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
154 st
->codec
->codec_id
= wsaud
->audio_type
;
155 st
->codec
->codec_tag
= 0; /* no tag */
156 st
->codec
->channels
= wsaud
->audio_channels
;
157 st
->codec
->sample_rate
= wsaud
->audio_samplerate
;
158 st
->codec
->bits_per_coded_sample
= wsaud
->audio_bits
;
159 st
->codec
->bit_rate
= st
->codec
->channels
* st
->codec
->sample_rate
*
160 st
->codec
->bits_per_coded_sample
/ 4;
161 st
->codec
->block_align
= st
->codec
->channels
* st
->codec
->bits_per_coded_sample
;
163 wsaud
->audio_stream_index
= st
->index
;
164 wsaud
->audio_frame_counter
= 0;
169 static int wsaud_read_packet(AVFormatContext
*s
,
172 WsAudDemuxContext
*wsaud
= s
->priv_data
;
173 ByteIOContext
*pb
= s
->pb
;
174 unsigned char preamble
[AUD_CHUNK_PREAMBLE_SIZE
];
175 unsigned int chunk_size
;
178 if (get_buffer(pb
, preamble
, AUD_CHUNK_PREAMBLE_SIZE
) !=
179 AUD_CHUNK_PREAMBLE_SIZE
)
182 /* validate the chunk */
183 if (AV_RL32(&preamble
[4]) != AUD_CHUNK_SIGNATURE
)
184 return AVERROR_INVALIDDATA
;
186 chunk_size
= AV_RL16(&preamble
[0]);
187 ret
= av_get_packet(pb
, pkt
, chunk_size
);
188 if (ret
!= chunk_size
)
190 pkt
->stream_index
= wsaud
->audio_stream_index
;
191 pkt
->pts
= wsaud
->audio_frame_counter
;
192 pkt
->pts
/= wsaud
->audio_samplerate
;
194 /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
195 wsaud
->audio_frame_counter
+= (chunk_size
* 2) / wsaud
->audio_channels
;
200 static int wsvqa_probe(AVProbeData
*p
)
202 /* need 12 bytes to qualify */
203 if (p
->buf_size
< 12)
206 /* check for the VQA signatures */
207 if ((AV_RB32(&p
->buf
[0]) != FORM_TAG
) ||
208 (AV_RB32(&p
->buf
[8]) != WVQA_TAG
))
211 return AVPROBE_SCORE_MAX
;
214 static int wsvqa_read_header(AVFormatContext
*s
,
215 AVFormatParameters
*ap
)
217 WsVqaDemuxContext
*wsvqa
= s
->priv_data
;
218 ByteIOContext
*pb
= s
->pb
;
220 unsigned char *header
;
221 unsigned char scratch
[VQA_PREAMBLE_SIZE
];
222 unsigned int chunk_tag
;
223 unsigned int chunk_size
;
225 /* initialize the video decoder stream */
226 st
= av_new_stream(s
, 0);
228 return AVERROR(ENOMEM
);
229 av_set_pts_info(st
, 33, 1, VQA_FRAMERATE
);
230 wsvqa
->video_stream_index
= st
->index
;
231 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
232 st
->codec
->codec_id
= CODEC_ID_WS_VQA
;
233 st
->codec
->codec_tag
= 0; /* no fourcc */
235 /* skip to the start of the VQA header */
236 url_fseek(pb
, 20, SEEK_SET
);
238 /* the VQA header needs to go to the decoder */
239 st
->codec
->extradata_size
= VQA_HEADER_SIZE
;
240 st
->codec
->extradata
= av_mallocz(VQA_HEADER_SIZE
+ FF_INPUT_BUFFER_PADDING_SIZE
);
241 header
= (unsigned char *)st
->codec
->extradata
;
242 if (get_buffer(pb
, st
->codec
->extradata
, VQA_HEADER_SIZE
) !=
244 av_free(st
->codec
->extradata
);
247 st
->codec
->width
= AV_RL16(&header
[6]);
248 st
->codec
->height
= AV_RL16(&header
[8]);
250 /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
251 if (AV_RL16(&header
[24]) || (AV_RL16(&header
[0]) == 1 && AV_RL16(&header
[2]) == 1)) {
252 st
= av_new_stream(s
, 0);
254 return AVERROR(ENOMEM
);
255 av_set_pts_info(st
, 33, 1, VQA_FRAMERATE
);
256 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
257 if (AV_RL16(&header
[0]) == 1)
258 st
->codec
->codec_id
= CODEC_ID_WESTWOOD_SND1
;
260 st
->codec
->codec_id
= CODEC_ID_ADPCM_IMA_WS
;
261 st
->codec
->codec_tag
= 0; /* no tag */
262 st
->codec
->sample_rate
= AV_RL16(&header
[24]);
263 if (!st
->codec
->sample_rate
)
264 st
->codec
->sample_rate
= 22050;
265 st
->codec
->channels
= header
[26];
266 if (!st
->codec
->channels
)
267 st
->codec
->channels
= 1;
268 st
->codec
->bits_per_coded_sample
= 16;
269 st
->codec
->bit_rate
= st
->codec
->channels
* st
->codec
->sample_rate
*
270 st
->codec
->bits_per_coded_sample
/ 4;
271 st
->codec
->block_align
= st
->codec
->channels
* st
->codec
->bits_per_coded_sample
;
273 wsvqa
->audio_stream_index
= st
->index
;
274 wsvqa
->audio_samplerate
= st
->codec
->sample_rate
;
275 wsvqa
->audio_channels
= st
->codec
->channels
;
276 wsvqa
->audio_frame_counter
= 0;
279 /* there are 0 or more chunks before the FINF chunk; iterate until
280 * FINF has been skipped and the file will be ready to be demuxed */
282 if (get_buffer(pb
, scratch
, VQA_PREAMBLE_SIZE
) != VQA_PREAMBLE_SIZE
) {
283 av_free(st
->codec
->extradata
);
286 chunk_tag
= AV_RB32(&scratch
[0]);
287 chunk_size
= AV_RB32(&scratch
[4]);
289 /* catch any unknown header tags, for curiousity */
302 av_log (s
, AV_LOG_ERROR
, " note: unknown chunk seen (%c%c%c%c)\n",
303 scratch
[0], scratch
[1],
304 scratch
[2], scratch
[3]);
308 url_fseek(pb
, chunk_size
, SEEK_CUR
);
309 } while (chunk_tag
!= FINF_TAG
);
311 wsvqa
->video_pts
= wsvqa
->audio_frame_counter
= 0;
316 static int wsvqa_read_packet(AVFormatContext
*s
,
319 WsVqaDemuxContext
*wsvqa
= s
->priv_data
;
320 ByteIOContext
*pb
= s
->pb
;
322 unsigned char preamble
[VQA_PREAMBLE_SIZE
];
323 unsigned int chunk_type
;
324 unsigned int chunk_size
;
327 while (get_buffer(pb
, preamble
, VQA_PREAMBLE_SIZE
) == VQA_PREAMBLE_SIZE
) {
328 chunk_type
= AV_RB32(&preamble
[0]);
329 chunk_size
= AV_RB32(&preamble
[4]);
330 skip_byte
= chunk_size
& 0x01;
332 if ((chunk_type
== SND1_TAG
) || (chunk_type
== SND2_TAG
) || (chunk_type
== VQFR_TAG
)) {
334 if (av_new_packet(pkt
, chunk_size
))
336 ret
= get_buffer(pb
, pkt
->data
, chunk_size
);
337 if (ret
!= chunk_size
) {
342 if (chunk_type
== SND2_TAG
) {
343 pkt
->stream_index
= wsvqa
->audio_stream_index
;
344 /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
345 wsvqa
->audio_frame_counter
+= (chunk_size
* 2) / wsvqa
->audio_channels
;
346 } else if(chunk_type
== SND1_TAG
) {
347 pkt
->stream_index
= wsvqa
->audio_stream_index
;
348 /* unpacked size is stored in header */
349 wsvqa
->audio_frame_counter
+= AV_RL16(pkt
->data
) / wsvqa
->audio_channels
;
351 pkt
->stream_index
= wsvqa
->video_stream_index
;
352 wsvqa
->video_pts
+= VQA_VIDEO_PTS_INC
;
354 /* stay on 16-bit alignment */
356 url_fseek(pb
, 1, SEEK_CUR
);
365 av_log(s
, AV_LOG_INFO
, "Skipping unknown chunk 0x%08X\n", chunk_type
);
367 url_fseek(pb
, chunk_size
+ skip_byte
, SEEK_CUR
);
374 #if CONFIG_WSAUD_DEMUXER
375 AVInputFormat wsaud_demuxer
= {
377 NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
378 sizeof(WsAudDemuxContext
),
384 #if CONFIG_WSVQA_DEMUXER
385 AVInputFormat wsvqa_demuxer
= {
387 NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
388 sizeof(WsVqaDemuxContext
),