1
|
1
|
|
2 #define MIN(a,b) (((a)<(b))?(a):(b))
|
|
3
|
|
4 void read_avi_header(int no_index){
|
|
5
|
|
6 int stream_id=-1;
|
|
7
|
|
8 //---- AVI header:
|
|
9 avi_header.idx_size=0;
|
|
10 while(1){
|
|
11 int id=stream_read_dword_le(demuxer->stream);
|
|
12 int chunksize,size2;
|
|
13 static int last_fccType=0;
|
|
14 //
|
|
15 if(stream_eof(demuxer->stream)) break;
|
|
16 //
|
|
17 if(id==mmioFOURCC('L','I','S','T')){
|
|
18 int len=stream_read_dword_le(demuxer->stream)-4; // list size
|
|
19 id=stream_read_dword_le(demuxer->stream); // list type
|
|
20 if(verbose>=2) printf("LIST %.4s len=%d\n",&id,len);
|
|
21 if(id==listtypeAVIMOVIE){
|
|
22 // found MOVI header
|
|
23 avi_header.movi_start=stream_tell(demuxer->stream);
|
|
24 avi_header.movi_end=avi_header.movi_start+len;
|
|
25 if(verbose>=1) printf("Found movie at 0x%X - 0x%X\n",avi_header.movi_start,avi_header.movi_end);
|
|
26 len=(len+1)&(~1);
|
|
27 stream_skip(demuxer->stream,len);
|
|
28 }
|
|
29 continue;
|
|
30 }
|
|
31 size2=stream_read_dword_le(demuxer->stream);
|
|
32 if(verbose>=2) printf("CHUNK %.4s len=%d\n",&id,size2);
|
|
33 chunksize=(size2+1)&(~1);
|
|
34 switch(id){
|
|
35 case ckidAVIMAINHDR: // read 'avih'
|
|
36 stream_read(demuxer->stream,(char*) &avi_header.avih,MIN(size2,sizeof(avi_header.avih)));
|
|
37 chunksize-=MIN(size2,sizeof(avi_header.avih));
|
|
38 if(verbose) print_avih(&avi_header.avih);
|
|
39 break;
|
|
40 case ckidSTREAMHEADER: { // read 'strh'
|
|
41 AVIStreamHeader h;
|
|
42 stream_read(demuxer->stream,(char*) &h,MIN(size2,sizeof(h)));
|
|
43 chunksize-=MIN(size2,sizeof(h));
|
291
|
44 if(h.fccType==streamtypeVIDEO) memcpy(&sh_video_i.video,&h,sizeof(h));else
|
|
45 if(h.fccType==streamtypeAUDIO) memcpy(&sh_audio_i.audio,&h,sizeof(h));
|
1
|
46 last_fccType=h.fccType;
|
|
47 if(verbose>=1) print_strh(&h);
|
|
48 ++stream_id;
|
|
49 break; }
|
|
50 case ckidSTREAMFORMAT: { // read 'strf'
|
|
51 if(last_fccType==streamtypeVIDEO){
|
291
|
52 sh_video_t *sh_video=&sh_video_i; // FIXME!
|
|
53 stream_read(demuxer->stream,(char*) &sh_video->bih,MIN(size2,sizeof(sh_video->bih)));
|
|
54 chunksize-=MIN(size2,sizeof(sh_video->bih));
|
|
55 sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
|
|
56 sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
|
1
|
57 if(demuxer->video->id==-1) demuxer->video->id=stream_id;
|
|
58 } else
|
|
59 if(last_fccType==streamtypeAUDIO){
|
291
|
60 sh_audio_t *sh_audio=&sh_audio_i; // FIXME!
|
1
|
61 int z=(chunksize<64)?chunksize:64;
|
|
62 if(verbose>=2) printf("found 'wf', %d bytes of %d\n",chunksize,sizeof(WAVEFORMATEX));
|
291
|
63 stream_read(demuxer->stream,(char*) &sh_audio->wf,z);
|
1
|
64 chunksize-=z;
|
291
|
65 if(verbose>=1) print_wave_header(&sh_audio->wf);
|
1
|
66 if(demuxer->audio->id==-1) demuxer->audio->id=stream_id;
|
|
67 }
|
|
68 break;
|
|
69 }
|
|
70 case ckidAVINEWINDEX: if(!no_index){
|
|
71 avi_header.idx_size=size2>>4;
|
|
72 if(verbose>=1) printf("Reading INDEX block, %d chunks for %d frames\n",
|
|
73 avi_header.idx_size,avi_header.avih.dwTotalFrames);
|
|
74 avi_header.idx=malloc(avi_header.idx_size<<4);
|
|
75 stream_read(demuxer->stream,(char*)avi_header.idx,avi_header.idx_size<<4);
|
|
76 chunksize-=avi_header.idx_size<<4;
|
|
77 if(verbose>=2) print_index();
|
|
78 break;
|
|
79 }
|
|
80 }
|
|
81 if(chunksize>0) stream_skip(demuxer->stream,chunksize); else
|
|
82 if(chunksize<0) printf("WARNING!!! chunksize=%d (id=%.4s)\n",chunksize,&id);
|
|
83
|
|
84 }
|
|
85
|
|
86 }
|
|
87
|
|
88 #undef MIN
|
|
89
|