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_PREAMBLE_SIZE 8
65 typedef struct WsAudDemuxContext
{
69 enum CodecID audio_type
;
70 int audio_stream_index
;
71 int64_t audio_frame_counter
;
74 typedef struct WsVqaDemuxContext
{
79 int audio_stream_index
;
80 int video_stream_index
;
82 int64_t audio_frame_counter
;
85 static int wsaud_probe(AVProbeData
*p
)
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.
99 if (p
->buf_size
< AUD_HEADER_SIZE
+ AUD_CHUNK_PREAMBLE_SIZE
)
102 /* check sample rate */
103 field
= AV_RL16(&p
->buf
[0]);
104 if ((field
< 8000) || (field
> 48000))
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)
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)
117 /* read ahead to the first audio chunk and validate the first header signature */
118 if (AV_RL32(&p
->buf
[16]) != AUD_CHUNK_SIGNATURE
)
121 /* return 1/2 certainty since this file check is a little sketchy */
122 return AVPROBE_SCORE_MAX
/ 2;
125 static int wsaud_read_header(AVFormatContext
*s
,
126 AVFormatParameters
*ap
)
128 WsAudDemuxContext
*wsaud
= s
->priv_data
;
129 ByteIOContext
*pb
= s
->pb
;
131 unsigned char header
[AUD_HEADER_SIZE
];
133 if (get_buffer(pb
, header
, AUD_HEADER_SIZE
) != AUD_HEADER_SIZE
)
135 wsaud
->audio_samplerate
= AV_RL16(&header
[0]);
136 if (header
[11] == 99)
137 wsaud
->audio_type
= CODEC_ID_ADPCM_IMA_WS
;
139 return AVERROR_INVALIDDATA
;
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;
146 /* initialize the audio decoder stream */
147 st
= av_new_stream(s
, 0);
149 return AVERROR(ENOMEM
);
150 av_set_pts_info(st
, 33, 1, wsaud
->audio_samplerate
);
151 st
->codec
->codec_type
= CODEC_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
;
161 wsaud
->audio_stream_index
= st
->index
;
162 wsaud
->audio_frame_counter
= 0;
167 static int wsaud_read_packet(AVFormatContext
*s
,
170 WsAudDemuxContext
*wsaud
= s
->priv_data
;
171 ByteIOContext
*pb
= s
->pb
;
172 unsigned char preamble
[AUD_CHUNK_PREAMBLE_SIZE
];
173 unsigned int chunk_size
;
176 if (get_buffer(pb
, preamble
, AUD_CHUNK_PREAMBLE_SIZE
) !=
177 AUD_CHUNK_PREAMBLE_SIZE
)
180 /* validate the chunk */
181 if (AV_RL32(&preamble
[4]) != AUD_CHUNK_SIGNATURE
)
182 return AVERROR_INVALIDDATA
;
184 chunk_size
= AV_RL16(&preamble
[0]);
185 ret
= av_get_packet(pb
, pkt
, chunk_size
);
186 if (ret
!= chunk_size
)
188 pkt
->stream_index
= wsaud
->audio_stream_index
;
189 pkt
->pts
= wsaud
->audio_frame_counter
;
190 pkt
->pts
/= wsaud
->audio_samplerate
;
192 /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
193 wsaud
->audio_frame_counter
+= (chunk_size
* 2) / wsaud
->audio_channels
;
198 static int wsvqa_probe(AVProbeData
*p
)
200 /* need 12 bytes to qualify */
201 if (p
->buf_size
< 12)
204 /* check for the VQA signatures */
205 if ((AV_RB32(&p
->buf
[0]) != FORM_TAG
) ||
206 (AV_RB32(&p
->buf
[8]) != WVQA_TAG
))
209 return AVPROBE_SCORE_MAX
;
212 static int wsvqa_read_header(AVFormatContext
*s
,
213 AVFormatParameters
*ap
)
215 WsVqaDemuxContext
*wsvqa
= s
->priv_data
;
216 ByteIOContext
*pb
= s
->pb
;
218 unsigned char *header
;
219 unsigned char scratch
[VQA_PREAMBLE_SIZE
];
220 unsigned int chunk_tag
;
221 unsigned int chunk_size
;
223 /* initialize the video decoder stream */
224 st
= av_new_stream(s
, 0);
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
= CODEC_TYPE_VIDEO
;
230 st
->codec
->codec_id
= CODEC_ID_WS_VQA
;
231 st
->codec
->codec_tag
= 0; /* no fourcc */
233 /* skip to the start of the VQA header */
234 url_fseek(pb
, 20, SEEK_SET
);
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
) !=
242 av_free(st
->codec
->extradata
);
245 st
->codec
->width
= AV_RL16(&header
[6]);
246 st
->codec
->height
= AV_RL16(&header
[8]);
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);
252 return AVERROR(ENOMEM
);
253 av_set_pts_info(st
, 33, 1, VQA_FRAMERATE
);
254 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
255 if (AV_RL16(&header
[0]) == 1)
256 st
->codec
->codec_id
= CODEC_ID_WESTWOOD_SND1
;
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
;
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;
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 */
280 if (get_buffer(pb
, scratch
, VQA_PREAMBLE_SIZE
) != VQA_PREAMBLE_SIZE
) {
281 av_free(st
->codec
->extradata
);
284 chunk_tag
= AV_RB32(&scratch
[0]);
285 chunk_size
= AV_RB32(&scratch
[4]);
287 /* catch any unknown header tags, for curiousity */
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]);
306 url_fseek(pb
, chunk_size
, SEEK_CUR
);
307 } while (chunk_tag
!= FINF_TAG
);
312 static int wsvqa_read_packet(AVFormatContext
*s
,
315 WsVqaDemuxContext
*wsvqa
= s
->priv_data
;
316 ByteIOContext
*pb
= s
->pb
;
318 unsigned char preamble
[VQA_PREAMBLE_SIZE
];
319 unsigned int chunk_type
;
320 unsigned int chunk_size
;
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;
328 if ((chunk_type
== SND1_TAG
) || (chunk_type
== SND2_TAG
) || (chunk_type
== VQFR_TAG
)) {
330 if (av_new_packet(pkt
, chunk_size
))
332 ret
= get_buffer(pb
, pkt
->data
, chunk_size
);
333 if (ret
!= chunk_size
) {
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
;
347 pkt
->stream_index
= wsvqa
->video_stream_index
;
349 /* stay on 16-bit alignment */
351 url_fseek(pb
, 1, SEEK_CUR
);
360 av_log(s
, AV_LOG_INFO
, "Skipping unknown chunk 0x%08X\n", chunk_type
);
362 url_fseek(pb
, chunk_size
+ skip_byte
, SEEK_CUR
);
369 #if CONFIG_WSAUD_DEMUXER
370 AVInputFormat wsaud_demuxer
= {
372 NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
373 sizeof(WsAudDemuxContext
),
379 #if CONFIG_WSVQA_DEMUXER
380 AVInputFormat wsvqa_demuxer
= {
382 NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
383 sizeof(WsVqaDemuxContext
),