Mercurial > mplayer.hg
annotate TOOLS/movinfo.c @ 25509:1cfa39a320cc
Fix update_subtitles() checking subtitle type for the wrong track.
update_subtitles() uses 'type' field from d_dvdsub even when some other track
is active. For this reason, external vobsub is not displayed when there is at
least one text track from demuxer (type is always 't' or 'a' in this case).
The solution is to check vobsub_id and dvdsub_id instead.
author | eugeni |
---|---|
date | Fri, 28 Dec 2007 20:57:38 +0000 |
parents | bed2ed7f132c |
children | 5ac02417f474 |
rev | line source |
---|---|
1 | 1 // show QuickTime .mov file structure (C) 2001. by A'rpi/ESP-team |
1175 | 2 // various hacks by alex@naxine.org |
3 | |
4 /* | |
5 Blocks: 4bytes atom_size | |
6 4bytes atom_type (name) | |
7 ... | |
8 | |
9 By older files, mdat is at the beginning, and moov follows it later, | |
10 by newer files, moov is at the begininng. | |
11 | |
12 Fontosabb typeok: | |
13 | |
14 trak: track: ezeken belul van egy-egy stream (video/audio) | |
15 tkhd: track header: fps (video esten picture size is itt van) | |
16 vmhd: video media handler (video stream informaciok) | |
17 smhd: sound media handler (audio stream informaciok) | |
18 */ | |
1 | 19 |
20 #include <stdio.h> | |
21 #include <stdlib.h> | |
22 | |
1175 | 23 #undef NO_SPECIAL |
24 | |
25 char *atom2human_type(int type) | |
26 { | |
27 switch (type) | |
28 { | |
29 case 0x766F6F6D: return ("Information sections"); /* moov */ | |
30 case 0x6468766D: return ("Movie header"); /* mvhd */ | |
31 case 0x6169646D: return ("Media stream"); /* mdia */ | |
32 case 0x64686D76: return ("Video media header"); /* vmhd */ | |
33 case 0x64686D73: return ("Sound media header"); /* smhd */ | |
34 case 0x6468646D: return ("Media header"); /* mdhd */ | |
35 case 0x666E696D: return ("Media information"); /* minf */ | |
1199 | 36 case 0x726C6468: return ("Handler reference"); /* hdlr */ |
1175 | 37 case 0x6B617274: return ("New track (stream)"); /* trak */ |
38 case 0x75716D72: return ("rmqu"); | |
39 case 0x65657266: return ("free"); | |
40 case 0x64686B74: return ("Track header"); /* tkhd */ | |
41 case 0x61746475: return ("User data"); /* udta */ | |
42 case 0x7461646D: return ("Movie data"); /* mdat */ | |
43 case 0x6C627473: return ("Sample information table"); /* stbl */ | |
44 case 0x64737473: return ("Sample description"); /* stsd */ | |
45 case 0x6F637473: return ("Chunk offset table"); /* stco */ | |
46 case 0x73747473: return ("Sample time table"); /* stts */ | |
47 case 0x63737473: return ("Sample->Chunk mapping table"); /* stsc */ | |
48 case 0x7A737473: return ("Sample size table"); /* stsz */ | |
49 } | |
50 return("unknown"); | |
51 } | |
52 | |
53 #define S_NONE 0 | |
54 #define S_AUDIO 1 | |
55 #define S_VIDEO 2 | |
56 int stream = S_NONE; | |
57 int v_stream = 0; | |
58 int a_stream = 0; | |
59 | |
1 | 60 unsigned int read_dword(FILE *f){ |
61 unsigned char atom_size_b[4]; | |
62 if(fread(&atom_size_b,4,1,f)<=0) return -1; | |
63 return (atom_size_b[0]<<24)|(atom_size_b[1]<<16)|(atom_size_b[2]<<8)|atom_size_b[3]; | |
64 } | |
65 | |
24202 | 66 void video_stream_info(FILE *f, int len) |
1175 | 67 { |
68 int orig_pos = ftell(f); | |
69 unsigned char data[len-8]; | |
70 int i; | |
23658 | 71 // char codec[len-8]; |
1175 | 72 |
73 len -= 8; | |
74 for (i=0; i<len; i++) | |
75 fread(&data[i], 1, 1, f); | |
76 | |
6908 | 77 // strncpy(codec, &data[43], len-43); |
78 // printf(" [codec: %s]\n", &codec); | |
1175 | 79 fseek(f,orig_pos,SEEK_SET); |
80 } | |
81 | |
24202 | 82 void audio_stream_info(FILE *f, int len) |
1175 | 83 { |
84 int orig_pos = ftell(f); | |
85 unsigned char data[len-8]; | |
86 int i; | |
87 | |
88 len -= 8; | |
89 for (i=0; i<len; i++) | |
90 fread(&data[i], 1, 1, f); | |
91 | |
92 printf(" [%d bit", data[19]); | |
93 if (data[17] == 1) | |
94 printf(" mono"); | |
95 else | |
96 printf(" %d channels", data[17]); | |
97 printf("]\n"); | |
98 fseek(f,orig_pos,SEEK_SET); | |
99 } | |
100 | |
24202 | 101 void userdata_info(FILE *f, int len, int pos, int level) |
1199 | 102 { |
103 int orig_pos = pos; /*ftell(f);*/ | |
104 unsigned int atom_size = 1; | |
105 unsigned int atom_type; | |
106 | |
107 // printf("userdata @ %d:%d (%d)\n", pos, pos+len, len); | |
108 | |
109 // fseek(f, pos+3, SEEK_SET); | |
110 | |
111 while (atom_size != 0) | |
112 { | |
113 atom_size=read_dword(f);// if(fread(&atom_size_b,4,1,f)<=0) break; | |
114 if(fread(&atom_type,4,1,f)<=0) break; | |
115 | |
116 if(atom_size<8) break; // error | |
117 | |
118 // printf("%08X: %*s %.4s (%08X) %05d (begin: %08X)\n",pos,level*2,"", | |
119 // &atom_type,atom_type,atom_size,pos+8); | |
120 | |
121 switch(atom_type) | |
122 { | |
123 case 0x797063A9: /* cpy (copyright) */ | |
124 { | |
125 char *data = malloc(atom_size-8); | |
126 | |
127 fseek(f, pos+6, SEEK_SET); | |
128 fread(data, atom_size-8, 1, f); | |
129 printf(" Copyright: %s\n", data); | |
130 free(data); | |
131 } | |
132 break; | |
133 case 0x666E69A9: /* inf (information) */ | |
134 { | |
135 char data[atom_size-8]; | |
136 | |
137 fread(&data, 1, atom_size-8, f); | |
138 printf(" Owner: %s\n", &data); | |
139 } | |
140 break; | |
141 case 0x6D616EA9: /* nam (name) */ | |
142 { | |
143 char data[atom_size-8]; | |
144 | |
145 fread(&data, 1, atom_size-8, f); | |
146 printf(" Name: %s\n", &data); | |
147 } | |
148 break; | |
149 } | |
150 } | |
151 fseek(f,orig_pos,SEEK_SET); | |
152 } | |
153 | |
154 int time_scale = 0; | |
155 | |
1 | 156 void lschunks(FILE *f,int level,unsigned int endpos){ |
157 unsigned int atom_size; | |
158 unsigned int atom_type; | |
159 int pos; | |
1175 | 160 |
1 | 161 while(endpos==0 || ftell(f)<endpos){ |
162 pos=ftell(f); | |
163 atom_size=read_dword(f);// if(fread(&atom_size_b,4,1,f)<=0) break; | |
164 if(fread(&atom_type,4,1,f)<=0) break; | |
165 | |
166 if(atom_size<8) break; // error | |
167 | |
1175 | 168 printf("%08X: %*s %.4s (%08X) %05d [%s] (begin: %08X)\n",pos,level*2,"",&atom_type,atom_type,atom_size, |
169 atom2human_type(atom_type), pos+8); // 8: atom_size fields (4) + atom_type fields (4) | |
170 | |
171 #ifndef NO_SPECIAL | |
1199 | 172 // if (atom_type == 0x61746475) |
173 // userdata_info(f, atom_size, pos, level); | |
174 | |
175 if (atom_type == 0x6468646D) | |
176 { | |
177 char data[4]; | |
178 | |
179 fread(&data, 1, 1, f); // char | |
180 printf("mdhd version %d\n", data[0]); | |
181 fread(&data, 3, 1, f); // int24 | |
182 fread(&data, 4, 1, f); // int32 | |
183 fread(&data, 4, 1, f); // int32 | |
184 fread(&data, 4, 1, f); // int32 | |
185 time_scale = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; | |
186 printf("timescale: %d\n", time_scale); | |
187 fread(&data, 4, 1, f); // int32 | |
188 fread(&data, 2, 1, f); // int16 | |
189 fread(&data, 2, 1, f); // int16 | |
190 } | |
191 | |
1175 | 192 if (atom_type == 0x64686D76) |
193 { | |
194 stream = S_VIDEO; | |
195 printf(" Found VIDEO Stream #%d\n", v_stream++); | |
196 } | |
197 | |
198 if (atom_type == 0x64686D73) | |
199 { | |
200 stream = S_AUDIO; | |
201 printf(" Found AUDIO Stream #%d\n", a_stream++); | |
202 } | |
203 | |
204 if (atom_type == 0x64686B74) // tkhd - track header | |
205 { | |
206 int i; | |
207 unsigned char data[atom_size]; | |
1199 | 208 int x, y; |
1175 | 209 |
210 for (i=0; i<atom_size; i++) | |
211 fread(&data[i], 1, 1, f); | |
212 | |
213 x = data[77]; | |
214 y = data[81]; | |
1199 | 215 printf(" Flags: %d\n", data[3]); |
1175 | 216 printf(" Picture size: %dx%d\n", x, y); |
217 if (x == 0 && y == 0) | |
218 printf(" Possible audio stream!\n"); | |
219 } | |
1 | 220 |
221 if(atom_type==0x64737473) { // stsd | |
222 unsigned int tmp; | |
223 unsigned int count; | |
224 int i; | |
225 fread(&tmp,4,1,f); | |
226 count=read_dword(f);// fread(&count,4,1,f); | |
227 printf("desc count = %d\n",count); | |
228 for(i=0;i<count;i++){ | |
229 unsigned int len; | |
230 unsigned int format; | |
231 len=read_dword(f); // fread(&len,4,1,f); | |
232 fread(&format,4,1,f); | |
233 printf(" desc #%d: %.4s (%d)\n",i+1,&format,len); | |
1175 | 234 if (stream == S_VIDEO) |
235 video_stream_info(f, len); | |
236 if (stream == S_AUDIO) | |
237 audio_stream_info(f, len); | |
1 | 238 fseek(f,len-8,SEEK_CUR); |
239 } | |
240 } | |
241 | |
242 if(atom_type==0x6F637473) { // stco | |
243 int len,i; | |
244 read_dword(f); | |
245 len=read_dword(f); | |
246 printf("Chunk table size :%d\n",len); | |
247 for(i=0;i<len;i++) printf(" chunk #%d: 0x%X\n",i+1,read_dword(f)); | |
248 } | |
249 | |
250 | |
251 if(atom_type==0x73747473) { // stts | |
252 int len,i; | |
253 read_dword(f); | |
254 len=read_dword(f); | |
255 printf("T->S table size :%d\n",len); | |
256 for(i=0;i<len;i++){ | |
257 int num=read_dword(f); | |
258 int dur=read_dword(f); | |
1199 | 259 printf("%5d samples: %d duration", num, dur); |
260 if (stream == S_AUDIO) | |
261 printf("(rate: %f Hz)\n", (float)time_scale/dur); | |
262 else | |
263 printf("(fps: %f)\n", (float)time_scale/dur); | |
1 | 264 } |
265 } | |
266 | |
267 if(atom_type==0x63737473) { // stsc | |
268 int len,i; | |
269 read_dword(f); | |
270 len=read_dword(f); | |
271 printf("S->C table size :%d\n",len); | |
272 for(i=0;i<len;i++){ | |
273 int first=read_dword(f); | |
274 int spc=read_dword(f); | |
275 int sdid=read_dword(f); | |
1199 | 276 printf(" chunk %d... %d s/c desc: %d\n",first,spc,sdid); |
1 | 277 } |
278 } | |
279 | |
280 if(atom_type==0x7A737473) { // stsz | |
281 int len,i,ss; | |
282 read_dword(f); | |
283 ss=read_dword(f); | |
284 len=read_dword(f); | |
285 printf("Sample size table len: %d\n",len); | |
286 if(ss){ | |
287 printf(" common sample size: %d bytes\n",ss); | |
288 } else { | |
289 for(i=0;i<len;i++) printf(" sample #%d: %d bytes\n",i+1,read_dword(f)); | |
290 } | |
291 } | |
1175 | 292 #endif |
1 | 293 |
294 #if 1 | |
295 switch(atom_type){ | |
1175 | 296 case 0x7461646D: // mdat Movie data |
1 | 297 case 0x75716D72: // rmqu |
298 case 0x65657266: // free JUNK | |
299 case 0x64686B74: // tkhd Track header | |
300 case 0x61746475: // udta User data | |
301 case 0x64737473: // stsd Sample description | |
302 case 0x6F637473: // stco Chunk offset table | |
303 case 0x73747473: // stts Sample time table | |
304 case 0x63737473: // stsc Sample->Chunk mapping table | |
305 case 0x7A737473: // stsz Sample size table | |
6870 | 306 case 0x746f6e70: // pnot |
307 case 0x54434950: // PICT | |
6908 | 308 case 0x70797466: |
1 | 309 break; |
310 default: lschunks(f,level+1,pos+atom_size); | |
311 } | |
312 #else | |
313 switch(atom_type){ | |
314 case 0x766F6F6D: // moov | |
315 case 0x61726D72: // rmra | |
316 case 0x61646D72: // rmda | |
317 lschunks(f,level+1,pos+atom_size); | |
318 } | |
319 #endif | |
320 fseek(f,pos+atom_size,SEEK_SET); | |
321 } | |
322 } | |
323 | |
1175 | 324 int main(int argc,char* argv[]) |
325 { | |
326 FILE *f; | |
327 | |
328 if ((f = fopen(argc>1?argv[1]:"Akira.mov","rb")) == NULL) | |
329 return 1; | |
1 | 330 |
1175 | 331 printf("%.8s %.4s (%.8s) %05s [%s]\n\n", |
332 "position", "atom", "atomtype", "len", "human readable atom name"); | |
1 | 333 |
1175 | 334 lschunks(f, 0, 0); |
335 | |
336 printf("\nSummary: streams: %d video/%d audio\n", v_stream, a_stream); | |
23659
f15f95c2671a
Fix "control reaches end of non-void function" warnings.
diego
parents:
23658
diff
changeset
|
337 |
f15f95c2671a
Fix "control reaches end of non-void function" warnings.
diego
parents:
23658
diff
changeset
|
338 return 0; |
1 | 339 } |