comparison westwood.c @ 1545:8811d543732e libavformat

Better VQA demuxer
author kostya
date Wed, 29 Nov 2006 05:42:59 +0000
parents 0899bfe4105c
children 3b4019c023a3
comparison
equal deleted inserted replaced
1544:49256f9ea0e9 1545:8811d543732e
42 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M') 42 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M')
43 #define WVQA_TAG MKBETAG('W', 'V', 'Q', 'A') 43 #define WVQA_TAG MKBETAG('W', 'V', 'Q', 'A')
44 #define VQHD_TAG MKBETAG('V', 'Q', 'H', 'D') 44 #define VQHD_TAG MKBETAG('V', 'Q', 'H', 'D')
45 #define FINF_TAG MKBETAG('F', 'I', 'N', 'F') 45 #define FINF_TAG MKBETAG('F', 'I', 'N', 'F')
46 #define SND0_TAG MKBETAG('S', 'N', 'D', '0') 46 #define SND0_TAG MKBETAG('S', 'N', 'D', '0')
47 #define SND1_TAG MKBETAG('S', 'N', 'D', '1')
47 #define SND2_TAG MKBETAG('S', 'N', 'D', '2') 48 #define SND2_TAG MKBETAG('S', 'N', 'D', '2')
48 #define VQFR_TAG MKBETAG('V', 'Q', 'F', 'R') 49 #define VQFR_TAG MKBETAG('V', 'Q', 'F', 'R')
49 50
50 /* don't know what these tags are for, but acknowledge their existence */ 51 /* don't know what these tags are for, but acknowledge their existence */
51 #define CINF_TAG MKBETAG('C', 'I', 'N', 'F') 52 #define CINF_TAG MKBETAG('C', 'I', 'N', 'F')
52 #define CINH_TAG MKBETAG('C', 'I', 'N', 'H') 53 #define CINH_TAG MKBETAG('C', 'I', 'N', 'H')
53 #define CIND_TAG MKBETAG('C', 'I', 'N', 'D') 54 #define CIND_TAG MKBETAG('C', 'I', 'N', 'D')
54 #define PINF_TAG MKBETAG('P', 'I', 'N', 'F') 55 #define PINF_TAG MKBETAG('P', 'I', 'N', 'F')
55 #define PINH_TAG MKBETAG('P', 'I', 'N', 'H') 56 #define PINH_TAG MKBETAG('P', 'I', 'N', 'H')
56 #define PIND_TAG MKBETAG('P', 'I', 'N', 'D') 57 #define PIND_TAG MKBETAG('P', 'I', 'N', 'D')
58 #define CMDS_TAG MKBETAG('C', 'M', 'D', 'S')
57 59
58 #define VQA_HEADER_SIZE 0x2A 60 #define VQA_HEADER_SIZE 0x2A
59 #define VQA_FRAMERATE 15 61 #define VQA_FRAMERATE 15
60 #define VQA_VIDEO_PTS_INC (90000 / VQA_FRAMERATE) 62 #define VQA_VIDEO_PTS_INC (90000 / VQA_FRAMERATE)
61 #define VQA_PREAMBLE_SIZE 8 63 #define VQA_PREAMBLE_SIZE 8
241 return AVERROR_IO; 243 return AVERROR_IO;
242 } 244 }
243 st->codec->width = LE_16(&header[6]); 245 st->codec->width = LE_16(&header[6]);
244 st->codec->height = LE_16(&header[8]); 246 st->codec->height = LE_16(&header[8]);
245 247
246 /* initialize the audio decoder stream is sample rate is non-zero */ 248 st->codec->time_base.num = 1;
247 if (LE_16(&header[24])) { 249 st->codec->time_base.den = VQA_FRAMERATE;
250
251 /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
252 if (LE_16(&header[24]) || (LE_16(&header[0]) == 1)) {
248 st = av_new_stream(s, 0); 253 st = av_new_stream(s, 0);
249 if (!st) 254 if (!st)
250 return AVERROR_NOMEM; 255 return AVERROR_NOMEM;
251 av_set_pts_info(st, 33, 1, 90000); 256 av_set_pts_info(st, 33, 1, 90000);
252 st->codec->codec_type = CODEC_TYPE_AUDIO; 257 st->codec->codec_type = CODEC_TYPE_AUDIO;
253 st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; 258 if (LE_16(&header[0]) == 1)
259 st->codec->codec_id = CODEC_ID_WESTWOOD_SND1;
260 else
261 st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS;
254 st->codec->codec_tag = 0; /* no tag */ 262 st->codec->codec_tag = 0; /* no tag */
255 st->codec->sample_rate = LE_16(&header[24]); 263 st->codec->sample_rate = LE_16(&header[24]);
264 if (!st->codec->sample_rate)
265 st->codec->sample_rate = 22050;
256 st->codec->channels = header[26]; 266 st->codec->channels = header[26];
267 if (!st->codec->channels)
268 st->codec->channels = 1;
257 st->codec->bits_per_sample = 16; 269 st->codec->bits_per_sample = 16;
258 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 270 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
259 st->codec->bits_per_sample / 4; 271 st->codec->bits_per_sample / 4;
260 st->codec->block_align = st->codec->channels * st->codec->bits_per_sample; 272 st->codec->block_align = st->codec->channels * st->codec->bits_per_sample;
261 273
282 case CIND_TAG: 294 case CIND_TAG:
283 case PINF_TAG: 295 case PINF_TAG:
284 case PINH_TAG: 296 case PINH_TAG:
285 case PIND_TAG: 297 case PIND_TAG:
286 case FINF_TAG: 298 case FINF_TAG:
299 case CMDS_TAG:
287 break; 300 break;
288 301
289 default: 302 default:
290 av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n", 303 av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n",
291 scratch[0], scratch[1], 304 scratch[0], scratch[1],
304 static int wsvqa_read_packet(AVFormatContext *s, 317 static int wsvqa_read_packet(AVFormatContext *s,
305 AVPacket *pkt) 318 AVPacket *pkt)
306 { 319 {
307 WsVqaDemuxContext *wsvqa = (WsVqaDemuxContext *)s->priv_data; 320 WsVqaDemuxContext *wsvqa = (WsVqaDemuxContext *)s->priv_data;
308 ByteIOContext *pb = &s->pb; 321 ByteIOContext *pb = &s->pb;
309 int ret = 0; 322 int ret = -1;
310 unsigned char preamble[VQA_PREAMBLE_SIZE]; 323 unsigned char preamble[VQA_PREAMBLE_SIZE];
311 unsigned int chunk_type; 324 unsigned int chunk_type;
312 unsigned int chunk_size; 325 unsigned int chunk_size;
313 int skip_byte; 326 int skip_byte;
314 327
315 if (get_buffer(pb, preamble, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) 328 while (get_buffer(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) {
316 return AVERROR_IO; 329 chunk_type = BE_32(&preamble[0]);
317 330 chunk_size = BE_32(&preamble[4]);
318 chunk_type = BE_32(&preamble[0]); 331 skip_byte = chunk_size & 0x01;
319 chunk_size = BE_32(&preamble[4]); 332
320 skip_byte = chunk_size & 0x01; 333 if ((chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) {
321 334
322 if ((chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) { 335 if (av_new_packet(pkt, chunk_size))
323 336 return AVERROR_IO;
324 av_get_packet(pb, pkt, chunk_size); 337 ret = get_buffer(pb, pkt->data, chunk_size);
325 if (ret != chunk_size) { 338 if (ret != chunk_size) {
326 ret = AVERROR_IO; 339 av_free_packet(pkt);
340 return AVERROR_IO;
341 }
342
343 if (chunk_type == SND2_TAG) {
344 pkt->stream_index = wsvqa->audio_stream_index;
345
346 pkt->pts = 90000;
347 pkt->pts *= wsvqa->audio_frame_counter;
348 pkt->pts /= wsvqa->audio_samplerate;
349
350 /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
351 wsvqa->audio_frame_counter += (chunk_size * 2) / wsvqa->audio_channels;
352 } else if(chunk_type == SND1_TAG) {
353 pkt->stream_index = wsvqa->audio_stream_index;
354
355 pkt->pts = 90000;
356 pkt->pts *= wsvqa->audio_frame_counter;
357 pkt->pts /= wsvqa->audio_samplerate;
358
359 /* unpacked size is stored in header */
360 wsvqa->audio_frame_counter += LE_16(pkt->data) / wsvqa->audio_channels;
361 } else {
362 pkt->stream_index = wsvqa->video_stream_index;
363 pkt->pts = wsvqa->video_pts;
364 wsvqa->video_pts += VQA_VIDEO_PTS_INC;
365 }
366 /* stay on 16-bit alignment */
367 if (skip_byte)
368 url_fseek(pb, 1, SEEK_CUR);
369
370 return ret;
371 } else {
372 switch(chunk_type){
373 case CMDS_TAG:
374 case SND0_TAG:
375 break;
376 default:
377 av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type);
378 }
379 url_fseek(pb, chunk_size + skip_byte, SEEK_CUR);
327 } 380 }
328 381 }
329 if (chunk_type == SND2_TAG) {
330 pkt->stream_index = wsvqa->audio_stream_index;
331
332 pkt->pts = 90000;
333 pkt->pts *= wsvqa->audio_frame_counter;
334 pkt->pts /= wsvqa->audio_samplerate;
335
336 /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
337 wsvqa->audio_frame_counter += (chunk_size * 2) /
338 wsvqa->audio_channels;
339 } else {
340 pkt->stream_index = wsvqa->video_stream_index;
341 pkt->pts = wsvqa->video_pts;
342 wsvqa->video_pts += VQA_VIDEO_PTS_INC;
343 }
344
345 } else
346 return AVERROR_INVALIDDATA;
347
348 /* stay on 16-bit alignment */
349 if (skip_byte)
350 url_fseek(pb, 1, SEEK_CUR);
351 382
352 return ret; 383 return ret;
353 } 384 }
354 385
355 static int wsvqa_read_close(AVFormatContext *s) 386 static int wsvqa_read_close(AVFormatContext *s)