Mercurial > mplayer.hg
annotate TOOLS/asfinfo.c @ 30251:fbb33d643fe6
Remove hackish and not actually working code to make vidix compile with
compilers without inline assembly.
Almost no OS provides inb() etc. in its libraries, and removing the
broken fallback code makes it compile on Solaris with Sun C compiler.
author | reimar |
---|---|
date | Tue, 12 Jan 2010 20:20:49 +0000 |
parents | b45a3ae01e54 |
children | b573c7c7173b |
rev | line source |
---|---|
1 | 1 #define SAVE_STREAMS |
2 | |
3 // simple ASF header display program by A'rpi/ESP-team | |
4 // .asf fileformat docs from http://divx.euro.ru | |
5 | |
6 #include <stdio.h> | |
7 #include <stdlib.h> | |
8 | |
27636 | 9 typedef struct __attribute__((packed)) |
1 | 10 { |
27636 | 11 long biSize; // sizeof(BITMAPINFOHEADER) |
12 long biWidth; | |
13 long biHeight; | |
14 short biPlanes; // unused | |
15 short biBitCount; | |
16 long biCompression; // fourcc of image | |
17 long biSizeImage; // size of image. For uncompressed images | |
18 // ( biCompression 0 or 3 ) can be zero. | |
1 | 19 |
20 | |
27636 | 21 long biXPelsPerMeter; // unused |
22 long biYPelsPerMeter; // unused | |
23 long biClrUsed; // valid only for palettized images. | |
24 // Number of colors in palette. | |
25 long biClrImportant; | |
1 | 26 } BITMAPINFOHEADER; |
27 | |
28 typedef struct | |
29 { | |
27636 | 30 short wFormatTag; // value that identifies compression format |
31 short nChannels; | |
32 long nSamplesPerSec; | |
33 long nAvgBytesPerSec; | |
34 short nBlockAlign; // size of a data sample | |
35 short wBitsPerSample; | |
36 short cbSize; // size of format-specific data | |
1 | 37 } WAVEFORMATEX; |
38 | |
39 typedef struct __attribute__((packed)) { | |
27636 | 40 unsigned char guid[16]; |
1 | 41 unsigned long long size; |
42 } ASF_obj_header_t; | |
43 | |
44 typedef struct __attribute__((packed)) { | |
45 ASF_obj_header_t objh; | |
27636 | 46 unsigned int cno; // number of subchunks |
47 unsigned char v1; // unknown (0x01) | |
48 unsigned char v2; // unknown (0x02) | |
1 | 49 } ASF_header_t; |
50 | |
51 typedef struct __attribute__((packed)) { | |
52 unsigned char client[16]; // Client GUID | |
53 unsigned long long file_size; | |
54 unsigned long long creat_time; //File creation time FILETIME 8 | |
55 unsigned long long packets; //Number of packets UINT64 8 | |
56 unsigned long long end_timestamp; //Timestamp of the end position UINT64 8 | |
57 unsigned long long duration; //Duration of the playback UINT64 8 | |
58 unsigned long start_timestamp; //Timestamp of the start position UINT32 4 | |
59 unsigned long unk1; //Unknown, maybe reserved ( usually contains 0 ) UINT32 4 | |
60 unsigned long flags; //Unknown, maybe flags ( usually contains 2 ) UINT32 4 | |
61 unsigned long packetsize; //Size of packet, in bytes UINT32 4 | |
62 unsigned long packetsize2; //Size of packet ( confirm ) UINT32 4 | |
63 unsigned long frame_size; //Size of uncompressed video frame UINT32 4 | |
64 } ASF_file_header_t; | |
65 | |
66 typedef struct __attribute__((packed)) { | |
67 unsigned char type[16]; // Stream type (audio/video) GUID 16 | |
68 unsigned char concealment[16]; // Audio error concealment type GUID 16 | |
69 unsigned long long unk1; // Unknown, maybe reserved ( usually contains 0 ) UINT64 8 | |
70 unsigned long type_size; //Total size of type-specific data UINT32 4 | |
71 unsigned long stream_size; //Size of stream-specific data UINT32 4 | |
72 unsigned short stream_no; //Stream number UINT16 2 | |
73 unsigned long unk2; //Unknown UINT32 4 | |
74 } ASF_stream_header_t; | |
75 | |
76 typedef struct __attribute__((packed)) { | |
77 unsigned char streamno; | |
78 unsigned char seq; | |
79 unsigned long x; | |
80 unsigned char flag; | |
81 } ASF_segmhdr_t; | |
82 | |
83 | |
84 ASF_header_t asfh; | |
85 ASF_obj_header_t objh; | |
86 ASF_file_header_t fileh; | |
87 ASF_stream_header_t streamh; | |
88 unsigned char buffer[8192]; | |
89 | |
90 int i; | |
91 | |
26575
1ca484e74f18
Mark all functions that are only used within the file as static.
diego
parents:
25308
diff
changeset
|
92 static char* chunk_type(unsigned char* guid){ |
1 | 93 switch(*((unsigned int*)guid)){ |
94 case 0xF8699E40: return "guid_audio_stream"; | |
95 case 0xBC19EFC0: return "guid_video_stream"; | |
96 case 0x49f1a440: return "guid_audio_conceal_none"; | |
97 case 0xbfc3cd50: return "guid_audio_conceal_interleave"; | |
98 case 0x75B22630: return "guid_header"; | |
99 case 0x75b22636: return "guid_data_chunk"; | |
100 case 0x33000890: return "guid_index_chunk"; | |
101 case 0xB7DC0791: return "guid_stream_header"; | |
102 case 0xD6E229D1: return "guid_header_2_0"; | |
103 case 0x8CABDCA1: return "guid_file_header"; | |
104 } | |
105 return NULL; | |
106 } | |
107 | |
26575
1ca484e74f18
Mark all functions that are only used within the file as static.
diego
parents:
25308
diff
changeset
|
108 static void print_wave_header(WAVEFORMATEX *h){ |
27636 | 109 printf("======= WAVE Format =======\n"); |
1 | 110 |
27636 | 111 printf("Format Tag: %d (0x%X)\n", h->wFormatTag, h->wFormatTag); |
112 printf("Channels: %d\n", h->nChannels); | |
113 printf("Samplerate: %ld\n", h->nSamplesPerSec); | |
114 printf("avg byte/sec: %ld\n", h->nAvgBytesPerSec); | |
115 printf("Block align: %d\n", h->nBlockAlign); | |
116 printf("bits/sample: %d\n", h->wBitsPerSample); | |
117 printf("cbSize: %d\n", h->cbSize); | |
118 | |
1 | 119 switch(h->wFormatTag){ |
27636 | 120 case 0x01: printf("Audio in PCM format\n"); break; |
121 case 0x50: printf("Audio in MPEG Layer 1/2 format\n"); break; | |
122 case 0x55: printf("Audio in MPEG Layer-3 format\n"); break; // ACM | |
123 case 0x02: printf("Audio in MS ADPCM format\n"); break; // ACM | |
124 case 0x11: printf("Audio in IMA ADPCM format\n"); break; // ACM | |
125 case 0x31: | |
126 case 0x32: printf("Audio in MS GSM 6.10 format\n"); break; // ACM | |
127 case 0x160: | |
128 case 0x161: printf("Audio in DivX WMA format\n"); break; // ACM | |
129 default: printf("Audio in UNKNOWN (id=0x%X) format\n", h->wFormatTag); | |
1 | 130 } |
131 | |
132 printf("===========================\n"); | |
133 } | |
134 | |
26575
1ca484e74f18
Mark all functions that are only used within the file as static.
diego
parents:
25308
diff
changeset
|
135 static void print_video_header(BITMAPINFOHEADER *h){ |
1 | 136 printf("======= VIDEO Format ======\n"); |
27636 | 137 printf(" biSize %ld\n", h->biSize); |
138 printf(" biWidth %ld\n", h->biWidth); | |
139 printf(" biHeight %ld\n", h->biHeight); | |
140 printf(" biPlanes %d\n", h->biPlanes); | |
141 printf(" biBitCount %d\n", h->biBitCount); | |
142 printf(" biCompression %ld='%.4s'\n", h->biCompression, &h->biCompression); | |
143 printf(" biSizeImage %ld\n", h->biSizeImage); | |
1 | 144 printf("===========================\n"); |
145 } | |
146 | |
147 FILE* streams[128]; | |
148 | |
27636 | 149 int main(int argc, char* argv[]){ |
150 FILE *f = fopen(argc > 1 ? argv[1] : "Alice Deejay - Back In My Life.asf", "rb"); | |
1 | 151 |
27636 | 152 if(!f){ |
153 printf("file not found\n"); | |
154 exit(1); | |
155 } | |
1 | 156 |
27636 | 157 //printf("sizeof=%d\n", sizeof(objh)); |
158 //printf("sizeof=%d\n", sizeof(asfh)); | |
1 | 159 |
27636 | 160 fread(&asfh, sizeof(asfh), 1, f); // header obj |
161 //for(i = 0; i < 16; i++) | |
162 // printf("%02X ", asfh.objh.guid[i]); | |
163 printf("[%s] %d (subchunks: %d)\n", chunk_type(asfh.objh.guid), | |
164 (int) asfh.objh.size, asfh.cno); | |
1 | 165 |
27636 | 166 while(fread(&objh, sizeof(objh), 1, f) > 0){ |
167 int pos = ftell(f); | |
168 //for(i = 0; i < 16; i++) | |
169 // printf("%02X ", objh.guid[i]); | |
170 printf("0x%08X [%s] %d\n", pos-sizeof(objh), chunk_type(objh.guid), | |
171 (int) objh.size); | |
172 switch(*((unsigned int*)&objh.guid)){ | |
173 case 0xB7DC0791: // guid_stream_header | |
174 fread(&streamh, sizeof(streamh), 1, f); | |
175 printf("stream type: %s\n", chunk_type(streamh.type)); | |
176 printf("stream concealment: %s\n", chunk_type(streamh.concealment)); | |
177 printf("type: %d bytes, stream: %d bytes ID: %d\n", | |
178 (int)streamh.type_size, (int)streamh.stream_size, | |
179 (int)streamh.stream_no); | |
180 printf("FILEPOS=0x%lX\n", ftell(f)); | |
181 // type-specific data: | |
182 fread(buffer,streamh.type_size,1,f); | |
183 switch(*((unsigned int*)&streamh.type)){ | |
184 case 0xF8699E40: // guid_audio_stream | |
185 print_wave_header((WAVEFORMATEX*)buffer); | |
186 break; | |
187 case 0xBC19EFC0: // guid_video_stream | |
188 print_video_header((BITMAPINFOHEADER*)&buffer[4 + 4 + 1 + 2]); | |
189 break; | |
190 } | |
191 // stream-specific data: | |
192 fread(buffer, streamh.stream_size, 1, f); | |
1 | 193 break; |
27636 | 194 //case 0xD6E229D1: |
195 // return "guid_header_2_0"; | |
196 case 0x8CABDCA1: // guid_file_header | |
197 fread(&fileh, sizeof(fileh), 1, f); | |
198 printf("packets: %d flags: %d pack_size: %d frame_size: %d\n", | |
199 (int)fileh.packets, (int)fileh.flags, (int)fileh.packetsize, | |
200 (int)fileh.frame_size); | |
1 | 201 break; |
27636 | 202 case 0x75b22636: // guid_data_chunk |
203 { int endp = pos + objh.size - sizeof(objh); | |
204 unsigned char* packet = malloc((int)fileh.packetsize); | |
205 int fpos; | |
206 fseek(f, 26, SEEK_CUR); | |
207 while((fpos = ftell(f)) < endp){ | |
208 fread(packet, (int)fileh.packetsize, 1, f); | |
209 if(packet[0] == 0x82){ | |
210 unsigned char flags = packet[3]; | |
211 unsigned char* p = &packet[5]; | |
212 unsigned long time; | |
213 unsigned short duration; | |
214 int segs = 1; | |
215 int seg; | |
216 int padding=0; | |
217 if(flags & 8){ | |
218 padding = p[0]; | |
219 ++p; | |
220 } else | |
221 if(flags & 16){ | |
222 padding = p[0] | (p[1] << 8); | |
223 p += 2; | |
224 } | |
225 time = *((unsigned long*)p); | |
226 p += 4; | |
227 duration = *((unsigned short*)p); | |
228 p += 2; | |
229 if(flags & 1){ | |
230 segs = p[0] - 0x80; | |
231 ++p; | |
232 } | |
233 printf("%08X: flag=%02X segs=%d pad=%d time=%ld dur=%d\n", | |
234 fpos, flags, segs, padding, time, duration); | |
235 for(seg = 0; seg < segs; seg++){ | |
236 ASF_segmhdr_t* sh = (ASF_segmhdr_t*)p; | |
237 int len = 0; | |
238 p += sizeof(ASF_segmhdr_t); | |
239 if(sh->flag & 8) p+=8;// else | |
240 if(sh->flag & 1) ++p; | |
241 if(flags & 1){ | |
242 len = *((unsigned short*)p); | |
243 p += 2; | |
244 } | |
245 printf(" seg #%d: streamno=%d seq=%d flag=%02X len=%d\n", | |
246 seg, sh->streamno&0x7F, sh->seq, sh->flag, len); | |
247 #ifdef SAVE_STREAMS | |
248 if(!streams[sh->streamno & 0x7F]){ | |
249 char name[256]; | |
250 snprintf(name, 256, "stream%02X.dat", sh->streamno & 0x7F); | |
251 streams[sh->streamno & 0x7F] = fopen(name, "wb"); | |
252 } | |
253 fwrite(p, len, 1, streams[sh->streamno & 0x7F]); | |
254 #endif | |
255 p += len; | |
256 } | |
1 | 257 } else |
27636 | 258 printf("%08X: UNKNOWN %02X %02X %02X %02X %02X...\n", fpos, |
259 packet[0], packet[1], packet[2], packet[3], packet[4]); | |
260 } | |
1 | 261 } |
27636 | 262 break; |
263 | |
264 //case 0x33000890: | |
265 // return "guid_index_chunk"; | |
1 | 266 |
27636 | 267 } |
268 fseek(f, pos + objh.size - sizeof(objh), SEEK_SET); | |
269 } | |
1 | 270 |
27636 | 271 return 0; |
1 | 272 } |
273 |