Mercurial > libavformat.hg
comparison westwood.c @ 275:377bd276adaa libavformat
handle a wider variety of VQA files, including silent files
author | tmmm |
---|---|
date | Sat, 04 Oct 2003 17:41:56 +0000 |
parents | 8bb470d85249 |
children | 845f9de2c883 |
comparison
equal
deleted
inserted
replaced
274:9fa2ec3b9982 | 275:377bd276adaa |
---|---|
59 #define FINF_TAG FOURCC_TAG('F', 'I', 'N', 'F') | 59 #define FINF_TAG FOURCC_TAG('F', 'I', 'N', 'F') |
60 #define SND0_TAG FOURCC_TAG('S', 'N', 'D', '0') | 60 #define SND0_TAG FOURCC_TAG('S', 'N', 'D', '0') |
61 #define SND2_TAG FOURCC_TAG('S', 'N', 'D', '2') | 61 #define SND2_TAG FOURCC_TAG('S', 'N', 'D', '2') |
62 #define VQFR_TAG FOURCC_TAG('V', 'Q', 'F', 'R') | 62 #define VQFR_TAG FOURCC_TAG('V', 'Q', 'F', 'R') |
63 | 63 |
64 /* don't know what these tags are for, but acknowledge their existence */ | |
65 #define CINF_TAG FOURCC_TAG('C', 'I', 'N', 'F') | |
66 #define CINH_TAG FOURCC_TAG('C', 'I', 'N', 'H') | |
67 #define CIND_TAG FOURCC_TAG('C', 'I', 'N', 'D') | |
68 #define PINF_TAG FOURCC_TAG('P', 'I', 'N', 'F') | |
69 #define PINH_TAG FOURCC_TAG('P', 'I', 'N', 'H') | |
70 #define PIND_TAG FOURCC_TAG('P', 'I', 'N', 'D') | |
71 | |
64 #define VQA_HEADER_SIZE 0x2A | 72 #define VQA_HEADER_SIZE 0x2A |
65 #define VQA_FRAMERATE 15 | 73 #define VQA_FRAMERATE 15 |
66 #define VQA_VIDEO_PTS_INC (90000 / VQA_FRAMERATE) | 74 #define VQA_VIDEO_PTS_INC (90000 / VQA_FRAMERATE) |
67 #define VQA_PREAMBLE_SIZE 8 | 75 #define VQA_PREAMBLE_SIZE 8 |
68 | 76 |
225 WsVqaDemuxContext *wsvqa = (WsVqaDemuxContext *)s->priv_data; | 233 WsVqaDemuxContext *wsvqa = (WsVqaDemuxContext *)s->priv_data; |
226 ByteIOContext *pb = &s->pb; | 234 ByteIOContext *pb = &s->pb; |
227 AVStream *st; | 235 AVStream *st; |
228 unsigned char *header; | 236 unsigned char *header; |
229 unsigned char scratch[VQA_PREAMBLE_SIZE]; | 237 unsigned char scratch[VQA_PREAMBLE_SIZE]; |
238 unsigned int chunk_tag; | |
239 unsigned int chunk_size; | |
230 | 240 |
231 /* set the pts reference (1 pts = 1/90000) */ | 241 /* set the pts reference (1 pts = 1/90000) */ |
232 s->pts_num = 1; | 242 s->pts_num = 1; |
233 s->pts_den = 90000; | 243 s->pts_den = 90000; |
234 | 244 |
254 return -EIO; | 264 return -EIO; |
255 } | 265 } |
256 st->codec.width = LE_16(&header[6]); | 266 st->codec.width = LE_16(&header[6]); |
257 st->codec.height = LE_16(&header[8]); | 267 st->codec.height = LE_16(&header[8]); |
258 | 268 |
259 /* initialize the audio decoder stream */ | 269 /* initialize the audio decoder stream is sample rate is non-zero */ |
260 st = av_new_stream(s, 0); | 270 if (LE_16(&header[24])) { |
261 if (!st) | 271 st = av_new_stream(s, 0); |
262 return AVERROR_NOMEM; | 272 if (!st) |
263 st->codec.codec_type = CODEC_TYPE_AUDIO; | 273 return AVERROR_NOMEM; |
264 st->codec.codec_id = CODEC_ID_ADPCM_IMA_WS; | 274 st->codec.codec_type = CODEC_TYPE_AUDIO; |
265 st->codec.codec_tag = 0; /* no tag */ | 275 st->codec.codec_id = CODEC_ID_ADPCM_IMA_WS; |
266 st->codec.sample_rate = LE_16(&header[24]); | 276 st->codec.codec_tag = 0; /* no tag */ |
267 st->codec.channels = header[26]; | 277 st->codec.sample_rate = LE_16(&header[24]); |
268 st->codec.bits_per_sample = 16; | 278 st->codec.channels = header[26]; |
269 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * | 279 st->codec.bits_per_sample = 16; |
270 st->codec.bits_per_sample / 4; | 280 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * |
271 st->codec.block_align = st->codec.channels * st->codec.bits_per_sample; | 281 st->codec.bits_per_sample / 4; |
272 | 282 st->codec.block_align = st->codec.channels * st->codec.bits_per_sample; |
273 wsvqa->audio_stream_index = st->index; | 283 |
274 wsvqa->audio_samplerate = st->codec.sample_rate; | 284 wsvqa->audio_stream_index = st->index; |
275 wsvqa->audio_channels = st->codec.channels; | 285 wsvqa->audio_samplerate = st->codec.sample_rate; |
276 wsvqa->audio_frame_counter = 0; | 286 wsvqa->audio_channels = st->codec.channels; |
277 | 287 wsvqa->audio_frame_counter = 0; |
278 /* skip the useless FINF chunk index */ | |
279 if (get_buffer(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) { | |
280 av_free(st->codec.extradata); | |
281 return -EIO; | |
282 } | 288 } |
283 url_fseek(pb, BE_32(&scratch[4]), SEEK_CUR); | 289 |
290 /* there are 0 or more chunks before the FINF chunk; iterate until | |
291 * FINF has been skipped and the file will be ready to be demuxed */ | |
292 do { | |
293 if (get_buffer(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) { | |
294 av_free(st->codec.extradata); | |
295 return -EIO; | |
296 } | |
297 chunk_tag = BE_32(&scratch[0]); | |
298 chunk_size = BE_32(&scratch[4]); | |
299 | |
300 /* catch any unknown header tags, for curiousity */ | |
301 switch (chunk_tag) { | |
302 case CINF_TAG: | |
303 case CINH_TAG: | |
304 case CIND_TAG: | |
305 case PINF_TAG: | |
306 case PINH_TAG: | |
307 case PIND_TAG: | |
308 case FINF_TAG: | |
309 break; | |
310 | |
311 default: | |
312 printf (" note: unknown chunk seen (%c%c%c%c)\n", | |
313 scratch[0], scratch[1], | |
314 scratch[2], scratch[3]); | |
315 break; | |
316 } | |
317 | |
318 url_fseek(pb, chunk_size, SEEK_CUR); | |
319 } while (chunk_tag != FINF_TAG); | |
320 | |
284 wsvqa->video_pts = wsvqa->audio_frame_counter = 0; | 321 wsvqa->video_pts = wsvqa->audio_frame_counter = 0; |
285 | 322 |
286 return 0; | 323 return 0; |
287 } | 324 } |
288 | 325 |