comparison libmpdemux/demux_avi.c @ 29263:0f1b5b68af32

whitespace cosmetics: Remove all trailing whitespace.
author diego
date Wed, 13 May 2009 02:58:57 +0000
parents d643e4643313
children a90c7676bf0e
comparison
equal deleted inserted replaced
29262:7d545a6b8aff 29263:0f1b5b68af32
120 120
121 static int demux_avi_read_packet(demuxer_t *demux,demux_stream_t *ds,unsigned int id,unsigned int len,int idxpos,int flags){ 121 static int demux_avi_read_packet(demuxer_t *demux,demux_stream_t *ds,unsigned int id,unsigned int len,int idxpos,int flags){
122 avi_priv_t *priv=demux->priv; 122 avi_priv_t *priv=demux->priv;
123 int skip; 123 int skip;
124 float pts=0; 124 float pts=0;
125 125
126 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_avi.read_packet: %X\n",id); 126 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_avi.read_packet: %X\n",id);
127 127
128 if(ds==demux->audio){ 128 if(ds==demux->audio){
129 if(priv->pts_corrected==0){ 129 if(priv->pts_corrected==0){
130 if(priv->pts_has_video){ 130 if(priv->pts_has_video){
148 pts=priv->avi_audio_pts; //+priv->pts_correction; 148 pts=priv->avi_audio_pts; //+priv->pts_correction;
149 priv->avi_audio_pts=0; 149 priv->avi_audio_pts=0;
150 // update blockcount: 150 // update blockcount:
151 priv->audio_block_no+=priv->audio_block_size ? 151 priv->audio_block_no+=priv->audio_block_size ?
152 ((len+priv->audio_block_size-1)/priv->audio_block_size) : 1; 152 ((len+priv->audio_block_size-1)/priv->audio_block_size) : 1;
153 } else 153 } else
154 if(ds==demux->video){ 154 if(ds==demux->video){
155 // video 155 // video
156 if(priv->skip_video_frames>0){ 156 if(priv->skip_video_frames>0){
157 // drop frame (seeking) 157 // drop frame (seeking)
158 --priv->skip_video_frames; 158 --priv->skip_video_frames;
167 priv->pts_has_video=1; 167 priv->pts_has_video=1;
168 168
169 if(ds) ++priv->video_pack_no; 169 if(ds) ++priv->video_pack_no;
170 170
171 } 171 }
172 172
173 skip=(len+1)&(~1); // total bytes in this chunk 173 skip=(len+1)&(~1); // total bytes in this chunk
174 174
175 if(ds){ 175 if(ds){
176 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_AVI: Read %d data bytes from packet %04X\n",len,id); 176 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_AVI: Read %d data bytes from packet %04X\n",len,id);
177 ds_read_packet(ds,demux->stream,len,pts,idxpos,flags); 177 ds_read_packet(ds,demux->stream,len,pts,idxpos,flags);
178 skip-=len; 178 skip-=len;
179 } 179 }
212 do{ 212 do{
213 int flags=1; 213 int flags=1;
214 AVIINDEXENTRY *idx=NULL; 214 AVIINDEXENTRY *idx=NULL;
215 if(priv->idx_size>0 && priv->idx_pos<priv->idx_size){ 215 if(priv->idx_size>0 && priv->idx_pos<priv->idx_size){
216 off_t pos; 216 off_t pos;
217 217
218 idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++]; 218 idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++];
219 219
220 if(idx->dwFlags&AVIIF_LIST){ 220 if(idx->dwFlags&AVIIF_LIST){
221 // LIST 221 // LIST
222 continue; 222 continue;
223 } 223 }
224 if(!demux_avi_select_stream(demux,idx->ckid)){ 224 if(!demux_avi_select_stream(demux,idx->ckid)){
233 } 233 }
234 stream_seek(demux->stream,pos); 234 stream_seek(demux->stream,pos);
235 demux->filepos=stream_tell(demux->stream); 235 demux->filepos=stream_tell(demux->stream);
236 id=stream_read_dword_le(demux->stream); 236 id=stream_read_dword_le(demux->stream);
237 if(stream_eof(demux->stream)) return 0; // EOF! 237 if(stream_eof(demux->stream)) return 0; // EOF!
238 238
239 if(id!=idx->ckid){ 239 if(id!=idx->ckid){
240 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); 240 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid);
241 if(valid_fourcc(idx->ckid)) 241 if(valid_fourcc(idx->ckid))
242 id=idx->ckid; // use index if valid 242 id=idx->ckid; // use index if valid
243 else 243 else
257 return 0; 257 return 0;
258 } 258 }
259 id=avi_find_id(demux->stream); 259 id=avi_find_id(demux->stream);
260 len=stream_read_dword_le(demux->stream); 260 len=stream_read_dword_le(demux->stream);
261 if(stream_eof(demux->stream)) return 0; // EOF! 261 if(stream_eof(demux->stream)) return 0; // EOF!
262 262
263 if(id==mmioFOURCC('L','I','S','T') || id==mmioFOURCC('R', 'I', 'F', 'F')){ 263 if(id==mmioFOURCC('L','I','S','T') || id==mmioFOURCC('R', 'I', 'F', 'F')){
264 id=stream_read_dword_le(demux->stream); // list or RIFF type 264 id=stream_read_dword_le(demux->stream); // list or RIFF type
265 continue; 265 continue;
266 } 266 }
267 } 267 }
284 } 284 }
285 priv->idx_pos_v=priv->idx_pos_a=priv->idx_pos; 285 priv->idx_pos_v=priv->idx_pos_a=priv->idx_pos;
286 // quit now, we can't even (no enough buffer memory) read this packet :( 286 // quit now, we can't even (no enough buffer memory) read this packet :(
287 return -1; 287 return -1;
288 } 288 }
289 289
290 ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,flags); 290 ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,flags);
291 } while(ret!=1); 291 } while(ret!=1);
292 return 1; 292 return 1;
293 } 293 }
294 294
305 do{ 305 do{
306 int flags=1; 306 int flags=1;
307 AVIINDEXENTRY *idx=NULL; 307 AVIINDEXENTRY *idx=NULL;
308 int idx_pos=0; 308 int idx_pos=0;
309 demux->filepos=stream_tell(demux->stream); 309 demux->filepos=stream_tell(demux->stream);
310 310
311 if(ds==demux->video) idx_pos=priv->idx_pos_v++; else 311 if(ds==demux->video) idx_pos=priv->idx_pos_v++; else
312 if(ds==demux->audio) idx_pos=priv->idx_pos_a++; else 312 if(ds==demux->audio) idx_pos=priv->idx_pos_a++; else
313 idx_pos=priv->idx_pos++; 313 idx_pos=priv->idx_pos++;
314 314
315 if(priv->idx_size>0 && idx_pos<priv->idx_size){ 315 if(priv->idx_size>0 && idx_pos<priv->idx_size){
316 off_t pos; 316 off_t pos;
317 idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos]; 317 idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos];
318 318
319 if(idx->dwFlags&AVIIF_LIST){ 319 if(idx->dwFlags&AVIIF_LIST){
320 // LIST 320 // LIST
321 continue; 321 continue;
322 } 322 }
323 if(ds && demux_avi_select_stream(demux,idx->ckid)!=ds){ 323 if(ds && demux_avi_select_stream(demux,idx->ckid)!=ds){
383 383
384 id=avi_find_id(demux->stream); 384 id=avi_find_id(demux->stream);
385 len=stream_read_dword_le(demux->stream); 385 len=stream_read_dword_le(demux->stream);
386 386
387 if(stream_eof(demux->stream)) return 0; 387 if(stream_eof(demux->stream)) return 0;
388 388
389 if(id==mmioFOURCC('L','I','S','T')){ 389 if(id==mmioFOURCC('L','I','S','T')){
390 id=stream_read_dword_le(demux->stream); // list type 390 id=stream_read_dword_le(demux->stream); // list type
391 continue; 391 continue;
392 } 392 }
393 393
394 if(id==mmioFOURCC('R','I','F','F')){ 394 if(id==mmioFOURCC('R','I','F','F')){
395 mp_msg(MSGT_DEMUX,MSGL_V,"additional RIFF header...\n"); 395 mp_msg(MSGT_DEMUX,MSGL_V,"additional RIFF header...\n");
396 id=stream_read_dword_le(demux->stream); // "AVIX" 396 id=stream_read_dword_le(demux->stream); // "AVIX"
397 continue; 397 continue;
398 } 398 }
399 399
400 if(ds==demux_avi_select_stream(demux,id)){ 400 if(ds==demux_avi_select_stream(demux,id)){
401 // read it! 401 // read it!
402 ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,0); 402 ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,0);
403 } else { 403 } else {
404 // skip it! 404 // skip it!
405 int skip=(len+1)&(~1); // total bytes in this chunk 405 int skip=(len+1)&(~1); // total bytes in this chunk
406 stream_skip(demux->stream,skip); 406 stream_skip(demux->stream,skip);
407 } 407 }
408 408
409 } while(ret!=1); 409 } while(ret!=1);
410 fpos[0]=stream_tell(demux->stream); 410 fpos[0]=stream_tell(demux->stream);
411 return 1; 411 return 1;
412 } 412 }
413 413
440 440
441 demuxer->priv=(void*)priv; 441 demuxer->priv=(void*)priv;
442 442
443 //---- AVI header: 443 //---- AVI header:
444 read_avi_header(demuxer,(demuxer->stream->flags & STREAM_SEEK_BW)?index_mode:-2); 444 read_avi_header(demuxer,(demuxer->stream->flags & STREAM_SEEK_BW)?index_mode:-2);
445 445
446 if(demuxer->audio->id>=0 && !demuxer->a_streams[demuxer->audio->id]){ 446 if(demuxer->audio->id>=0 && !demuxer->a_streams[demuxer->audio->id]){
447 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamNosound,demuxer->audio->id); 447 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamNosound,demuxer->audio->id);
448 demuxer->audio->id=-2; // disabled 448 demuxer->audio->id=-2; // disabled
449 } 449 }
450 if(demuxer->video->id>=0 && !demuxer->v_streams[demuxer->video->id]){ 450 if(demuxer->video->id>=0 && !demuxer->v_streams[demuxer->video->id]){
451 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamUsingDefault,demuxer->video->id); 451 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamUsingDefault,demuxer->video->id);
452 demuxer->video->id=-1; // autodetect 452 demuxer->video->id=-1; // autodetect
453 } 453 }
454 454
455 stream_reset(demuxer->stream); 455 stream_reset(demuxer->stream);
456 stream_seek(demuxer->stream,demuxer->movi_start); 456 stream_seek(demuxer->stream,demuxer->movi_start);
457 priv->idx_pos=0; 457 priv->idx_pos=0;
458 priv->idx_pos_a=0; 458 priv->idx_pos_a=0;
459 priv->idx_pos_v=0; 459 priv->idx_pos_v=0;
474 mp_msg(MSGT_DEMUX,MSGL_V,"AVI index offset: 0x%X (movi=0x%X idx0=0x%X idx1=0x%X)\n", 474 mp_msg(MSGT_DEMUX,MSGL_V,"AVI index offset: 0x%X (movi=0x%X idx0=0x%X idx1=0x%X)\n",
475 (int)priv->idx_offset,(int)demuxer->movi_start, 475 (int)priv->idx_offset,(int)demuxer->movi_start,
476 (int)((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset, 476 (int)((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset,
477 (int)((AVIINDEXENTRY *)priv->idx)[1].dwChunkOffset); 477 (int)((AVIINDEXENTRY *)priv->idx)[1].dwChunkOffset);
478 } 478 }
479 479
480 if(priv->idx_size>0){ 480 if(priv->idx_size>0){
481 // check that file is non-interleaved: 481 // check that file is non-interleaved:
482 int i; 482 int i;
483 off_t a_pos=-1; 483 off_t a_pos=-1;
484 off_t v_pos=-1; 484 off_t v_pos=-1;
542 int64_t vsize=0; 542 int64_t vsize=0;
543 int64_t asize=0; 543 int64_t asize=0;
544 size_t vsamples=0; 544 size_t vsamples=0;
545 size_t asamples=0; 545 size_t asamples=0;
546 int i; 546 int i;
547 for(i=0;i<priv->idx_size;i++){ 547 for(i=0;i<priv->idx_size;i++){
548 int id=avi_stream_id(((AVIINDEXENTRY *)priv->idx)[i].ckid); 548 int id=avi_stream_id(((AVIINDEXENTRY *)priv->idx)[i].ckid);
549 int len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength; 549 int len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength;
550 if(sh_video->ds->id == id) { 550 if(sh_video->ds->id == id) {
551 vsize+=len; 551 vsize+=len;
552 ++vsamples; 552 ++vsamples;
569 // bad video header, try to get number of frames from audio 569 // bad video header, try to get number of frames from audio
570 if(sh_audio && sh_audio->wf->nAvgBytesPerSec) priv->numberofframes=sh_video->fps*sh_audio->audio.dwLength/sh_audio->audio.dwRate*sh_audio->audio.dwScale; 570 if(sh_audio && sh_audio->wf->nAvgBytesPerSec) priv->numberofframes=sh_video->fps*sh_audio->audio.dwLength/sh_audio->audio.dwRate*sh_audio->audio.dwScale;
571 if(priv->numberofframes<=1){ 571 if(priv->numberofframes<=1){
572 mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CouldntDetFNo); 572 mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CouldntDetFNo);
573 priv->numberofframes=0; 573 priv->numberofframes=0;
574 } 574 }
575 575
576 if(sh_audio){ 576 if(sh_audio){
577 if(sh_audio->wf->nAvgBytesPerSec && sh_audio->audio.dwSampleSize!=1){ 577 if(sh_audio->wf->nAvgBytesPerSec && sh_audio->audio.dwSampleSize!=1){
578 asize=(float)sh_audio->wf->nAvgBytesPerSec*sh_audio->audio.dwLength*sh_audio->audio.dwScale/sh_audio->audio.dwRate; 578 asize=(float)sh_audio->wf->nAvgBytesPerSec*sh_audio->audio.dwLength*sh_audio->audio.dwScale/sh_audio->audio.dwRate;
579 } else { 579 } else {
585 mp_msg(MSGT_DEMUX,MSGL_V,"AVI video size=%"PRId64" (%u) audio size=%"PRId64"\n",vsize,priv->numberofframes,asize); 585 mp_msg(MSGT_DEMUX,MSGL_V,"AVI video size=%"PRId64" (%u) audio size=%"PRId64"\n",vsize,priv->numberofframes,asize);
586 sh_video->i_bps=(float)vsize/(sh_video->frametime*priv->numberofframes); 586 sh_video->i_bps=(float)vsize/(sh_video->frametime*priv->numberofframes);
587 } 587 }
588 588
589 return demuxer; 589 return demuxer;
590 590
591 } 591 }
592 592
593 593
594 void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ 594 void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
595 avi_priv_t *priv=demuxer->priv; 595 avi_priv_t *priv=demuxer->priv;
607 607
608 if(flags&SEEK_ABSOLUTE){ 608 if(flags&SEEK_ABSOLUTE){
609 // seek absolute 609 // seek absolute
610 video_chunk_pos=0; 610 video_chunk_pos=0;
611 } 611 }
612 612
613 if(flags&SEEK_FACTOR){ 613 if(flags&SEEK_FACTOR){
614 rel_seek_frames=rel_seek_secs*priv->numberofframes; 614 rel_seek_frames=rel_seek_secs*priv->numberofframes;
615 } 615 }
616 616
617 priv->skip_video_frames=0; 617 priv->skip_video_frames=0;
618 priv->avi_audio_pts=0; 618 priv->avi_audio_pts=0;
619 619
620 // ------------ STEP 1: find nearest video keyframe chunk ------------ 620 // ------------ STEP 1: find nearest video keyframe chunk ------------
621 // find nearest video keyframe chunk pos: 621 // find nearest video keyframe chunk pos:
648 } 648 }
649 priv->video_pack_no= 649 priv->video_pack_no=
650 sh_video->num_frames=sh_video->num_frames_decoded=d_video->pack_no; 650 sh_video->num_frames=sh_video->num_frames_decoded=d_video->pack_no;
651 priv->avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; 651 priv->avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
652 d_video->pos=video_chunk_pos; 652 d_video->pos=video_chunk_pos;
653 653
654 mp_msg(MSGT_SEEK,MSGL_DBG2,"V_SEEK: pack=%d pts=%5.3f chunk=%d \n",d_video->pack_no,priv->avi_video_pts,video_chunk_pos); 654 mp_msg(MSGT_SEEK,MSGL_DBG2,"V_SEEK: pack=%d pts=%5.3f chunk=%d \n",d_video->pack_no,priv->avi_video_pts,video_chunk_pos);
655 655
656 // ------------ STEP 2: seek audio, find the right chunk & pos ------------ 656 // ------------ STEP 2: seek audio, find the right chunk & pos ------------
657 657
658 d_audio->pack_no=0; 658 d_audio->pack_no=0;
664 int len=0; 664 int len=0;
665 int skip_audio_bytes=0; 665 int skip_audio_bytes=0;
666 int curr_audio_pos=-1; 666 int curr_audio_pos=-1;
667 int audio_chunk_pos=-1; 667 int audio_chunk_pos=-1;
668 int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:priv->idx_size; 668 int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:priv->idx_size;
669 669
670 if(sh_audio->audio.dwSampleSize){ 670 if(sh_audio->audio.dwSampleSize){
671 // constant rate audio stream 671 // constant rate audio stream
672 /* immediate seeking to audio position, including when streams are delayed */ 672 /* immediate seeking to audio position, including when streams are delayed */
673 curr_audio_pos=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; 673 curr_audio_pos=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale;
674 curr_audio_pos*=sh_audio->audio.dwSampleSize; 674 curr_audio_pos*=sh_audio->audio.dwSampleSize;
690 audio_chunk_pos=i; 690 audio_chunk_pos=i;
691 skip_audio_bytes=curr_audio_pos-d_audio->dpos; 691 skip_audio_bytes=curr_audio_pos-d_audio->dpos;
692 692
693 mp_msg(MSGT_SEEK,MSGL_V,"SEEK: i=%d (max:%d) dpos=%d (wanted:%d) \n", 693 mp_msg(MSGT_SEEK,MSGL_V,"SEEK: i=%d (max:%d) dpos=%d (wanted:%d) \n",
694 i,chunk_max,(int)d_audio->dpos,curr_audio_pos); 694 i,chunk_max,(int)d_audio->dpos,curr_audio_pos);
695 695
696 } else { 696 } else {
697 // VBR audio 697 // VBR audio
698 /* immediate seeking to audio position, including when streams are delayed */ 698 /* immediate seeking to audio position, including when streams are delayed */
699 int chunks=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; 699 int chunks=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale;
700 audio_chunk_pos=0; 700 audio_chunk_pos=0;
701 701
702 // find audio chunk pos: 702 // find audio chunk pos:
703 for(i=0;i<priv->idx_size && chunks>0;i++){ 703 for(i=0;i<priv->idx_size && chunks>0;i++){
704 int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; 704 int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
705 if(avi_stream_id(id)==d_audio->id){ 705 if(avi_stream_id(id)==d_audio->id){
706 len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength; 706 len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength;
716 if(priv->audio_block_size) 716 if(priv->audio_block_size)
717 chunks-=(len+priv->audio_block_size-1)/priv->audio_block_size; 717 chunks-=(len+priv->audio_block_size-1)/priv->audio_block_size;
718 } 718 }
719 } 719 }
720 } 720 }
721 721
722 // Now we have: 722 // Now we have:
723 // audio_chunk_pos = chunk no in index table (it's <=chunk_max) 723 // audio_chunk_pos = chunk no in index table (it's <=chunk_max)
724 // skip_audio_bytes = bytes to be skipped after chunk seek 724 // skip_audio_bytes = bytes to be skipped after chunk seek
725 // d-audio->pack_no = chunk_no in stream at audio_chunk_pos 725 // d-audio->pack_no = chunk_no in stream at audio_chunk_pos
726 // d_audio->dpos = bytepos in stream at audio_chunk_pos 726 // d_audio->dpos = bytepos in stream at audio_chunk_pos
727 // let's seek! 727 // let's seek!
728 728
729 // update stream position: 729 // update stream position:
730 d_audio->pos=audio_chunk_pos; 730 d_audio->pos=audio_chunk_pos;
731 731
732 if(demuxer->type==DEMUXER_TYPE_AVI){ 732 if(demuxer->type==DEMUXER_TYPE_AVI){
733 // interleaved stream: 733 // interleaved stream:
734 if(audio_chunk_pos<video_chunk_pos){ 734 if(audio_chunk_pos<video_chunk_pos){
735 // calc priv->skip_video_frames & adjust video pts counter: 735 // calc priv->skip_video_frames & adjust video pts counter:
736 for(i=audio_chunk_pos;i<video_chunk_pos;i++){ 736 for(i=audio_chunk_pos;i<video_chunk_pos;i++){