Mercurial > mplayer.hg
annotate TOOLS/vivodump.c @ 16429:84174804804b
Updates to NUT spec:
1. remove average_bitrate
2. add other_stream_header, for subtitles and metadata
3. add max_pts to index
4. index_ptr - a 64 bit integer to say the total length of all index packets
5. specify how to write "multiple" indexes
6. change forward_ptr behavior, starts right after forward_ptr, ends after
checksum
7. remove stream_id <-> stream_class limitation.
8. time_base_nom must also be non zero.
9. rename time_base_nom and time_base_denom, now timebase means the length
of a tick, not amounts of ticks
10. remove (old?) sample_rate_mul stuff.
11. specify what exactly the checksum covers.
12. specify that stream classes which have multiple streams must have an
info packet.. (in new Semantic requirements section)
13. Rename 'timestamp' to pts.
14. Change date of draft...
15. Add myself to authors...
author | ods15 |
---|---|
date | Fri, 09 Sep 2005 10:26:21 +0000 |
parents | 245f5d4b4af7 |
children | fa17424b4c7b |
rev | line source |
---|---|
2665 | 1 #include <stdio.h> |
2667 | 2 #include <stdlib.h> |
3 #include <string.h> | |
13783 | 4 #include <inttypes.h> |
2667 | 5 |
13783 | 6 #include "loader/wine/mmreg.h" |
7 #include "loader/wine/avifmt.h" | |
8 #include "loader/wine/vfw.h" | |
9 | |
10 #include "libmpdemux/muxer.h" | |
2667 | 11 |
13783 | 12 char *info_name; |
13 char *info_artist; | |
14 char *info_genre; | |
15 char *info_subject; | |
16 char *info_copyright; | |
17 char *info_sourceform; | |
18 char *info_comment; | |
2665 | 19 |
20 static const short h263_format[8][2] = { | |
21 { 0, 0 }, | |
22 { 128, 96 }, | |
23 { 176, 144 }, | |
24 { 352, 288 }, | |
25 { 704, 576 }, | |
26 { 1408, 1152 }, | |
2696 | 27 { 320, 240 } |
2665 | 28 }; |
29 | |
30 unsigned char* buffer; | |
31 int bufptr=0; | |
32 int bitcnt=0; | |
33 unsigned char buf=0; | |
34 | |
35 unsigned int x_get_bits(int n){ | |
36 unsigned int x=0; | |
37 while(n-->0){ | |
38 if(!bitcnt){ | |
39 // fill buff | |
40 buf=buffer[bufptr++]; | |
41 bitcnt=8; | |
42 } | |
43 //x=(x<<1)|(buf&1);buf>>=1; | |
44 x=(x<<1)|(buf>>7);buf<<=1; | |
45 --bitcnt; | |
46 } | |
47 return x; | |
48 } | |
49 | |
50 #define get_bits(xxx,n) x_get_bits(n) | |
51 #define get_bits1(xxx) x_get_bits(1) | |
52 #define skip_bits(xxx,n) x_get_bits(n) | |
53 #define skip_bits1(xxx) x_get_bits(1) | |
54 | |
2696 | 55 int format; |
56 int width=320; | |
57 int height=240; | |
2667 | 58 |
2665 | 59 /* most is hardcoded. should extend to handle all h263 streams */ |
60 int h263_decode_picture_header(unsigned char *b_ptr) | |
61 { | |
2696 | 62 int i; |
63 | |
64 for(i=0;i<16;i++) printf(" %02X",b_ptr[i]); printf("\n"); | |
2665 | 65 |
66 buffer=b_ptr; | |
67 bufptr=bitcnt=buf=0; | |
68 | |
69 /* picture header */ | |
2696 | 70 if (get_bits(&s->gb, 22) != 0x20){ |
71 printf("bad picture header\n"); | |
2665 | 72 return -1; |
2696 | 73 } |
2665 | 74 skip_bits(&s->gb, 8); /* picture timestamp */ |
75 | |
2696 | 76 if (get_bits1(&s->gb) != 1){ |
77 printf("bad marker\n"); | |
2665 | 78 return -1; /* marker */ |
2696 | 79 } |
80 if (get_bits1(&s->gb) != 0){ | |
81 printf("bad h263 id\n"); | |
2665 | 82 return -1; /* h263 id */ |
2696 | 83 } |
2665 | 84 skip_bits1(&s->gb); /* split screen off */ |
85 skip_bits1(&s->gb); /* camera off */ | |
86 skip_bits1(&s->gb); /* freeze picture release off */ | |
87 | |
88 format = get_bits(&s->gb, 3); | |
89 | |
90 if (format != 7) { | |
91 printf("h263_plus = 0 format = %d\n",format); | |
92 /* H.263v1 */ | |
93 width = h263_format[format][0]; | |
94 height = h263_format[format][1]; | |
95 printf("%d x %d\n",width,height); | |
2696 | 96 // if (!width) return -1; |
2665 | 97 |
98 printf("pict_type=%d\n",get_bits1(&s->gb)); | |
99 printf("unrestricted_mv=%d\n",get_bits1(&s->gb)); | |
100 #if 1 | |
101 printf("SAC: %d\n",get_bits1(&s->gb)); | |
102 printf("advanced prediction mode: %d\n",get_bits1(&s->gb)); | |
103 printf("PB frame: %d\n",get_bits1(&s->gb)); | |
104 #else | |
105 if (get_bits1(&s->gb) != 0) | |
106 return -1; /* SAC: off */ | |
107 if (get_bits1(&s->gb) != 0) | |
108 return -1; /* advanced prediction mode: off */ | |
109 if (get_bits1(&s->gb) != 0) | |
110 return -1; /* not PB frame */ | |
111 #endif | |
112 printf("qscale=%d\n",get_bits(&s->gb, 5)); | |
113 skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ | |
114 } else { | |
115 printf("h263_plus = 1\n"); | |
116 /* H.263v2 */ | |
2696 | 117 if (get_bits(&s->gb, 3) != 1){ |
118 printf("H.263v2 A error\n"); | |
2665 | 119 return -1; |
2696 | 120 } |
121 if (get_bits(&s->gb, 3) != 6){ /* custom source format */ | |
122 printf("custom source format\n"); | |
2665 | 123 return -1; |
2696 | 124 } |
2665 | 125 skip_bits(&s->gb, 12); |
126 skip_bits(&s->gb, 3); | |
127 printf("pict_type=%d\n",get_bits(&s->gb, 3) + 1); | |
128 // if (s->pict_type != I_TYPE && | |
129 // s->pict_type != P_TYPE) | |
130 // return -1; | |
131 skip_bits(&s->gb, 7); | |
132 skip_bits(&s->gb, 4); /* aspect ratio */ | |
133 width = (get_bits(&s->gb, 9) + 1) * 4; | |
134 skip_bits1(&s->gb); | |
135 height = get_bits(&s->gb, 9) * 4; | |
136 printf("%d x %d\n",width,height); | |
2696 | 137 //if (height == 0) |
138 // return -1; | |
2665 | 139 printf("qscale=%d\n",get_bits(&s->gb, 5)); |
140 } | |
141 | |
142 /* PEI */ | |
143 while (get_bits1(&s->gb) != 0) { | |
144 skip_bits(&s->gb, 8); | |
145 } | |
146 // s->f_code = 1; | |
147 // s->width = width; | |
148 // s->height = height; | |
149 return 0; | |
150 } | |
151 | |
2667 | 152 int postable[32768]; |
2665 | 153 |
13801
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
154 int main(int argc,char ** argv){ |
2665 | 155 int c; |
156 unsigned int head=-1; | |
157 int pos=0; | |
2667 | 158 int frames=0; |
13784
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
159 FILE *f; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
160 FILE *f2; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
161 muxer_t* avi; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
162 muxer_stream_t* mux; |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
163 //unsigned char* buffer=malloc(0x200000); |
2696 | 164 int i,len; |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
165 int v_id=0; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
166 int flag=0; |
2696 | 167 int flag2=0; |
3233 | 168 int prefix=0; |
2667 | 169 |
13801
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
170 // check if enough args were given |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
171 if ( argc < 3 ){ |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
172 printf("Too few arguments given!\n" |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
173 "Usage: %s <input_file> <output_file>\n", argv[0]); |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
174 |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
175 return -1; |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
176 } |
13784
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
177 // input |
13801
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
178 if(!(f=fopen(argv[1],"rb"))){ |
13784
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
179 printf("Couldn't open input file.\n"); |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
180 return -1; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
181 } |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
182 // output |
13801
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
183 if(!(f2=fopen(argv[2],"wb"))){ |
13784
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
184 printf("Couldn't open output file.\n"); |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
185 return -1; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
186 } |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
187 |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
188 avi=muxer_new_muxer(MUXER_TYPE_AVI,f2); |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
189 mux=muxer_new_stream(avi,MUXER_TYPE_VIDEO); |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
190 |
2667 | 191 mux->buffer_size=0x200000; |
192 mux->buffer=malloc(mux->buffer_size); | |
193 | |
194 mux->h.dwScale=1; | |
195 mux->h.dwRate=10; | |
2665 | 196 |
2667 | 197 mux->bih=malloc(sizeof(BITMAPINFOHEADER)); |
198 mux->bih->biSize=sizeof(BITMAPINFOHEADER); | |
199 mux->bih->biPlanes=1; | |
200 mux->bih->biBitCount=24; | |
201 mux->bih->biCompression=0x6f766976;// 7669766f; | |
9014
c671e9adbe22
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8585
diff
changeset
|
202 muxer_write_header(avi); |
2667 | 203 |
2696 | 204 /* |
205 c=fgetc(f); if(c) printf("error! not vivo file?\n"); | |
206 len=0; | |
207 while((c=fgetc(f))>=0x80) len+=0x80*(c&0x0F); | |
208 len+=c; | |
209 printf("hdr1: %d\n",len); | |
210 for(i=0;i<len;i++) fgetc(f); | |
211 */ | |
212 | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
213 while((c=fgetc(f))>=0){ |
2696 | 214 |
3233 | 215 printf("%08X %02X\n",ftell(f),c); |
216 | |
217 prefix=0; | |
218 if(c==0x82){ | |
219 prefix=1; | |
220 //continue; | |
221 c=fgetc(f); | |
222 printf("%08X %02X\n",ftell(f),c); | |
223 } | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
224 |
2696 | 225 if(c==0x00){ |
226 // header | |
227 int len=0; | |
228 while((c=fgetc(f))>=0x80) len+=0x80*(c&0x0F); | |
229 len+=c; | |
230 printf("header: 00 (%d)\n",len); | |
231 for(i=0;i<len;i++) fgetc(f); | |
232 continue; | |
233 } | |
234 | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
235 if((c&0xF0)==0x40){ |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
236 // audio |
3233 | 237 len=24; |
238 if(prefix) len=fgetc(f); | |
239 printf("audio: %02X (%d)\n",c,len); | |
240 for(i=0;i<len;i++) fgetc(f); | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
241 continue; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
242 } |
2696 | 243 if((c&0xF0)==0x30){ |
244 // audio | |
3233 | 245 len=40; |
246 if(prefix) len=fgetc(f); | |
247 printf("audio: %02X (%d)\n",c,len); | |
248 for(i=0;i<len;i++) fgetc(f); | |
2696 | 249 continue; |
250 } | |
251 if(flag2 || (((c&0xF0)==0x10 || (c&0xF0)==0x20) && (c&0x0F)!=(v_id&0xF))){ | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
252 // end of frame: |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
253 printf("Frame size: %d\n",mux->buffer_len); |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
254 h263_decode_picture_header(mux->buffer); |
9014
c671e9adbe22
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8585
diff
changeset
|
255 muxer_write_chunk(mux,mux->buffer_len,0x10); |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
256 mux->buffer_len=0; |
2696 | 257 |
258 if((v_id&0xF0)==0x10) fprintf(stderr,"hmm. last video packet %02X\n",v_id); | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
259 } |
2696 | 260 flag2=0; |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
261 if((c&0xF0)==0x10){ |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
262 // 128 byte |
3233 | 263 len=128; |
264 if(prefix) len=fgetc(f); | |
265 printf("video: %02X (%d)\n",c,len); | |
266 fread(mux->buffer+mux->buffer_len,len,1,f); | |
267 mux->buffer_len+=len; | |
268 v_id=c; | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
269 continue; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
270 } |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
271 if((c&0xF0)==0x20){ |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
272 int len=fgetc(f); |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
273 printf("video: %02X (%d)\n",c,len); |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
274 fread(mux->buffer+mux->buffer_len,len,1,f); |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
275 mux->buffer_len+=len; |
2696 | 276 flag2=1; |
3233 | 277 v_id=c; |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
278 continue; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
279 } |
2696 | 280 printf("error: %02X!\n",c); |
3233 | 281 exit(1); |
2665 | 282 } |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
283 |
2696 | 284 if(!width) width=320; |
285 if(!height) height=240; | |
286 | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
287 mux->bih->biWidth=width; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
288 mux->bih->biHeight=height; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
289 mux->bih->biSizeImage=3*width*height; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
290 |
9014
c671e9adbe22
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8585
diff
changeset
|
291 muxer_write_index(avi); |
2667 | 292 fseek(f2,0,SEEK_SET); |
9014
c671e9adbe22
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8585
diff
changeset
|
293 muxer_write_header(avi); |
2667 | 294 |
295 } |