Mercurial > mplayer.hg
annotate TOOLS/vivodump.c @ 26234:f0788169e503
Ignore if we fail to get disc key, fixes playback of one of my DVDs which
claims to be scrambled but actually is not, and always allows to
fallback to cached keys.
author | reimar |
---|---|
date | Fri, 21 Mar 2008 12:31:47 +0000 |
parents | 8e73e469970c |
children | 1ca484e74f18 |
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 | |
22627 | 10 #include "stream/stream.h" |
13783 | 11 #include "libmpdemux/muxer.h" |
22627 | 12 #include "libmpdemux/demuxer.h" |
2667 | 13 |
13783 | 14 char *info_name; |
15 char *info_artist; | |
16 char *info_genre; | |
17 char *info_subject; | |
18 char *info_copyright; | |
19 char *info_sourceform; | |
20 char *info_comment; | |
2665 | 21 |
22 static const short h263_format[8][2] = { | |
23 { 0, 0 }, | |
24 { 128, 96 }, | |
25 { 176, 144 }, | |
26 { 352, 288 }, | |
27 { 704, 576 }, | |
28 { 1408, 1152 }, | |
2696 | 29 { 320, 240 } |
2665 | 30 }; |
31 | |
32 unsigned char* buffer; | |
33 int bufptr=0; | |
34 int bitcnt=0; | |
35 unsigned char buf=0; | |
36 | |
37 unsigned int x_get_bits(int n){ | |
38 unsigned int x=0; | |
39 while(n-->0){ | |
40 if(!bitcnt){ | |
41 // fill buff | |
42 buf=buffer[bufptr++]; | |
43 bitcnt=8; | |
44 } | |
45 //x=(x<<1)|(buf&1);buf>>=1; | |
46 x=(x<<1)|(buf>>7);buf<<=1; | |
47 --bitcnt; | |
48 } | |
49 return x; | |
50 } | |
51 | |
52 #define get_bits(xxx,n) x_get_bits(n) | |
53 #define get_bits1(xxx) x_get_bits(1) | |
54 #define skip_bits(xxx,n) x_get_bits(n) | |
55 #define skip_bits1(xxx) x_get_bits(1) | |
56 | |
2696 | 57 int format; |
58 int width=320; | |
59 int height=240; | |
2667 | 60 |
2665 | 61 /* most is hardcoded. should extend to handle all h263 streams */ |
62 int h263_decode_picture_header(unsigned char *b_ptr) | |
63 { | |
2696 | 64 int i; |
65 | |
66 for(i=0;i<16;i++) printf(" %02X",b_ptr[i]); printf("\n"); | |
2665 | 67 |
68 buffer=b_ptr; | |
69 bufptr=bitcnt=buf=0; | |
70 | |
71 /* picture header */ | |
2696 | 72 if (get_bits(&s->gb, 22) != 0x20){ |
73 printf("bad picture header\n"); | |
2665 | 74 return -1; |
2696 | 75 } |
2665 | 76 skip_bits(&s->gb, 8); /* picture timestamp */ |
77 | |
2696 | 78 if (get_bits1(&s->gb) != 1){ |
79 printf("bad marker\n"); | |
2665 | 80 return -1; /* marker */ |
2696 | 81 } |
82 if (get_bits1(&s->gb) != 0){ | |
83 printf("bad h263 id\n"); | |
2665 | 84 return -1; /* h263 id */ |
2696 | 85 } |
2665 | 86 skip_bits1(&s->gb); /* split screen off */ |
87 skip_bits1(&s->gb); /* camera off */ | |
88 skip_bits1(&s->gb); /* freeze picture release off */ | |
89 | |
90 format = get_bits(&s->gb, 3); | |
91 | |
92 if (format != 7) { | |
93 printf("h263_plus = 0 format = %d\n",format); | |
94 /* H.263v1 */ | |
95 width = h263_format[format][0]; | |
96 height = h263_format[format][1]; | |
97 printf("%d x %d\n",width,height); | |
2696 | 98 // if (!width) return -1; |
2665 | 99 |
100 printf("pict_type=%d\n",get_bits1(&s->gb)); | |
101 printf("unrestricted_mv=%d\n",get_bits1(&s->gb)); | |
102 #if 1 | |
103 printf("SAC: %d\n",get_bits1(&s->gb)); | |
104 printf("advanced prediction mode: %d\n",get_bits1(&s->gb)); | |
105 printf("PB frame: %d\n",get_bits1(&s->gb)); | |
106 #else | |
107 if (get_bits1(&s->gb) != 0) | |
108 return -1; /* SAC: off */ | |
109 if (get_bits1(&s->gb) != 0) | |
110 return -1; /* advanced prediction mode: off */ | |
111 if (get_bits1(&s->gb) != 0) | |
112 return -1; /* not PB frame */ | |
113 #endif | |
114 printf("qscale=%d\n",get_bits(&s->gb, 5)); | |
115 skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ | |
116 } else { | |
117 printf("h263_plus = 1\n"); | |
118 /* H.263v2 */ | |
2696 | 119 if (get_bits(&s->gb, 3) != 1){ |
120 printf("H.263v2 A error\n"); | |
2665 | 121 return -1; |
2696 | 122 } |
123 if (get_bits(&s->gb, 3) != 6){ /* custom source format */ | |
124 printf("custom source format\n"); | |
2665 | 125 return -1; |
2696 | 126 } |
2665 | 127 skip_bits(&s->gb, 12); |
128 skip_bits(&s->gb, 3); | |
129 printf("pict_type=%d\n",get_bits(&s->gb, 3) + 1); | |
130 // if (s->pict_type != I_TYPE && | |
131 // s->pict_type != P_TYPE) | |
132 // return -1; | |
133 skip_bits(&s->gb, 7); | |
134 skip_bits(&s->gb, 4); /* aspect ratio */ | |
135 width = (get_bits(&s->gb, 9) + 1) * 4; | |
136 skip_bits1(&s->gb); | |
137 height = get_bits(&s->gb, 9) * 4; | |
138 printf("%d x %d\n",width,height); | |
2696 | 139 //if (height == 0) |
140 // return -1; | |
2665 | 141 printf("qscale=%d\n",get_bits(&s->gb, 5)); |
142 } | |
143 | |
144 /* PEI */ | |
145 while (get_bits1(&s->gb) != 0) { | |
146 skip_bits(&s->gb, 8); | |
147 } | |
148 // s->f_code = 1; | |
149 // s->width = width; | |
150 // s->height = height; | |
151 return 0; | |
152 } | |
153 | |
2667 | 154 int postable[32768]; |
2665 | 155 |
13801
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
156 int main(int argc,char ** argv){ |
2665 | 157 int c; |
13784
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
158 FILE *f; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
159 FILE *f2; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
160 muxer_t* avi; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
161 muxer_stream_t* mux; |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
162 //unsigned char* buffer=malloc(0x200000); |
2696 | 163 int i,len; |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
164 int v_id=0; |
2696 | 165 int flag2=0; |
3233 | 166 int prefix=0; |
2667 | 167 |
13801
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
168 // check if enough args were given |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
169 if ( argc < 3 ){ |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
170 printf("Too few arguments given!\n" |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
171 "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
|
172 |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
173 return -1; |
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
174 } |
13784
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
175 // input |
13801
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
176 if(!(f=fopen(argv[1],"rb"))){ |
13784
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
177 printf("Couldn't open input file.\n"); |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
178 return -1; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
179 } |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
180 // output |
13801
245f5d4b4af7
Fixed the assumption user will always give 2+ args to the program.
al
parents:
13784
diff
changeset
|
181 if(!(f2=fopen(argv[2],"wb"))){ |
13784
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
182 printf("Couldn't open output file.\n"); |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
183 return -1; |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
184 } |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
185 |
7d3b84ddd2fd
Remove hardcoded filenames in favor of command line parameters, some error
diego
parents:
13783
diff
changeset
|
186 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
|
187 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
|
188 |
2667 | 189 mux->buffer_size=0x200000; |
190 mux->buffer=malloc(mux->buffer_size); | |
191 | |
192 mux->h.dwScale=1; | |
193 mux->h.dwRate=10; | |
2665 | 194 |
2667 | 195 mux->bih=malloc(sizeof(BITMAPINFOHEADER)); |
196 mux->bih->biSize=sizeof(BITMAPINFOHEADER); | |
197 mux->bih->biPlanes=1; | |
198 mux->bih->biBitCount=24; | |
199 mux->bih->biCompression=0x6f766976;// 7669766f; | |
9014
c671e9adbe22
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8585
diff
changeset
|
200 muxer_write_header(avi); |
2667 | 201 |
2696 | 202 /* |
203 c=fgetc(f); if(c) printf("error! not vivo file?\n"); | |
204 len=0; | |
205 while((c=fgetc(f))>=0x80) len+=0x80*(c&0x0F); | |
206 len+=c; | |
207 printf("hdr1: %d\n",len); | |
208 for(i=0;i<len;i++) fgetc(f); | |
209 */ | |
210 | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
211 while((c=fgetc(f))>=0){ |
2696 | 212 |
25309
8e73e469970c
Fix printf format string length modifiers, removes the warnings:
diego
parents:
24203
diff
changeset
|
213 printf("%08lX %02X\n",ftell(f),c); |
3233 | 214 |
215 prefix=0; | |
216 if(c==0x82){ | |
217 prefix=1; | |
218 //continue; | |
219 c=fgetc(f); | |
25309
8e73e469970c
Fix printf format string length modifiers, removes the warnings:
diego
parents:
24203
diff
changeset
|
220 printf("%08lX %02X\n",ftell(f),c); |
3233 | 221 } |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
222 |
2696 | 223 if(c==0x00){ |
224 // header | |
225 int len=0; | |
226 while((c=fgetc(f))>=0x80) len+=0x80*(c&0x0F); | |
227 len+=c; | |
228 printf("header: 00 (%d)\n",len); | |
229 for(i=0;i<len;i++) fgetc(f); | |
230 continue; | |
231 } | |
232 | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
233 if((c&0xF0)==0x40){ |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
234 // audio |
3233 | 235 len=24; |
236 if(prefix) len=fgetc(f); | |
237 printf("audio: %02X (%d)\n",c,len); | |
238 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
|
239 continue; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
240 } |
2696 | 241 if((c&0xF0)==0x30){ |
242 // audio | |
3233 | 243 len=40; |
244 if(prefix) len=fgetc(f); | |
245 printf("audio: %02X (%d)\n",c,len); | |
246 for(i=0;i<len;i++) fgetc(f); | |
2696 | 247 continue; |
248 } | |
249 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
|
250 // end of frame: |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
251 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
|
252 h263_decode_picture_header(mux->buffer); |
17487
fa17424b4c7b
change muxer_write_chunk() so that pts/dts _could_ be passed from encoder to muxer
michael
parents:
13801
diff
changeset
|
253 muxer_write_chunk(mux,mux->buffer_len,0x10, MP_NOPTS_VALUE, MP_NOPTS_VALUE); |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
254 mux->buffer_len=0; |
2696 | 255 |
256 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
|
257 } |
2696 | 258 flag2=0; |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
259 if((c&0xF0)==0x10){ |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
260 // 128 byte |
3233 | 261 len=128; |
262 if(prefix) len=fgetc(f); | |
263 printf("video: %02X (%d)\n",c,len); | |
264 fread(mux->buffer+mux->buffer_len,len,1,f); | |
265 mux->buffer_len+=len; | |
266 v_id=c; | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
267 continue; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
268 } |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
269 if((c&0xF0)==0x20){ |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
270 int len=fgetc(f); |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
271 printf("video: %02X (%d)\n",c,len); |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
272 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
|
273 mux->buffer_len+=len; |
2696 | 274 flag2=1; |
3233 | 275 v_id=c; |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
276 continue; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
277 } |
2696 | 278 printf("error: %02X!\n",c); |
3233 | 279 exit(1); |
2665 | 280 } |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
281 |
2696 | 282 if(!width) width=320; |
283 if(!height) height=240; | |
284 | |
2672
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
285 mux->bih->biWidth=width; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
286 mux->bih->biHeight=height; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
287 mux->bih->biSizeImage=3*width*height; |
1ff47e4ff44d
works! copy video steram to .avi file playable with ivvideo.dll
arpi
parents:
2667
diff
changeset
|
288 |
9014
c671e9adbe22
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8585
diff
changeset
|
289 muxer_write_index(avi); |
2667 | 290 fseek(f2,0,SEEK_SET); |
9014
c671e9adbe22
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8585
diff
changeset
|
291 muxer_write_header(avi); |
2667 | 292 |
24203 | 293 return 0; |
2667 | 294 } |