1
|
1 // show QuickTime .mov file structure (C) 2001. by A'rpi/ESP-team
|
|
2
|
|
3 #include <stdio.h>
|
|
4 #include <stdlib.h>
|
|
5
|
|
6 unsigned int read_dword(FILE *f){
|
|
7 unsigned char atom_size_b[4];
|
|
8 if(fread(&atom_size_b,4,1,f)<=0) return -1;
|
|
9 return (atom_size_b[0]<<24)|(atom_size_b[1]<<16)|(atom_size_b[2]<<8)|atom_size_b[3];
|
|
10 }
|
|
11
|
|
12 void lschunks(FILE *f,int level,unsigned int endpos){
|
|
13 unsigned int atom_size;
|
|
14 unsigned int atom_type;
|
|
15 int pos;
|
|
16 while(endpos==0 || ftell(f)<endpos){
|
|
17 pos=ftell(f);
|
|
18 atom_size=read_dword(f);// if(fread(&atom_size_b,4,1,f)<=0) break;
|
|
19 if(fread(&atom_type,4,1,f)<=0) break;
|
|
20
|
|
21 if(atom_size<8) break; // error
|
|
22
|
|
23 printf("%08X: %*s %.4s (%08X) %d\n",pos,level*2,"",&atom_type,atom_type,atom_size);
|
|
24
|
|
25 if(atom_type==0x64737473) { // stsd
|
|
26 unsigned int tmp;
|
|
27 unsigned int count;
|
|
28 int i;
|
|
29 fread(&tmp,4,1,f);
|
|
30 count=read_dword(f);// fread(&count,4,1,f);
|
|
31 printf("desc count = %d\n",count);
|
|
32 for(i=0;i<count;i++){
|
|
33 unsigned int len;
|
|
34 unsigned int format;
|
|
35 len=read_dword(f); // fread(&len,4,1,f);
|
|
36 fread(&format,4,1,f);
|
|
37 printf(" desc #%d: %.4s (%d)\n",i+1,&format,len);
|
|
38 fseek(f,len-8,SEEK_CUR);
|
|
39 }
|
|
40 }
|
|
41
|
|
42 if(atom_type==0x6F637473) { // stco
|
|
43 int len,i;
|
|
44 read_dword(f);
|
|
45 len=read_dword(f);
|
|
46 printf("Chunk table size :%d\n",len);
|
|
47 for(i=0;i<len;i++) printf(" chunk #%d: 0x%X\n",i+1,read_dword(f));
|
|
48 }
|
|
49
|
|
50
|
|
51 if(atom_type==0x73747473) { // stts
|
|
52 int len,i;
|
|
53 read_dword(f);
|
|
54 len=read_dword(f);
|
|
55 printf("T->S table size :%d\n",len);
|
|
56 for(i=0;i<len;i++){
|
|
57 int num=read_dword(f);
|
|
58 int dur=read_dword(f);
|
|
59 printf("%5d samples: %d duration\n",num,dur);
|
|
60 }
|
|
61 }
|
|
62
|
|
63 if(atom_type==0x63737473) { // stsc
|
|
64 int len,i;
|
|
65 read_dword(f);
|
|
66 len=read_dword(f);
|
|
67 printf("S->C table size :%d\n",len);
|
|
68 for(i=0;i<len;i++){
|
|
69 int first=read_dword(f);
|
|
70 int spc=read_dword(f);
|
|
71 int sdid=read_dword(f);
|
|
72 printf(" chunk %d... %d s/c desc: %d\n",first,spc,sdid);
|
|
73 }
|
|
74 }
|
|
75
|
|
76 if(atom_type==0x7A737473) { // stsz
|
|
77 int len,i,ss;
|
|
78 read_dword(f);
|
|
79 ss=read_dword(f);
|
|
80 len=read_dword(f);
|
|
81 printf("Sample size table len: %d\n",len);
|
|
82 if(ss){
|
|
83 printf(" common sample size: %d bytes\n",ss);
|
|
84 } else {
|
|
85 for(i=0;i<len;i++) printf(" sample #%d: %d bytes\n",i+1,read_dword(f));
|
|
86 }
|
|
87 }
|
|
88
|
|
89
|
|
90 #if 1
|
|
91 switch(atom_type){
|
|
92 case 0x75716D72: // rmqu
|
|
93 case 0x65657266: // free JUNK
|
|
94 case 0x64686B74: // tkhd Track header
|
|
95 case 0x61746475: // udta User data
|
|
96 case 0x7461646D: // mdat Movie data
|
|
97 case 0x64737473: // stsd Sample description
|
|
98 case 0x6F637473: // stco Chunk offset table
|
|
99 case 0x73747473: // stts Sample time table
|
|
100 case 0x63737473: // stsc Sample->Chunk mapping table
|
|
101 case 0x7A737473: // stsz Sample size table
|
|
102 break;
|
|
103 default: lschunks(f,level+1,pos+atom_size);
|
|
104 }
|
|
105 #else
|
|
106 switch(atom_type){
|
|
107 case 0x766F6F6D: // moov
|
|
108 case 0x61726D72: // rmra
|
|
109 case 0x61646D72: // rmda
|
|
110 lschunks(f,level+1,pos+atom_size);
|
|
111 }
|
|
112 #endif
|
|
113 fseek(f,pos+atom_size,SEEK_SET);
|
|
114 }
|
|
115 }
|
|
116
|
|
117 int main(int argc,char* argv[]){
|
|
118 int pos;
|
|
119 FILE *f=fopen(argc>1?argv[1]:"Akira.mov","rb");
|
|
120 if(!f) return 1;
|
|
121
|
|
122 lschunks(f,0,0);
|
|
123
|
|
124 }
|