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