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