Mercurial > mplayer.hg
annotate libmpdemux/aviheader.c @ 15533:ddf15d233d58
Do not switch to audio tracks whose codec private data differs from the main audio track's as this will most likely result in messed up audio output. Patch by Michael Behrisch <list () behrisch ! de>
author | mosu |
---|---|
date | Sat, 21 May 2005 06:50:08 +0000 |
parents | 35001ce5b853 |
children | a0b807d489bc |
rev | line source |
---|---|
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
1 |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
2 #include <stdio.h> |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
3 #include <stdlib.h> |
1430 | 4 #include <unistd.h> |
11234
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
5 #include <errno.h> |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
6 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
7 #include "config.h" |
1567 | 8 #include "mp_msg.h" |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
9 |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
10 #include "stream.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
11 #include "demuxer.h" |
2338 | 12 #include "stheader.h" |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
13 |
1309
598e3047ce13
Add some preliminary support for non-x86 architectures to mplayer
jkeil
parents:
1289
diff
changeset
|
14 #include "bswap.h" |
1342 | 15 #include "aviheader.h" |
1 | 16 |
17 #define MIN(a,b) (((a)<(b))?(a):(b)) | |
18 | |
1309
598e3047ce13
Add some preliminary support for non-x86 architectures to mplayer
jkeil
parents:
1289
diff
changeset
|
19 |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
20 static MainAVIHeader avih; |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
21 |
601 | 22 extern void print_avih(MainAVIHeader *h); |
1456
8c57a5a3c645
printfs cleanup - moved to higher -v level or moved to stderr
arpi
parents:
1430
diff
changeset
|
23 extern void print_avih_flags(MainAVIHeader *h); |
601 | 24 extern void print_strh(AVIStreamHeader *h); |
25 extern void print_wave_header(WAVEFORMATEX *h); | |
1496 | 26 extern void print_video_header(BITMAPINFOHEADER *h); |
601 | 27 extern void print_index(AVIINDEXENTRY *idx,int idx_size); |
12036 | 28 extern void print_avistdindex_chunk(avistdindex_chunk *h); |
29 extern void print_avisuperindex_chunk(avisuperindex_chunk *h); | |
13187 | 30 extern void print_vprp(VideoPropHeader *vprp); |
12036 | 31 |
32 static int odml_get_vstream_id(int id, unsigned char res[]) | |
33 { | |
34 unsigned char *p = (unsigned char *)&id; | |
35 id = le2me_32(id); | |
36 | |
37 if (p[2] == 'd') { | |
38 if (res) { | |
39 res[0] = p[0]; | |
40 res[1] = p[1]; | |
41 } | |
42 return 1; | |
43 } | |
44 return 0; | |
45 } | |
46 | |
14297 | 47 int avi_idx_cmp(const void *elem1,const void *elem2) { |
48 register off_t a = AVI_IDX_OFFSET((AVIINDEXENTRY *)elem1); | |
49 register off_t b = AVI_IDX_OFFSET((AVIINDEXENTRY *)elem2); | |
50 return (a > b) - (b > a); | |
12036 | 51 } |
601 | 52 |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
53 void read_avi_header(demuxer_t *demuxer,int index_mode){ |
426 | 54 sh_audio_t *sh_audio=NULL; |
55 sh_video_t *sh_video=NULL; | |
1 | 56 int stream_id=-1; |
568 | 57 int idxfix_videostream=0; |
58 int idxfix_divx=0; | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
59 avi_priv_t* priv=demuxer->priv; |
4664 | 60 off_t list_end=0; |
1 | 61 |
62 //---- AVI header: | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
63 priv->idx_size=0; |
2330 | 64 priv->audio_streams=0; |
1 | 65 while(1){ |
66 int id=stream_read_dword_le(demuxer->stream); | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
67 unsigned chunksize,size2; |
1 | 68 static int last_fccType=0; |
1671
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
69 char* hdr=NULL; |
1 | 70 // |
71 if(stream_eof(demuxer->stream)) break; | |
11234
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
72 // Imply -forceidx if -saveidx is specified |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
73 if (index_file_save) |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
74 index_mode = 2; |
1 | 75 // |
76 if(id==mmioFOURCC('L','I','S','T')){ | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
77 unsigned len=stream_read_dword_le(demuxer->stream); // list size |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
78 id=stream_read_dword_le(demuxer->stream); // list type |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
79 mp_msg(MSGT_HEADER,MSGL_DBG2,"LIST %.4s len=%u\n",(char *) &id,len); |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
80 if(len >= 4) { |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
81 len -= 4; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
82 list_end=stream_tell(demuxer->stream)+((len+1)&(~1)); |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
83 } else { |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
84 mp_msg(MSGT_HEADER,MSGL_WARN,"** empty list?!\n"); |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
85 list_end = 0; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
86 } |
5933 | 87 mp_msg(MSGT_HEADER,MSGL_V,"list_end=0x%X\n",(int)list_end); |
1 | 88 if(id==listtypeAVIMOVIE){ |
89 // found MOVI header | |
4154 | 90 if(!demuxer->movi_start) demuxer->movi_start=stream_tell(demuxer->stream); |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
91 demuxer->movi_end=stream_tell(demuxer->stream)+len; |
1754 | 92 mp_msg(MSGT_HEADER,MSGL_V,"Found movie at 0x%X - 0x%X\n",(int)demuxer->movi_start,(int)demuxer->movi_end); |
6274 | 93 if(demuxer->stream->end_pos>demuxer->movi_end) demuxer->movi_end=demuxer->stream->end_pos; |
4621
16cbaff638ac
Don't read index for -forceidx and -nodix (speedup with bad media and not needed anyway)
atmos4
parents:
4225
diff
changeset
|
94 if(index_mode==-2 || index_mode==2 || index_mode==0) |
16cbaff638ac
Don't read index for -forceidx and -nodix (speedup with bad media and not needed anyway)
atmos4
parents:
4225
diff
changeset
|
95 break; // reading from non-seekable source (stdin) or forced index or no index forced |
7762 | 96 if(list_end>0) stream_seek(demuxer->stream,list_end); // skip movi |
97 list_end=0; | |
1 | 98 } |
99 continue; | |
100 } | |
101 size2=stream_read_dword_le(demuxer->stream); | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
102 mp_msg(MSGT_HEADER,MSGL_DBG2,"CHUNK %.4s len=%u\n",(char *) &id,size2); |
1 | 103 chunksize=(size2+1)&(~1); |
104 switch(id){ | |
4664 | 105 |
106 // Indicates where the subject of the file is archived | |
107 case mmioFOURCC('I','A','R','L'): hdr="Archival Location";break; | |
108 // Lists the artist of the original subject of the file; | |
109 // for example, "Michaelangelo." | |
110 case mmioFOURCC('I','A','R','T'): hdr="Artist";break; | |
111 // Lists the name of the person or organization that commissioned | |
112 // the subject of the file; for example "Pope Julian II." | |
113 case mmioFOURCC('I','C','M','S'): hdr="Commissioned";break; | |
114 // Provides general comments about the file or the subject | |
115 // of the file. If the comment is several sentences long, end each | |
116 // sentence with a period. Do not include new-line characters. | |
117 case mmioFOURCC('I','C','M','T'): hdr="Comments";break; | |
118 // Records the copyright information for the file; for example, | |
119 // "Copyright Encyclopedia International 1991." If there are multiple | |
120 // copyrights, separate them by semicolon followed by a space. | |
121 case mmioFOURCC('I','C','O','P'): hdr="Copyright";break; | |
122 // Describes whether an image has been cropped and, if so, how it | |
123 // was cropped; for example, "lower-right corner." | |
124 case mmioFOURCC('I','C','R','D'): hdr="Creation Date";break; | |
125 // Describes whether an image has been cropped and, if so, how it | |
126 // was cropped; for example, "lower-right corner." | |
127 case mmioFOURCC('I','C','R','P'): hdr="Cropped";break; | |
128 // Specifies the size of the original subject of the file; for | |
129 // example, "8.5 in h, 11 in w." | |
130 case mmioFOURCC('I','D','I','M'): hdr="Dimensions";break; | |
131 // Stores dots per inch setting of the digitizer used to | |
132 // produce the file, such as "300." | |
133 case mmioFOURCC('I','D','P','I'): hdr="Dots Per Inch";break; | |
134 // Stores the of the engineer who worked on the file. If there are | |
135 // multiple engineers, separate the names by a semicolon and a blank; | |
136 // for example, "Smith, John; Adams, Joe." | |
137 case mmioFOURCC('I','E','N','G'): hdr="Engineer";break; | |
138 // Describes the original work, such as "landscape,", "portrait," | |
139 // "still liefe," etc. | |
140 case mmioFOURCC('I','G','N','R'): hdr="Genre";break; | |
141 // Provides a list of keywords that refer to the file or subject of the | |
142 // file. Separate multiple keywords with a semicolon and a blank; | |
143 // for example, "Seattle, aerial view; scenery." | |
144 case mmioFOURCC('I','K','E','Y'): hdr="Keywords";break; | |
145 // ILGT - Describes the changes in the lightness settings on the digitizer | |
146 // required to produce the file. Note that the format of this information | |
147 // depends on the hardware used. | |
148 case mmioFOURCC('I','L','G','T'): hdr="Lightness";break; | |
149 // IMED - Decribes the original subject of the file, such as | |
150 // "computer image," "drawing," "lithograph," and so on. | |
151 case mmioFOURCC('I','M','E','D'): hdr="Medium";break; | |
152 // INAM - Stores the title of the subject of the file, such as | |
153 // "Seattle from Above." | |
1671
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
154 case mmioFOURCC('I','N','A','M'): hdr="Name";break; |
4664 | 155 // IPLT - Specifies the number of colors requested when digitizing |
156 // an image, such as "256." | |
157 case mmioFOURCC('I','P','L','T'): hdr="Palette Setting";break; | |
158 // IPRD - Specifies the name of title the file was originally intended | |
159 // for, such as "Encyclopedia of Pacific Northwest Geography." | |
160 case mmioFOURCC('I','P','R','D'): hdr="Product";break; | |
161 // ISBJ - Decsribes the contents of the file, such as | |
162 // "Aerial view of Seattle." | |
163 case mmioFOURCC('I','S','B','J'): hdr="Subject";break; | |
164 // ISFT - Identifies the name of the software packages used to create the | |
165 // file, such as "Microsoft WaveEdit" | |
166 case mmioFOURCC('I','S','F','T'): hdr="Software";break; | |
167 // ISHP - Identifies the change in sharpness for the digitizer | |
168 // required to produce the file (the format depends on the hardware used). | |
169 case mmioFOURCC('I','S','H','P'): hdr="Sharpness";break; | |
170 // ISRC - Identifies the name of the person or organization who | |
171 // suplied the original subject of the file; for example, "Try Research." | |
172 case mmioFOURCC('I','S','R','C'): hdr="Source";break; | |
173 // ISRF - Identifies the original form of the material that was digitized, | |
174 // such as "slide," "paper," "map," and so on. This is not necessarily | |
175 // the same as IMED | |
176 case mmioFOURCC('I','S','R','F'): hdr="Source Form";break; | |
177 // ITCH - Identifies the technician who digitized the subject file; | |
178 // for example, "Smith, John." | |
179 case mmioFOURCC('I','T','C','H'): hdr="Technician";break; | |
180 case mmioFOURCC('I','S','M','P'): hdr="Time Code";break; | |
181 case mmioFOURCC('I','D','I','T'): hdr="Digitization Time";break; | |
182 | |
1 | 183 case ckidAVIMAINHDR: // read 'avih' |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
184 stream_read(demuxer->stream,(char*) &avih,MIN(size2,sizeof(avih))); |
1309
598e3047ce13
Add some preliminary support for non-x86 architectures to mplayer
jkeil
parents:
1289
diff
changeset
|
185 le2me_MainAVIHeader(&avih); // swap to machine endian |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
186 chunksize-=MIN(size2,sizeof(avih)); |
8027 | 187 if(verbose>0) print_avih(&avih); // else print_avih_flags(&avih); |
1 | 188 break; |
189 case ckidSTREAMHEADER: { // read 'strh' | |
190 AVIStreamHeader h; | |
191 stream_read(demuxer->stream,(char*) &h,MIN(size2,sizeof(h))); | |
1309
598e3047ce13
Add some preliminary support for non-x86 architectures to mplayer
jkeil
parents:
1289
diff
changeset
|
192 le2me_AVIStreamHeader(&h); // swap to machine endian |
1 | 193 chunksize-=MIN(size2,sizeof(h)); |
426 | 194 ++stream_id; |
195 if(h.fccType==streamtypeVIDEO){ | |
1289 | 196 sh_video=new_sh_video(demuxer,stream_id); |
426 | 197 memcpy(&sh_video->video,&h,sizeof(h)); |
198 } else | |
199 if(h.fccType==streamtypeAUDIO){ | |
1289 | 200 sh_audio=new_sh_audio(demuxer,stream_id); |
426 | 201 memcpy(&sh_audio->audio,&h,sizeof(h)); |
202 } | |
1 | 203 last_fccType=h.fccType; |
204 if(verbose>=1) print_strh(&h); | |
205 break; } | |
12036 | 206 case mmioFOURCC('i', 'n', 'd', 'x'): { |
12342 | 207 uint32_t i; |
12036 | 208 unsigned msize = 0; |
209 avisuperindex_chunk *s; | |
210 priv->suidx_size++; | |
211 priv->suidx = realloc(priv->suidx, priv->suidx_size * sizeof (avisuperindex_chunk)); | |
212 s = &priv->suidx[priv->suidx_size-1]; | |
213 | |
214 chunksize-=24; | |
215 memcpy(s->fcc, "indx", 4); | |
216 s->dwSize = size2; | |
217 s->wLongsPerEntry = stream_read_word_le(demuxer->stream); | |
218 s->bIndexSubType = stream_read_char(demuxer->stream); | |
219 s->bIndexType = stream_read_char(demuxer->stream); | |
220 s->nEntriesInUse = stream_read_dword_le(demuxer->stream); | |
221 *(uint32_t *)s->dwChunkId = stream_read_dword_le(demuxer->stream); | |
222 stream_read(demuxer->stream, (char *)s->dwReserved, 3*4); | |
223 memset(s->dwReserved, 0, 3*4); | |
224 | |
225 print_avisuperindex_chunk(s); | |
226 | |
227 msize = sizeof (uint32_t) * s->wLongsPerEntry * s->nEntriesInUse; | |
228 s->aIndex = malloc(msize); | |
229 memset (s->aIndex, 0, msize); | |
230 s->stdidx = malloc (s->nEntriesInUse * sizeof (avistdindex_chunk)); | |
231 memset (s->stdidx, 0, s->nEntriesInUse * sizeof (avistdindex_chunk)); | |
232 | |
233 // now the real index of indices | |
234 for (i=0; i<s->nEntriesInUse; i++) { | |
235 chunksize-=16; | |
236 s->aIndex[i].qwOffset = stream_read_dword_le(demuxer->stream) & 0xffffffff; | |
237 s->aIndex[i].qwOffset |= ((uint64_t)stream_read_dword_le(demuxer->stream) & 0xffffffff)<<32; | |
238 s->aIndex[i].dwSize = stream_read_dword_le(demuxer->stream); | |
239 s->aIndex[i].dwDuration = stream_read_dword_le(demuxer->stream); | |
240 mp_msg (MSGT_HEADER, MSGL_V, "ODML (%.4s): [%d] 0x%016llx 0x%04lx %ld\n", | |
241 (s->dwChunkId), i, | |
242 (uint64_t)s->aIndex[i].qwOffset, s->aIndex[i].dwSize, s->aIndex[i].dwDuration); | |
243 } | |
244 | |
245 break; } | |
1 | 246 case ckidSTREAMFORMAT: { // read 'strf' |
247 if(last_fccType==streamtypeVIDEO){ | |
433 | 248 sh_video->bih=calloc((chunksize<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):chunksize,1); |
249 // sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize); | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
250 mp_msg(MSGT_HEADER,MSGL_V,"found 'bih', %u 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
|
251 stream_read(demuxer->stream,(char*) sh_video->bih,chunksize); |
1309
598e3047ce13
Add some preliminary support for non-x86 architectures to mplayer
jkeil
parents:
1289
diff
changeset
|
252 le2me_BITMAPINFOHEADER(sh_video->bih); // swap to machine endian |
5418
5b852c08473f
I hate M$. it seems that MSRLE biSize is always 40 when number of colors < 256 instead of 40+colors*4
arpi
parents:
4664
diff
changeset
|
253 // fixup MS-RLE header (seems to be broken for <256 color files) |
7784 | 254 if(sh_video->bih->biCompression<=1 && sh_video->bih->biSize==40) |
5418
5b852c08473f
I hate M$. it seems that MSRLE biSize is always 40 when number of colors < 256 instead of 40+colors*4
arpi
parents:
4664
diff
changeset
|
255 sh_video->bih->biSize=chunksize; |
1492 | 256 if(verbose>=1) print_video_header(sh_video->bih); |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
257 chunksize=0; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
258 // 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
|
259 // sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; |
426 | 260 // if(demuxer->video->id==-1) demuxer->video->id=stream_id; |
568 | 261 // IdxFix: |
262 idxfix_videostream=stream_id; | |
263 switch(sh_video->bih->biCompression){ | |
6275 | 264 case mmioFOURCC('M', 'P', 'G', '4'): |
265 case mmioFOURCC('m', 'p', 'g', '4'): | |
266 case mmioFOURCC('D', 'I', 'V', '1'): | |
13700 | 267 idxfix_divx=3; // set index recovery mpeg4 flavour: msmpeg4v1 |
6275 | 268 mp_msg(MSGT_HEADER,MSGL_V,"Regenerating keyframe table for M$ mpg4v1 video\n"); |
269 break; | |
270 case mmioFOURCC('D', 'I', 'V', '3'): | |
568 | 271 case mmioFOURCC('d', 'i', 'v', '3'): |
272 case mmioFOURCC('D', 'I', 'V', '4'): | |
273 case mmioFOURCC('d', 'i', 'v', '4'): | |
274 case mmioFOURCC('D', 'I', 'V', '5'): | |
275 case mmioFOURCC('d', 'i', 'v', '5'): | |
276 case mmioFOURCC('D', 'I', 'V', '6'): | |
277 case mmioFOURCC('d', 'i', 'v', '6'): | |
278 case mmioFOURCC('M', 'P', '4', '3'): | |
279 case mmioFOURCC('m', 'p', '4', '3'): | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
280 case mmioFOURCC('M', 'P', '4', '2'): |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
281 case mmioFOURCC('m', 'p', '4', '2'): |
773 | 282 case mmioFOURCC('D', 'I', 'V', '2'): |
568 | 283 case mmioFOURCC('A', 'P', '4', '1'): |
13700 | 284 idxfix_divx=1; // set index recovery mpeg4 flavour: msmpeg4v3 |
285 mp_msg(MSGT_HEADER,MSGL_V,"Regenerating keyframe table for DIVX3 video\n"); | |
2598
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
286 break; |
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
287 case mmioFOURCC('D', 'I', 'V', 'X'): |
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
288 case mmioFOURCC('d', 'i', 'v', 'x'): |
6274 | 289 case mmioFOURCC('D', 'X', '5', '0'): |
13671 | 290 case mmioFOURCC('X', 'V', 'I', 'D'): |
291 case mmioFOURCC('x', 'v', 'i', 'd'): | |
14766 | 292 case mmioFOURCC('F', 'M', 'P', '4'): |
293 case mmioFOURCC('f', 'm', 'p', '4'): | |
13700 | 294 idxfix_divx=2; // set index recovery mpeg4 flavour: generic mpeg4 |
295 mp_msg(MSGT_HEADER,MSGL_V,"Regenerating keyframe table for MPEG4 video\n"); | |
2598
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
296 break; |
568 | 297 } |
1 | 298 } else |
299 if(last_fccType==streamtypeAUDIO){ | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
300 unsigned wf_size = chunksize<sizeof(WAVEFORMATEX)?sizeof(WAVEFORMATEX):chunksize; |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J«ärgen Keil <jk@tools.de>
arpi_esp
parents:
773
diff
changeset
|
301 sh_audio->wf=calloc(wf_size,1); |
433 | 302 // sh_audio->wf=malloc(chunksize); memset(sh_audio->wf,0,chunksize); |
1567 | 303 mp_msg(MSGT_HEADER,MSGL_V,"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
|
304 stream_read(demuxer->stream,(char*) sh_audio->wf,chunksize); |
1309
598e3047ce13
Add some preliminary support for non-x86 architectures to mplayer
jkeil
parents:
1289
diff
changeset
|
305 le2me_WAVEFORMATEX(sh_audio->wf); |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J«ärgen Keil <jk@tools.de>
arpi_esp
parents:
773
diff
changeset
|
306 if (sh_audio->wf->cbSize != 0 && |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J«ärgen Keil <jk@tools.de>
arpi_esp
parents:
773
diff
changeset
|
307 wf_size < sizeof(WAVEFORMATEX)+sh_audio->wf->cbSize) { |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J«ärgen Keil <jk@tools.de>
arpi_esp
parents:
773
diff
changeset
|
308 sh_audio->wf=realloc(sh_audio->wf, sizeof(WAVEFORMATEX)+sh_audio->wf->cbSize); |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J«ärgen Keil <jk@tools.de>
arpi_esp
parents:
773
diff
changeset
|
309 } |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
310 chunksize=0; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
426
diff
changeset
|
311 if(verbose>=1) print_wave_header(sh_audio->wf); |
2330 | 312 ++priv->audio_streams; |
426 | 313 // if(demuxer->audio->id==-1) demuxer->audio->id=stream_id; |
1 | 314 } |
315 break; | |
316 } | |
12036 | 317 case mmioFOURCC('v', 'p', 'r', 'p'): { |
318 VideoPropHeader *vprp = malloc(chunksize); | |
12342 | 319 unsigned int i; |
12036 | 320 stream_read(demuxer->stream, (void*)vprp, chunksize); |
321 le2me_VideoPropHeader(vprp); | |
322 chunksize -= sizeof(*vprp)-sizeof(vprp->FieldInfo); | |
323 chunksize /= sizeof(VIDEO_FIELD_DESC); | |
324 if (vprp->nbFieldPerFrame > chunksize) { | |
325 vprp->nbFieldPerFrame = chunksize; | |
326 } | |
327 chunksize = 0; | |
328 for (i=0; i<vprp->nbFieldPerFrame; i++) { | |
329 le2me_VIDEO_FIELD_DESC(&vprp->FieldInfo[i]); | |
330 } | |
12061 | 331 if (sh_video) { |
12036 | 332 sh_video->aspect = GET_AVI_ASPECT(vprp->dwFrameAspectRatio); |
333 } | |
334 if(verbose>=1) print_vprp(vprp); | |
335 break; | |
336 } | |
337 case mmioFOURCC('d', 'm', 'l', 'h'): { | |
338 // dmlh 00 00 00 04 frms | |
339 unsigned int total_frames = stream_read_dword_le(demuxer->stream); | |
340 mp_msg(MSGT_HEADER,MSGL_V,"AVI: dmlh found (size=%d) (total_frames=%d)\n", chunksize, total_frames); | |
341 stream_skip(demuxer->stream, chunksize-4); | |
342 chunksize = 0; | |
343 } | |
344 break; | |
4225 | 345 case ckidAVINEWINDEX: |
346 if(demuxer->movi_end>stream_tell(demuxer->stream)) | |
347 demuxer->movi_end=stream_tell(demuxer->stream); // fixup movi-end | |
12036 | 348 if(index_mode && !priv->isodml){ |
1309
598e3047ce13
Add some preliminary support for non-x86 architectures to mplayer
jkeil
parents:
1289
diff
changeset
|
349 int i; |
12036 | 350 off_t base = 0; |
351 uint32_t last_off = 0; | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
352 priv->idx_size=size2>>4; |
7762 | 353 mp_msg(MSGT_HEADER,MSGL_V,"Reading INDEX block, %d chunks for %ld frames (fpos=%p)\n", |
354 priv->idx_size,avih.dwTotalFrames, stream_tell(demuxer->stream)); | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
355 priv->idx=malloc(priv->idx_size<<4); |
7762 | 356 // printf("\nindex to %p !!!!! (priv=%p)\n",priv->idx,priv); |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
357 stream_read(demuxer->stream,(char*)priv->idx,priv->idx_size<<4); |
12737
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
358 for (i = 0; i < priv->idx_size; i++) { // swap index to machine endian |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
359 AVIINDEXENTRY *entry=(AVIINDEXENTRY*)priv->idx + i; |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
360 le2me_AVIINDEXENTRY(entry); |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
361 /* |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
362 * We (ab)use the upper word for bits 32-47 of the offset, so |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
363 * we'll clear them here. |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
364 * FIXME: AFAIK no codec uses them, but if one does it will break |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
365 */ |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
366 entry->dwFlags&=0xffff; |
ac56419ba6db
We still need to make sure the upper 16 bits of dwFlags are cleared
ranma
parents:
12736
diff
changeset
|
367 } |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
368 chunksize-=priv->idx_size<<4; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
369 if(verbose>=2) print_index(priv->idx,priv->idx_size); |
1 | 370 } |
12036 | 371 break; |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
372 /* added May 2002 */ |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
373 case mmioFOURCC('R','I','F','F'): { |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
374 char riff_type[4]; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
375 |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
376 mp_msg(MSGT_HEADER, MSGL_V, "additional RIFF header...\n"); |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
377 stream_read(demuxer->stream, riff_type, sizeof riff_type); |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
378 if (strncmp(riff_type, "AVIX", sizeof riff_type)) |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
379 mp_msg(MSGT_HEADER, MSGL_WARN, |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
380 "** warning: this is no extended AVI header..\n"); |
12362 | 381 else { |
382 /* | |
383 * We got an extended AVI header, so we need to switch to | |
384 * ODML to get seeking to work, provided we got indx chunks | |
385 * in the header (suidx_size > 0). | |
386 */ | |
387 if (priv->suidx_size > 0) | |
388 priv->isodml = 1; | |
389 } | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
390 chunksize = 0; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
391 list_end = 0; /* a new list will follow */ |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
392 break; } |
12036 | 393 case ckidAVIPADDING: |
394 stream_skip(demuxer->stream, chunksize); | |
395 chunksize = 0; | |
396 break; | |
1 | 397 } |
1671
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
398 if(hdr){ |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
399 mp_msg(MSGT_HEADER,MSGL_V,"hdr=%s size=%u\n",hdr,size2); |
4664 | 400 if(size2==3) |
401 chunksize=1; // empty | |
402 else { | |
1671
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
403 char buf[256]; |
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
404 int len=(size2<250)?size2:250; |
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
405 stream_read(demuxer->stream,buf,len); |
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
406 chunksize-=len; |
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
407 buf[len]=0; |
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
408 mp_msg(MSGT_HEADER,MSGL_V,"%-10s: %s\n",hdr,buf); |
3071 | 409 demux_info_add(demuxer, hdr, buf); |
4664 | 410 } |
1671
e6804fef9061
print AVI info block (copyright,artist etc) (-v only)
arpi
parents:
1567
diff
changeset
|
411 } |
4664 | 412 mp_msg(MSGT_HEADER,MSGL_DBG2,"list_end=0x%X pos=0x%X chunksize=0x%X next=0x%X\n", |
413 (int)list_end, (int)stream_tell(demuxer->stream), | |
414 chunksize, (int)chunksize+stream_tell(demuxer->stream)); | |
12036 | 415 if(list_end>0 && |
416 chunksize+stream_tell(demuxer->stream) == list_end) list_end=0; | |
4664 | 417 if(list_end>0 && chunksize+stream_tell(demuxer->stream)>list_end){ |
418 mp_msg(MSGT_HEADER,MSGL_V,"Broken chunk? chunksize=%d (id=%.4s)\n",chunksize,(char *) &id); | |
419 stream_seek(demuxer->stream,list_end); | |
420 list_end=0; | |
421 } else | |
1 | 422 if(chunksize>0) stream_skip(demuxer->stream,chunksize); else |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
423 if((int)chunksize<0) mp_msg(MSGT_HEADER,MSGL_WARN,"chunksize=%u (id=%.4s)\n",chunksize,(char *) &id); |
1 | 424 |
425 } | |
426 | |
12728
5369a905c5a5
If we don't have a NEWAVIINDEX chunk, but have an OpenDML index,
ranma
parents:
12362
diff
changeset
|
427 if (priv->suidx_size > 0 && priv->idx_size == 0) { |
5369a905c5a5
If we don't have a NEWAVIINDEX chunk, but have an OpenDML index,
ranma
parents:
12362
diff
changeset
|
428 /* |
5369a905c5a5
If we don't have a NEWAVIINDEX chunk, but have an OpenDML index,
ranma
parents:
12362
diff
changeset
|
429 * No NEWAVIINDEX, but we got an OpenDML index. |
5369a905c5a5
If we don't have a NEWAVIINDEX chunk, but have an OpenDML index,
ranma
parents:
12362
diff
changeset
|
430 */ |
5369a905c5a5
If we don't have a NEWAVIINDEX chunk, but have an OpenDML index,
ranma
parents:
12362
diff
changeset
|
431 priv->isodml = 1; |
5369a905c5a5
If we don't have a NEWAVIINDEX chunk, but have an OpenDML index,
ranma
parents:
12362
diff
changeset
|
432 } |
5369a905c5a5
If we don't have a NEWAVIINDEX chunk, but have an OpenDML index,
ranma
parents:
12362
diff
changeset
|
433 |
12036 | 434 if (priv->isodml && (index_mode==-1 || index_mode==0)) { |
435 int i, j, k; | |
436 int safety=1000; | |
437 | |
438 avisuperindex_chunk *cx; | |
439 AVIINDEXENTRY *idx; | |
440 | |
441 | |
442 if (priv->idx_size) free(priv->idx); | |
443 priv->idx_size = 0; | |
444 priv->idx_offset = 0; | |
445 priv->idx = NULL; | |
446 | |
447 mp_msg(MSGT_HEADER, MSGL_INFO, | |
448 "AVI: ODML: Building odml index (%d superindexchunks)\n", priv->suidx_size); | |
449 | |
450 // read the standard indices | |
451 for (cx = &priv->suidx[0], i=0; i<priv->suidx_size; cx++, i++) { | |
452 stream_reset(demuxer->stream); | |
453 for (j=0; j<cx->nEntriesInUse; j++) { | |
454 int ret1, ret2; | |
455 memset(&cx->stdidx[j], 0, 32); | |
456 ret1 = stream_seek(demuxer->stream, (off_t)cx->aIndex[j].qwOffset); | |
457 ret2 = stream_read(demuxer->stream, (char *)&cx->stdidx[j], 32); | |
458 if (ret1 != 1 || ret2 != 32 || cx->stdidx[j].nEntriesInUse==0) { | |
459 // this is a broken file (probably incomplete) let the standard | |
460 // gen_index routine handle this | |
461 priv->isodml = 0; | |
462 priv->idx_size = 0; | |
463 mp_msg(MSGT_HEADER, MSGL_WARN, | |
464 "AVI: ODML: Broken (incomplete?) file detected. Will use traditional index\n"); | |
465 goto freeout; | |
466 } | |
467 | |
468 le2me_AVISTDIDXCHUNK(&cx->stdidx[j]); | |
469 print_avistdindex_chunk(&cx->stdidx[j]); | |
470 priv->idx_size += cx->stdidx[j].nEntriesInUse; | |
471 cx->stdidx[j].aIndex = malloc(cx->stdidx[j].nEntriesInUse*sizeof(avistdindex_entry)); | |
472 stream_read(demuxer->stream, (char *)cx->stdidx[j].aIndex, | |
473 cx->stdidx[j].nEntriesInUse*sizeof(avistdindex_entry)); | |
474 for (k=0;k<cx->stdidx[j].nEntriesInUse; k++) | |
475 le2me_AVISTDIDXENTRY(&cx->stdidx[j].aIndex[k]); | |
476 | |
477 cx->stdidx[j].dwReserved3 = 0; | |
478 | |
479 } | |
480 } | |
481 | |
482 /* | |
483 * We convert the index by translating all entries into AVIINDEXENTRYs | |
484 * and sorting them by offset. The result should be the same index | |
485 * we would get with -forceidx. | |
486 */ | |
487 | |
488 idx = priv->idx = malloc(priv->idx_size * sizeof (AVIINDEXENTRY)); | |
489 | |
490 for (cx = priv->suidx; cx != &priv->suidx[priv->suidx_size]; cx++) { | |
491 avistdindex_chunk *sic; | |
492 for (sic = cx->stdidx; sic != &cx->stdidx[cx->nEntriesInUse]; sic++) { | |
493 avistdindex_entry *sie; | |
494 for (sie = sic->aIndex; sie != &sic->aIndex[sic->nEntriesInUse]; sie++) { | |
495 uint64_t off = sic->qwBaseOffset + sie->dwOffset - 8; | |
496 memcpy(&idx->ckid, sic->dwChunkId, 4); | |
497 idx->dwChunkOffset = off; | |
498 idx->dwFlags = (off >> 32) << 16; | |
499 idx->dwChunkLength = sie->dwSize & 0x7fffffff; | |
500 idx->dwFlags |= (sie->dwSize&0x80000000)?0x0:AVIIF_KEYFRAME; // bit 31 denotes !keyframe | |
501 idx++; | |
502 } | |
503 } | |
504 } | |
14297 | 505 qsort(priv->idx, priv->idx_size, sizeof(AVIINDEXENTRY), avi_idx_cmp); |
12036 | 506 |
507 /* | |
508 Hack to work around a "wrong" index in some divx odml files | |
509 (processor_burning.avi as an example) | |
510 They have ##dc on non keyframes but the ix00 tells us they are ##db. | |
511 Read the fcc of a non-keyframe vid frame and check it. | |
512 */ | |
513 | |
514 { | |
515 uint32_t id; | |
516 uint32_t db = 0; | |
517 stream_reset (demuxer->stream); | |
518 | |
519 // find out the video stream id. I have seen files with 01db. | |
520 for (idx = &((AVIINDEXENTRY *)priv->idx)[0], i=0; i<priv->idx_size; i++, idx++){ | |
521 unsigned char res[2]; | |
522 if (odml_get_vstream_id(idx->ckid, res)) { | |
523 db = mmioFOURCC(res[0], res[1], 'd', 'b'); | |
524 break; | |
525 } | |
526 } | |
527 | |
528 // find first non keyframe | |
529 for (idx = &((AVIINDEXENTRY *)priv->idx)[0], i=0; i<priv->idx_size; i++, idx++){ | |
530 if (!(idx->dwFlags & AVIIF_KEYFRAME) && idx->ckid == db) break; | |
531 } | |
532 if (i<priv->idx_size && db) { | |
533 stream_seek(demuxer->stream, AVI_IDX_OFFSET(idx)); | |
534 id = stream_read_dword_le(demuxer->stream); | |
535 if (id && id != db) // index fcc and real fcc differ? fix it. | |
536 for (idx = &((AVIINDEXENTRY *)priv->idx)[0], i=0; i<priv->idx_size; i++, idx++){ | |
537 if (!(idx->dwFlags & AVIIF_KEYFRAME) && idx->ckid == db) | |
538 idx->ckid = id; | |
539 } | |
540 } | |
541 } | |
542 | |
543 if (verbose>=2) print_index(priv->idx, priv->idx_size); | |
544 | |
545 demuxer->movi_end=demuxer->stream->end_pos; | |
546 | |
547 freeout: | |
548 | |
549 // free unneeded stuff | |
550 cx = &priv->suidx[0]; | |
551 do { | |
552 for (j=0;j<cx->nEntriesInUse;j++) | |
553 if (cx->stdidx[j].nEntriesInUse) free(cx->stdidx[j].aIndex); | |
554 free(cx->stdidx); | |
555 | |
556 } while (cx++ != &priv->suidx[priv->suidx_size-1]); | |
557 free(priv->suidx); | |
558 | |
559 } | |
560 | |
11234
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
561 /* Read a saved index file */ |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
562 if (index_file_load) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
563 FILE *fp; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
564 char magic[7]; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
565 unsigned int i; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
566 |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
567 if ((fp = fopen(index_file_load, "r")) == NULL) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
568 mp_msg(MSGT_HEADER,MSGL_ERR, "Can't read index file %s: %s\n", index_file_load, strerror(errno)); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
569 goto gen_index; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
570 } |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
571 fread(&magic, 6, 1, fp); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
572 if (strncmp(magic, "MPIDX1", 6)) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
573 mp_msg(MSGT_HEADER,MSGL_ERR, "%s is not a valid MPlayer index file\n", index_file_load); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
574 goto gen_index; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
575 } |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
576 fread(&priv->idx_size, sizeof(priv->idx_size), 1, fp); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
577 priv->idx=malloc(priv->idx_size*sizeof(AVIINDEXENTRY)); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
578 if (!priv->idx) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
579 mp_msg(MSGT_HEADER,MSGL_ERR, "Could not allocate memory for index data from %s\n", index_file_load); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
580 priv->idx_size = 0; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
581 goto gen_index; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
582 } |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
583 |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
584 for (i=0; i<priv->idx_size;i++) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
585 AVIINDEXENTRY *idx; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
586 idx=&((AVIINDEXENTRY *)priv->idx)[i]; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
587 fread(idx, sizeof(AVIINDEXENTRY), 1, fp); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
588 if (feof(fp)) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
589 mp_msg(MSGT_HEADER,MSGL_ERR, "Premature end of index file %s\n", index_file_load); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
590 free(priv->idx); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
591 priv->idx_size = 0; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
592 goto gen_index; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
593 } |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
594 } |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
595 fclose(fp); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
596 mp_msg(MSGT_HEADER,MSGL_INFO, "Loaded index file: %s\n", index_file_load); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
597 } |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
598 gen_index: |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
599 if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){ |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
600 // build index for file: |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
601 stream_reset(demuxer->stream); |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
569
diff
changeset
|
602 stream_seek(demuxer->stream,demuxer->movi_start); |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
603 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
604 priv->idx_pos=0; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
605 priv->idx_size=0; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
606 priv->idx=NULL; |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
607 |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
608 while(1){ |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
609 int id; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
610 unsigned len; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
611 off_t skip; |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
612 AVIINDEXENTRY* idx; |
2598
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
613 unsigned int c; |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
614 demuxer->filepos=stream_tell(demuxer->stream); |
2598
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
615 if(demuxer->filepos>=demuxer->movi_end && demuxer->movi_start<demuxer->movi_end) break; |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
616 id=stream_read_dword_le(demuxer->stream); |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
617 len=stream_read_dword_le(demuxer->stream); |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
618 if(id==mmioFOURCC('L','I','S','T') || id==mmioFOURCC('R', 'I', 'F', 'F')){ |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
619 id=stream_read_dword_le(demuxer->stream); // list or RIFF type |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
620 continue; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
621 } |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
622 if(stream_eof(demuxer->stream)) break; |
1392 | 623 if(!id || avi_stream_id(id)==100) goto skip_chunk; // bad ID (or padding?) |
624 | |
1499 | 625 if(priv->idx_pos>=priv->idx_size){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
626 // priv->idx_size+=32; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
627 priv->idx_size+=1024; // +16kB |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
628 priv->idx=realloc(priv->idx,priv->idx_size*sizeof(AVIINDEXENTRY)); |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
629 if(!priv->idx){priv->idx_pos=0; break;} // error! |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
630 } |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
631 idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++]; |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
632 idx->ckid=id; |
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
633 idx->dwFlags=AVIIF_KEYFRAME; // FIXME |
12036 | 634 idx->dwFlags|=(demuxer->filepos>>16)&0xffff0000U; |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
635 idx->dwChunkOffset=(unsigned long)demuxer->filepos; |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
636 idx->dwChunkLength=len; |
569 | 637 |
2598
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
638 c=stream_read_dword(demuxer->stream); |
568 | 639 |
640 // Fix keyframes for DivX files: | |
641 if(idxfix_divx) | |
642 if(avi_stream_id(id)==idxfix_videostream){ | |
2598
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
643 switch(idxfix_divx){ |
6275 | 644 case 3: c=stream_read_dword(demuxer->stream)<<5; //skip 32+5 bits for m$mpeg4v1 |
12036 | 645 case 1: if(c&0x40000000) idx->dwFlags&=~AVIIF_KEYFRAME;break; // divx 3 |
646 case 2: if(c==0x1B6) idx->dwFlags&=~AVIIF_KEYFRAME;break; // divx 4 | |
2598
a937f0024514
-idx fixes: support for divx4 and ignoring bad movi_end
arpi
parents:
2338
diff
changeset
|
647 } |
568 | 648 } |
3781 | 649 |
650 // update status line: | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
651 { static off_t lastpos; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
652 off_t pos; |
3781 | 653 off_t len=demuxer->movi_end-demuxer->movi_start; |
654 if(len){ | |
655 pos=100*(demuxer->filepos-demuxer->movi_start)/len; // % | |
656 } else { | |
657 pos=(demuxer->filepos-demuxer->movi_start)>>20; // MB | |
658 } | |
659 if(pos!=lastpos){ | |
660 lastpos=pos; | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
661 mp_msg(MSGT_HEADER,MSGL_STATUS,"Generating Index: %3lu %s \r", |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
662 (unsigned long)pos, len?"%":"MB"); |
3781 | 663 } |
664 } | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
665 mp_dbg(MSGT_HEADER,MSGL_DBG2,"%08X %08X %.4s %08X %X\n",(unsigned int)demuxer->filepos,id,(char *) &id,(int)c,(unsigned int) idx->dwFlags); |
568 | 666 #if 0 |
667 { unsigned char tmp[64]; | |
668 int i; | |
669 stream_read(demuxer->stream,tmp,64); | |
670 printf("%.4s",&id); | |
671 for(i=0;i<64;i++) printf(" %02X",tmp[i]); | |
672 printf("\n"); | |
673 } | |
674 #endif | |
1392 | 675 skip_chunk: |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
5933
diff
changeset
|
676 skip=(len+1)&(~1UL); // total bytes in this chunk |
568 | 677 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
|
678 } |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
679 priv->idx_size=priv->idx_pos; |
1567 | 680 mp_msg(MSGT_HEADER,MSGL_INFO,"AVI: Generated index table for %d chunks!\n",priv->idx_size); |
7762 | 681 if(verbose>=2) print_index(priv->idx,priv->idx_size); |
11234
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
682 |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
683 /* Write generated index to a file */ |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
684 if (index_file_save) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
685 FILE *fp; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
686 unsigned int i; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
687 |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
688 if ((fp=fopen(index_file_save, "w")) == NULL) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
689 mp_msg(MSGT_HEADER,MSGL_ERR, "Couldn't write index file %s: %s\n", index_file_save, strerror(errno)); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
690 return; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
691 } |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
692 fwrite("MPIDX1", 6, 1, fp); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
693 fwrite(&priv->idx_size, sizeof(priv->idx_size), 1, fp); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
694 for (i=0; i<priv->idx_size; i++) { |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
695 AVIINDEXENTRY *idx = &((AVIINDEXENTRY *)priv->idx)[i]; |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
696 fwrite(idx, sizeof(AVIINDEXENTRY), 1, fp); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
697 } |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
698 fclose(fp); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
699 mp_msg(MSGT_HEADER,MSGL_INFO, "Saved index file: %s\n", index_file_save); |
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
8027
diff
changeset
|
700 } |
564
747759a4a28f
seeking in raw/broken avi files (rebuilding index chunk)
arpi_esp
parents:
433
diff
changeset
|
701 } |
1 | 702 } |
703 | |
704 #undef MIN | |
705 | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1456
diff
changeset
|
706 |