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));
|
|
44 if(h.fccType==streamtypeVIDEO) memcpy(&avi_header.video,&h,sizeof(h));else
|
|
45 if(h.fccType==streamtypeAUDIO) memcpy(&avi_header.audio,&h,sizeof(h));
|
|
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){
|
|
52 stream_read(demuxer->stream,(char*) &avi_header.bih,MIN(size2,sizeof(avi_header.bih)));
|
|
53 chunksize-=MIN(size2,sizeof(avi_header.bih));
|
|
54 // init_video_codec();
|
|
55 // init_video_out();
|
|
56 if(demuxer->video->id==-1) demuxer->video->id=stream_id;
|
|
57 } else
|
|
58 if(last_fccType==streamtypeAUDIO){
|
|
59 int z=(chunksize<64)?chunksize:64;
|
|
60 if(verbose>=2) printf("found 'wf', %d bytes of %d\n",chunksize,sizeof(WAVEFORMATEX));
|
|
61 stream_read(demuxer->stream,(char*) &avi_header.wf_ext,z);
|
|
62 chunksize-=z;
|
|
63 if(verbose>=1) print_wave_header((WAVEFORMATEX*)&avi_header.wf_ext);
|
|
64 // init_audio_codec();
|
|
65 // init_audio_out();
|
|
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
|