Mercurial > mplayer.hg
annotate aviheader.c @ 585:96621b6b7f9f
added: extern int vo_dbpp
author | arpi_esp |
---|---|
date | Mon, 23 Apr 2001 03:38:17 +0000 |
parents | 2810e747e545 |
children | 8511095c5283 |
rev | line source |
---|---|
1 | 1 |
2 #define MIN(a,b) (((a)<(b))?(a):(b)) | |
3 | |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
4 void read_avi_header(int index_mode){ |
426 | 5 sh_audio_t *sh_audio=NULL; |
6 sh_video_t *sh_video=NULL; | |
1 | 7 int stream_id=-1; |
568 | 8 int idxfix_videostream=0; |
9 int idxfix_divx=0; | |
1 | 10 |
11 //---- AVI header: | |
12 avi_header.idx_size=0; | |
13 while(1){ | |
14 int id=stream_read_dword_le(demuxer->stream); | |
15 int chunksize,size2; | |
16 static int last_fccType=0; | |
17 // | |
18 if(stream_eof(demuxer->stream)) break; | |
19 // | |
20 if(id==mmioFOURCC('L','I','S','T')){ | |
21 int len=stream_read_dword_le(demuxer->stream)-4; // list size | |
22 id=stream_read_dword_le(demuxer->stream); // list type | |
23 if(verbose>=2) printf("LIST %.4s len=%d\n",&id,len); | |
24 if(id==listtypeAVIMOVIE){ | |
25 // found MOVI header | |
26 avi_header.movi_start=stream_tell(demuxer->stream); | |
27 avi_header.movi_end=avi_header.movi_start+len; | |
28 if(verbose>=1) printf("Found movie at 0x%X - 0x%X\n",avi_header.movi_start,avi_header.movi_end); | |
29 len=(len+1)&(~1); | |
30 stream_skip(demuxer->stream,len); | |
31 } | |
32 continue; | |
33 } | |
34 size2=stream_read_dword_le(demuxer->stream); | |
35 if(verbose>=2) printf("CHUNK %.4s len=%d\n",&id,size2); | |
36 chunksize=(size2+1)&(~1); | |
37 switch(id){ | |
38 case ckidAVIMAINHDR: // read 'avih' | |
39 stream_read(demuxer->stream,(char*) &avi_header.avih,MIN(size2,sizeof(avi_header.avih))); | |
40 chunksize-=MIN(size2,sizeof(avi_header.avih)); | |
41 if(verbose) print_avih(&avi_header.avih); | |
42 break; | |
43 case ckidSTREAMHEADER: { // read 'strh' | |
44 AVIStreamHeader h; | |
45 stream_read(demuxer->stream,(char*) &h,MIN(size2,sizeof(h))); | |
46 chunksize-=MIN(size2,sizeof(h)); | |
426 | 47 ++stream_id; |
48 if(h.fccType==streamtypeVIDEO){ | |
49 sh_video=new_sh_video(stream_id); | |
50 memcpy(&sh_video->video,&h,sizeof(h)); | |
51 } else | |
52 if(h.fccType==streamtypeAUDIO){ | |
53 sh_audio=new_sh_audio(stream_id); | |
54 memcpy(&sh_audio->audio,&h,sizeof(h)); | |
55 } | |
1 | 56 last_fccType=h.fccType; |
57 if(verbose>=1) print_strh(&h); | |
58 break; } | |
59 case ckidSTREAMFORMAT: { // read 'strf' | |
60 if(last_fccType==streamtypeVIDEO){ | |
433 | 61 sh_video->bih=calloc((chunksize<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):chunksize,1); |
62 // sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize); | |
63 if(verbose>=1) printf("found 'bih', %d bytes of %d\n",chunksize,sizeof(BITMAPINFOHEADER)); | |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
64 stream_read(demuxer->stream,(char*) sh_video->bih,chunksize); |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
65 chunksize=0; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
66 // sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
67 // sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; |
426 | 68 // if(demuxer->video->id==-1) demuxer->video->id=stream_id; |
568 | 69 // IdxFix: |
70 idxfix_videostream=stream_id; | |
71 switch(sh_video->bih->biCompression){ | |
72 case mmioFOURCC('D', 'I', 'V', '3'): | |
73 case mmioFOURCC('d', 'i', 'v', '3'): | |
74 case mmioFOURCC('D', 'I', 'V', '4'): | |
75 case mmioFOURCC('d', 'i', 'v', '4'): | |
76 case mmioFOURCC('D', 'I', 'V', '5'): | |
77 case mmioFOURCC('d', 'i', 'v', '5'): | |
78 case mmioFOURCC('D', 'I', 'V', '6'): | |
79 case mmioFOURCC('d', 'i', 'v', '6'): | |
80 case mmioFOURCC('M', 'P', '4', '3'): | |
81 case mmioFOURCC('m', 'p', '4', '3'): | |
82 case mmioFOURCC('A', 'P', '4', '1'): | |
83 idxfix_divx=1; // we can fix keyframes only for divx coded files! | |
84 } | |
1 | 85 } else |
86 if(last_fccType==streamtypeAUDIO){ | |
433 | 87 sh_audio->wf=calloc((chunksize<sizeof(WAVEFORMATEX))?sizeof(WAVEFORMATEX):chunksize,1); |
88 // sh_audio->wf=malloc(chunksize); memset(sh_audio->wf,0,chunksize); | |
89 if(verbose>=1) printf("found 'wf', %d bytes of %d\n",chunksize,sizeof(WAVEFORMATEX)); | |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
90 stream_read(demuxer->stream,(char*) sh_audio->wf,chunksize); |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
91 chunksize=0; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
92 if(verbose>=1) print_wave_header(sh_audio->wf); |
426 | 93 // if(demuxer->audio->id==-1) demuxer->audio->id=stream_id; |
1 | 94 } |
95 break; | |
96 } | |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
97 case ckidAVINEWINDEX: if(index_mode){ |
1 | 98 avi_header.idx_size=size2>>4; |
99 if(verbose>=1) printf("Reading INDEX block, %d chunks for %d frames\n", | |
100 avi_header.idx_size,avi_header.avih.dwTotalFrames); | |
101 avi_header.idx=malloc(avi_header.idx_size<<4); | |
102 stream_read(demuxer->stream,(char*)avi_header.idx,avi_header.idx_size<<4); | |
103 chunksize-=avi_header.idx_size<<4; | |
104 if(verbose>=2) print_index(); | |
105 break; | |
106 } | |
107 } | |
108 if(chunksize>0) stream_skip(demuxer->stream,chunksize); else | |
109 if(chunksize<0) printf("WARNING!!! chunksize=%d (id=%.4s)\n",chunksize,&id); | |
110 | |
111 } | |
112 | |
568 | 113 if(index_mode>=2 || (avi_header.idx_size==0 && index_mode==1)){ |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
114 // build index for file: |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
115 stream_reset(demuxer->stream); |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
116 stream_seek(demuxer->stream,avi_header.movi_start); |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
117 |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
118 avi_header.idx_pos=0; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
119 avi_header.idx=NULL; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
120 |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
121 while(1){ |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
122 int id,len,skip; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
123 AVIINDEXENTRY* idx; |
569 | 124 unsigned char c; |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
125 demuxer->filepos=stream_tell(demuxer->stream); |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
126 if(demuxer->filepos>=avi_header.movi_end) break; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
127 id=stream_read_dword_le(demuxer->stream); |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
128 len=stream_read_dword_le(demuxer->stream); |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
129 if(id==mmioFOURCC('L','I','S','T')){ |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
130 id=stream_read_dword_le(demuxer->stream); // list type |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
131 continue; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
132 } |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
133 if(stream_eof(demuxer->stream)) break; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
134 if(avi_header.idx_pos<=avi_header.idx_size){ |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
135 avi_header.idx_size+=32; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
136 avi_header.idx=realloc(avi_header.idx,avi_header.idx_size*sizeof(AVIINDEXENTRY)); |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
137 if(!avi_header.idx){avi_header.idx_pos=0; break;} // error! |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
138 } |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
139 idx=&avi_header.idx[avi_header.idx_pos++]; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
140 idx->ckid=id; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
141 idx->dwFlags=AVIIF_KEYFRAME; // FIXME |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
142 idx->dwChunkOffset=demuxer->filepos; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
143 idx->dwChunkLength=len; |
569 | 144 |
145 c=stream_read_char(demuxer->stream); | |
568 | 146 |
147 // Fix keyframes for DivX files: | |
148 if(idxfix_divx) | |
149 if(avi_stream_id(id)==idxfix_videostream){ | |
569 | 150 if(c&0x40) idx->dwFlags=0; |
568 | 151 } |
152 | |
569 | 153 if(verbose>=2) printf("%08X %08X %.4s %02X %X\n",demuxer->filepos,id,&id,c,idx->dwFlags); |
568 | 154 #if 0 |
155 { unsigned char tmp[64]; | |
156 int i; | |
157 stream_read(demuxer->stream,tmp,64); | |
158 printf("%.4s",&id); | |
159 for(i=0;i<64;i++) printf(" %02X",tmp[i]); | |
160 printf("\n"); | |
161 } | |
162 #endif | |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
163 skip=(len+1)&(~1); // total bytes in this chunk |
568 | 164 stream_seek(demuxer->stream,8+demuxer->filepos+skip); |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
165 } |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
166 avi_header.idx_size=avi_header.idx_pos; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
167 printf("AVI: Generated index table for %d chunks!\n",avi_header.idx_size); |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
168 } |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
169 |
1 | 170 } |
171 | |
172 #undef MIN | |
173 |