Libav
|
00001 /* 00002 * Westwood Studios Multimedia Formats Demuxer (VQA, AUD) 00003 * Copyright (c) 2003 The ffmpeg Project 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00036 #include "libavutil/intreadwrite.h" 00037 #include "avformat.h" 00038 00039 #define AUD_HEADER_SIZE 12 00040 #define AUD_CHUNK_PREAMBLE_SIZE 8 00041 #define AUD_CHUNK_SIGNATURE 0x0000DEAF 00042 00043 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M') 00044 #define WVQA_TAG MKBETAG('W', 'V', 'Q', 'A') 00045 #define VQHD_TAG MKBETAG('V', 'Q', 'H', 'D') 00046 #define FINF_TAG MKBETAG('F', 'I', 'N', 'F') 00047 #define SND0_TAG MKBETAG('S', 'N', 'D', '0') 00048 #define SND1_TAG MKBETAG('S', 'N', 'D', '1') 00049 #define SND2_TAG MKBETAG('S', 'N', 'D', '2') 00050 #define VQFR_TAG MKBETAG('V', 'Q', 'F', 'R') 00051 00052 /* don't know what these tags are for, but acknowledge their existence */ 00053 #define CINF_TAG MKBETAG('C', 'I', 'N', 'F') 00054 #define CINH_TAG MKBETAG('C', 'I', 'N', 'H') 00055 #define CIND_TAG MKBETAG('C', 'I', 'N', 'D') 00056 #define PINF_TAG MKBETAG('P', 'I', 'N', 'F') 00057 #define PINH_TAG MKBETAG('P', 'I', 'N', 'H') 00058 #define PIND_TAG MKBETAG('P', 'I', 'N', 'D') 00059 #define CMDS_TAG MKBETAG('C', 'M', 'D', 'S') 00060 00061 #define VQA_HEADER_SIZE 0x2A 00062 #define VQA_FRAMERATE 15 00063 #define VQA_PREAMBLE_SIZE 8 00064 00065 typedef struct WsAudDemuxContext { 00066 int audio_samplerate; 00067 int audio_channels; 00068 int audio_bits; 00069 enum CodecID audio_type; 00070 int audio_stream_index; 00071 int64_t audio_frame_counter; 00072 } WsAudDemuxContext; 00073 00074 typedef struct WsVqaDemuxContext { 00075 int audio_samplerate; 00076 int audio_channels; 00077 int audio_bits; 00078 00079 int audio_stream_index; 00080 int video_stream_index; 00081 00082 int64_t audio_frame_counter; 00083 } WsVqaDemuxContext; 00084 00085 static int wsaud_probe(AVProbeData *p) 00086 { 00087 int field; 00088 00089 /* Probabilistic content detection strategy: There is no file signature 00090 * so perform sanity checks on various header parameters: 00091 * 8000 <= sample rate (16 bits) <= 48000 ==> 40001 acceptable numbers 00092 * flags <= 0x03 (2 LSBs are used) ==> 4 acceptable numbers 00093 * compression type (8 bits) = 1 or 99 ==> 2 acceptable numbers 00094 * first audio chunk signature (32 bits) ==> 1 acceptable number 00095 * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 = 00096 * 320008 acceptable number combinations. 00097 */ 00098 00099 if (p->buf_size < AUD_HEADER_SIZE + AUD_CHUNK_PREAMBLE_SIZE) 00100 return 0; 00101 00102 /* check sample rate */ 00103 field = AV_RL16(&p->buf[0]); 00104 if ((field < 8000) || (field > 48000)) 00105 return 0; 00106 00107 /* enforce the rule that the top 6 bits of this flags field are reserved (0); 00108 * this might not be true, but enforce it until deemed unnecessary */ 00109 if (p->buf[10] & 0xFC) 00110 return 0; 00111 00112 /* note: only check for WS IMA (type 99) right now since there is no 00113 * support for type 1 */ 00114 if (p->buf[11] != 99) 00115 return 0; 00116 00117 /* read ahead to the first audio chunk and validate the first header signature */ 00118 if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE) 00119 return 0; 00120 00121 /* return 1/2 certainty since this file check is a little sketchy */ 00122 return AVPROBE_SCORE_MAX / 2; 00123 } 00124 00125 static int wsaud_read_header(AVFormatContext *s, 00126 AVFormatParameters *ap) 00127 { 00128 WsAudDemuxContext *wsaud = s->priv_data; 00129 ByteIOContext *pb = s->pb; 00130 AVStream *st; 00131 unsigned char header[AUD_HEADER_SIZE]; 00132 00133 if (get_buffer(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE) 00134 return AVERROR(EIO); 00135 wsaud->audio_samplerate = AV_RL16(&header[0]); 00136 if (header[11] == 99) 00137 wsaud->audio_type = CODEC_ID_ADPCM_IMA_WS; 00138 else 00139 return AVERROR_INVALIDDATA; 00140 00141 /* flag 0 indicates stereo */ 00142 wsaud->audio_channels = (header[10] & 0x1) + 1; 00143 /* flag 1 indicates 16 bit audio */ 00144 wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8; 00145 00146 /* initialize the audio decoder stream */ 00147 st = av_new_stream(s, 0); 00148 if (!st) 00149 return AVERROR(ENOMEM); 00150 av_set_pts_info(st, 33, 1, wsaud->audio_samplerate); 00151 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00152 st->codec->codec_id = wsaud->audio_type; 00153 st->codec->codec_tag = 0; /* no tag */ 00154 st->codec->channels = wsaud->audio_channels; 00155 st->codec->sample_rate = wsaud->audio_samplerate; 00156 st->codec->bits_per_coded_sample = wsaud->audio_bits; 00157 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 00158 st->codec->bits_per_coded_sample / 4; 00159 st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; 00160 00161 wsaud->audio_stream_index = st->index; 00162 wsaud->audio_frame_counter = 0; 00163 00164 return 0; 00165 } 00166 00167 static int wsaud_read_packet(AVFormatContext *s, 00168 AVPacket *pkt) 00169 { 00170 WsAudDemuxContext *wsaud = s->priv_data; 00171 ByteIOContext *pb = s->pb; 00172 unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE]; 00173 unsigned int chunk_size; 00174 int ret = 0; 00175 00176 if (get_buffer(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) != 00177 AUD_CHUNK_PREAMBLE_SIZE) 00178 return AVERROR(EIO); 00179 00180 /* validate the chunk */ 00181 if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE) 00182 return AVERROR_INVALIDDATA; 00183 00184 chunk_size = AV_RL16(&preamble[0]); 00185 ret= av_get_packet(pb, pkt, chunk_size); 00186 if (ret != chunk_size) 00187 return AVERROR(EIO); 00188 pkt->stream_index = wsaud->audio_stream_index; 00189 pkt->pts = wsaud->audio_frame_counter; 00190 pkt->pts /= wsaud->audio_samplerate; 00191 00192 /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ 00193 wsaud->audio_frame_counter += (chunk_size * 2) / wsaud->audio_channels; 00194 00195 return ret; 00196 } 00197 00198 static int wsvqa_probe(AVProbeData *p) 00199 { 00200 /* need 12 bytes to qualify */ 00201 if (p->buf_size < 12) 00202 return 0; 00203 00204 /* check for the VQA signatures */ 00205 if ((AV_RB32(&p->buf[0]) != FORM_TAG) || 00206 (AV_RB32(&p->buf[8]) != WVQA_TAG)) 00207 return 0; 00208 00209 return AVPROBE_SCORE_MAX; 00210 } 00211 00212 static int wsvqa_read_header(AVFormatContext *s, 00213 AVFormatParameters *ap) 00214 { 00215 WsVqaDemuxContext *wsvqa = s->priv_data; 00216 ByteIOContext *pb = s->pb; 00217 AVStream *st; 00218 unsigned char *header; 00219 unsigned char scratch[VQA_PREAMBLE_SIZE]; 00220 unsigned int chunk_tag; 00221 unsigned int chunk_size; 00222 00223 /* initialize the video decoder stream */ 00224 st = av_new_stream(s, 0); 00225 if (!st) 00226 return AVERROR(ENOMEM); 00227 av_set_pts_info(st, 33, 1, VQA_FRAMERATE); 00228 wsvqa->video_stream_index = st->index; 00229 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 00230 st->codec->codec_id = CODEC_ID_WS_VQA; 00231 st->codec->codec_tag = 0; /* no fourcc */ 00232 00233 /* skip to the start of the VQA header */ 00234 url_fseek(pb, 20, SEEK_SET); 00235 00236 /* the VQA header needs to go to the decoder */ 00237 st->codec->extradata_size = VQA_HEADER_SIZE; 00238 st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); 00239 header = (unsigned char *)st->codec->extradata; 00240 if (get_buffer(pb, st->codec->extradata, VQA_HEADER_SIZE) != 00241 VQA_HEADER_SIZE) { 00242 av_free(st->codec->extradata); 00243 return AVERROR(EIO); 00244 } 00245 st->codec->width = AV_RL16(&header[6]); 00246 st->codec->height = AV_RL16(&header[8]); 00247 00248 /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */ 00249 if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) { 00250 st = av_new_stream(s, 0); 00251 if (!st) 00252 return AVERROR(ENOMEM); 00253 av_set_pts_info(st, 33, 1, VQA_FRAMERATE); 00254 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00255 if (AV_RL16(&header[0]) == 1) 00256 st->codec->codec_id = CODEC_ID_WESTWOOD_SND1; 00257 else 00258 st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; 00259 st->codec->codec_tag = 0; /* no tag */ 00260 st->codec->sample_rate = AV_RL16(&header[24]); 00261 if (!st->codec->sample_rate) 00262 st->codec->sample_rate = 22050; 00263 st->codec->channels = header[26]; 00264 if (!st->codec->channels) 00265 st->codec->channels = 1; 00266 st->codec->bits_per_coded_sample = 16; 00267 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 00268 st->codec->bits_per_coded_sample / 4; 00269 st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; 00270 00271 wsvqa->audio_stream_index = st->index; 00272 wsvqa->audio_samplerate = st->codec->sample_rate; 00273 wsvqa->audio_channels = st->codec->channels; 00274 wsvqa->audio_frame_counter = 0; 00275 } 00276 00277 /* there are 0 or more chunks before the FINF chunk; iterate until 00278 * FINF has been skipped and the file will be ready to be demuxed */ 00279 do { 00280 if (get_buffer(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) { 00281 av_free(st->codec->extradata); 00282 return AVERROR(EIO); 00283 } 00284 chunk_tag = AV_RB32(&scratch[0]); 00285 chunk_size = AV_RB32(&scratch[4]); 00286 00287 /* catch any unknown header tags, for curiousity */ 00288 switch (chunk_tag) { 00289 case CINF_TAG: 00290 case CINH_TAG: 00291 case CIND_TAG: 00292 case PINF_TAG: 00293 case PINH_TAG: 00294 case PIND_TAG: 00295 case FINF_TAG: 00296 case CMDS_TAG: 00297 break; 00298 00299 default: 00300 av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n", 00301 scratch[0], scratch[1], 00302 scratch[2], scratch[3]); 00303 break; 00304 } 00305 00306 url_fseek(pb, chunk_size, SEEK_CUR); 00307 } while (chunk_tag != FINF_TAG); 00308 00309 return 0; 00310 } 00311 00312 static int wsvqa_read_packet(AVFormatContext *s, 00313 AVPacket *pkt) 00314 { 00315 WsVqaDemuxContext *wsvqa = s->priv_data; 00316 ByteIOContext *pb = s->pb; 00317 int ret = -1; 00318 unsigned char preamble[VQA_PREAMBLE_SIZE]; 00319 unsigned int chunk_type; 00320 unsigned int chunk_size; 00321 int skip_byte; 00322 00323 while (get_buffer(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) { 00324 chunk_type = AV_RB32(&preamble[0]); 00325 chunk_size = AV_RB32(&preamble[4]); 00326 skip_byte = chunk_size & 0x01; 00327 00328 if ((chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) { 00329 00330 if (av_new_packet(pkt, chunk_size)) 00331 return AVERROR(EIO); 00332 ret = get_buffer(pb, pkt->data, chunk_size); 00333 if (ret != chunk_size) { 00334 av_free_packet(pkt); 00335 return AVERROR(EIO); 00336 } 00337 00338 if (chunk_type == SND2_TAG) { 00339 pkt->stream_index = wsvqa->audio_stream_index; 00340 /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ 00341 wsvqa->audio_frame_counter += (chunk_size * 2) / wsvqa->audio_channels; 00342 } else if(chunk_type == SND1_TAG) { 00343 pkt->stream_index = wsvqa->audio_stream_index; 00344 /* unpacked size is stored in header */ 00345 wsvqa->audio_frame_counter += AV_RL16(pkt->data) / wsvqa->audio_channels; 00346 } else { 00347 pkt->stream_index = wsvqa->video_stream_index; 00348 } 00349 /* stay on 16-bit alignment */ 00350 if (skip_byte) 00351 url_fseek(pb, 1, SEEK_CUR); 00352 00353 return ret; 00354 } else { 00355 switch(chunk_type){ 00356 case CMDS_TAG: 00357 case SND0_TAG: 00358 break; 00359 default: 00360 av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type); 00361 } 00362 url_fseek(pb, chunk_size + skip_byte, SEEK_CUR); 00363 } 00364 } 00365 00366 return ret; 00367 } 00368 00369 #if CONFIG_WSAUD_DEMUXER 00370 AVInputFormat wsaud_demuxer = { 00371 "wsaud", 00372 NULL_IF_CONFIG_SMALL("Westwood Studios audio format"), 00373 sizeof(WsAudDemuxContext), 00374 wsaud_probe, 00375 wsaud_read_header, 00376 wsaud_read_packet, 00377 }; 00378 #endif 00379 #if CONFIG_WSVQA_DEMUXER 00380 AVInputFormat wsvqa_demuxer = { 00381 "wsvqa", 00382 NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"), 00383 sizeof(WsVqaDemuxContext), 00384 wsvqa_probe, 00385 wsvqa_read_header, 00386 wsvqa_read_packet, 00387 }; 00388 #endif