7029
|
1 /*
|
|
2 * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn@dtek.chalmers.se>,
|
|
3 * Håkan Hjort <d95hjort@dtek.chalmers.se>
|
|
4 *
|
|
5 * This program is free software; you can redistribute it and/or modify
|
|
6 * it under the terms of the GNU General Public License as published by
|
|
7 * the Free Software Foundation; either version 2 of the License, or
|
|
8 * (at your option) any later version.
|
|
9 *
|
|
10 * This program is distributed in the hope that it will be useful,
|
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 * GNU General Public License for more details.
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License
|
|
16 * along with this program; if not, write to the Free Software
|
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18 */
|
|
19
|
|
20 #include <stdio.h>
|
|
21 #include <stdlib.h>
|
|
22 #include <unistd.h>
|
|
23 #include <inttypes.h>
|
|
24 #include <string.h>
|
|
25 #include <ctype.h>
|
7033
|
26 //#include <assert.h>
|
7029
|
27
|
|
28 #include "config.h" // Needed for WORDS_BIGENDIAN
|
|
29 #include "ifo_types.h"
|
|
30 #include "ifo_read.h"
|
|
31 #include "ifo_print.h"
|
|
32
|
|
33 /* Put this in some other file / package? It's used in nav_print too. */
|
|
34 static void ifoPrint_time(int level, dvd_time_t *dtime) {
|
|
35 const char *rate;
|
|
36 assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
|
|
37 assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
|
|
38 assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
|
|
39 assert((dtime->frame_u&0xf) < 0xa);
|
|
40
|
|
41 printf("%02x:%02x:%02x.%02x",
|
|
42 dtime->hour,
|
|
43 dtime->minute,
|
|
44 dtime->second,
|
|
45 dtime->frame_u & 0x3f);
|
|
46 switch((dtime->frame_u & 0xc0) >> 6) {
|
|
47 case 1:
|
|
48 rate = "25.00";
|
|
49 break;
|
|
50 case 3:
|
|
51 rate = "29.97";
|
|
52 break;
|
|
53 default:
|
|
54 if(dtime->hour == 0 && dtime->minute == 0
|
|
55 && dtime->second == 0 && dtime->frame_u == 0)
|
|
56 rate = "no";
|
|
57 else
|
|
58 rate = "(please send a bug report)";
|
|
59 break;
|
|
60 }
|
|
61 printf(" @ %s fps", rate);
|
|
62 }
|
|
63
|
|
64 /* Put this in some other file / package? It's used in nav_print too.
|
|
65 Possibly also by the vm / navigator. */
|
|
66 static void ifoPrint_CMD(int row, vm_cmd_t *command) {
|
|
67 int i;
|
|
68
|
|
69 printf("(%03d) ", row + 1);
|
|
70 for(i=0;i<8;i++)
|
|
71 printf("%02x ", command->bytes[i]);
|
|
72 printf("| ");
|
|
73
|
|
74 //vmcmd(command);
|
|
75 printf("\n");
|
|
76 }
|
|
77
|
|
78 static void ifoPrint_video_attributes(int level, video_attr_t *attr) {
|
|
79
|
|
80 /* The following test is shorter but not correct ISO C,
|
|
81 memcmp(attr,my_friendly_zeros, sizeof(video_attr_t)) */
|
|
82 if(attr->mpeg_version == 0
|
|
83 && attr->video_format == 0
|
|
84 && attr->display_aspect_ratio == 0
|
|
85 && attr->permitted_df == 0
|
|
86 && attr->unknown1 == 0
|
|
87 && attr->line21_cc_1 == 0
|
|
88 && attr->line21_cc_2 == 0
|
|
89 && attr->video_format == 0
|
|
90 && attr->letterboxed == 0
|
|
91 && attr->film_mode == 0) {
|
|
92 printf("-- Unspecified --");
|
|
93 return;
|
|
94 }
|
|
95
|
|
96 switch(attr->mpeg_version) {
|
|
97 case 0:
|
|
98 printf("mpeg1 ");
|
|
99 break;
|
|
100 case 1:
|
|
101 printf("mpeg2 ");
|
|
102 break;
|
|
103 default:
|
|
104 printf("(please send a bug report) ");
|
|
105 }
|
|
106
|
|
107 switch(attr->video_format) {
|
|
108 case 0:
|
|
109 printf("ntsc ");
|
|
110 break;
|
|
111 case 1:
|
|
112 printf("pal ");
|
|
113 break;
|
|
114 default:
|
|
115 printf("(please send a bug report) ");
|
|
116 }
|
|
117
|
|
118 switch(attr->display_aspect_ratio) {
|
|
119 case 0:
|
|
120 printf("4:3 ");
|
|
121 break;
|
|
122 case 3:
|
|
123 printf("16:9 ");
|
|
124 break;
|
|
125 default:
|
|
126 printf("(please send a bug report) ");
|
|
127 }
|
|
128
|
|
129 // Wide is allways allowed..!!!
|
|
130 switch(attr->permitted_df) {
|
|
131 case 0:
|
|
132 printf("pan&scan+letterboxed ");
|
|
133 break;
|
|
134 case 1:
|
|
135 printf("only pan&scan "); //??
|
|
136 break;
|
|
137 case 2:
|
|
138 printf("only letterboxed ");
|
|
139 break;
|
|
140 case 3:
|
|
141 // not specified
|
|
142 break;
|
|
143 default:
|
|
144 printf("(please send a bug report)");
|
|
145 }
|
|
146
|
|
147 printf("U%x ", attr->unknown1);
|
|
148 assert(!attr->unknown1);
|
|
149
|
|
150 if(attr->line21_cc_1 || attr->line21_cc_2) {
|
|
151 printf("NTSC CC ");
|
|
152 if(attr->line21_cc_1)
|
|
153 printf("1 ");
|
|
154 if(attr->line21_cc_2)
|
|
155 printf("2 ");
|
|
156 }
|
|
157
|
|
158 {
|
|
159 int height = 480;
|
|
160 if(attr->video_format != 0)
|
|
161 height = 576;
|
|
162 switch(attr->picture_size) {
|
|
163 case 0:
|
|
164 printf("720x%d ", height);
|
|
165 break;
|
|
166 case 1:
|
|
167 printf("704x%d ", height);
|
|
168 break;
|
|
169 case 2:
|
|
170 printf("352x%d ", height);
|
|
171 break;
|
|
172 case 3:
|
|
173 printf("352x%d ", height/2);
|
|
174 break;
|
|
175 default:
|
|
176 printf("(please send a bug report) ");
|
|
177 }
|
|
178 }
|
|
179
|
|
180 if(attr->letterboxed) {
|
|
181 printf("source letterboxed ");
|
|
182 }
|
|
183
|
|
184 if(attr->film_mode) {
|
|
185 printf("film");
|
|
186 } else {
|
|
187 printf("video"); //camera
|
|
188 }
|
|
189 }
|
|
190
|
|
191 static void ifoPrint_audio_attributes(int level, audio_attr_t *attr) {
|
|
192
|
|
193 if(attr->audio_format == 0
|
|
194 && attr->multichannel_extension == 0
|
|
195 && attr->lang_type == 0
|
|
196 && attr->application_mode == 0
|
|
197 && attr->quantization == 0
|
|
198 && attr->sample_frequency == 0
|
|
199 && attr->channels == 0
|
|
200 && attr->lang_extension == 0
|
|
201 && attr->unknown1 == 0
|
|
202 && attr->unknown1 == 0) {
|
|
203 printf("-- Unspecified --");
|
|
204 return;
|
|
205 }
|
|
206
|
|
207 switch(attr->audio_format) {
|
|
208 case 0:
|
|
209 printf("ac3 ");
|
|
210 break;
|
|
211 case 1:
|
|
212 printf("(please send a bug report) ");
|
|
213 break;
|
|
214 case 2:
|
|
215 printf("mpeg1 ");
|
|
216 break;
|
|
217 case 3:
|
|
218 printf("mpeg2ext ");
|
|
219 break;
|
|
220 case 4:
|
|
221 printf("lpcm ");
|
|
222 break;
|
|
223 case 5:
|
|
224 printf("(please send a bug report) ");
|
|
225 break;
|
|
226 case 6:
|
|
227 printf("dts ");
|
|
228 break;
|
|
229 default:
|
|
230 printf("(please send a bug report) ");
|
|
231 }
|
|
232
|
|
233 if(attr->multichannel_extension)
|
|
234 printf("multichannel_extension ");
|
|
235
|
|
236 switch(attr->lang_type) {
|
|
237 case 0:
|
|
238 // not specified
|
|
239 assert(attr->lang_code == 0 || attr->lang_code == 0xffff);
|
|
240 break;
|
|
241 case 1:
|
|
242 printf("%c%c ", attr->lang_code>>8, attr->lang_code & 0xff);
|
|
243 break;
|
|
244 default:
|
|
245 printf("(please send a bug report) ");
|
|
246 }
|
|
247
|
|
248 switch(attr->application_mode) {
|
|
249 case 0:
|
|
250 // not specified
|
|
251 break;
|
|
252 case 1:
|
|
253 printf("karaoke mode ");
|
|
254 break;
|
|
255 case 2:
|
|
256 printf("surround sound mode ");
|
|
257 break;
|
|
258 default:
|
|
259 printf("(please send a bug report) ");
|
|
260 }
|
|
261
|
|
262 switch(attr->quantization) {
|
|
263 case 0:
|
|
264 printf("16bit ");
|
|
265 break;
|
|
266 case 1:
|
|
267 printf("20bit ");
|
|
268 break;
|
|
269 case 2:
|
|
270 printf("24bit ");
|
|
271 break;
|
|
272 case 3:
|
|
273 printf("drc ");
|
|
274 break;
|
|
275 default:
|
|
276 printf("(please send a bug report) ");
|
|
277 }
|
|
278
|
|
279 switch(attr->sample_frequency) {
|
|
280 case 0:
|
|
281 printf("48kHz ");
|
|
282 break;
|
|
283 case 1:
|
|
284 printf("??kHz ");
|
|
285 break;
|
|
286 default:
|
|
287 printf("sample_frequency %i (please send a bug report) ",
|
|
288 attr->sample_frequency);
|
|
289 }
|
|
290
|
|
291 printf("%dCh ", attr->channels + 1);
|
|
292
|
|
293 switch(attr->lang_extension) {
|
|
294 case 0:
|
|
295 printf("Not specified ");
|
|
296 break;
|
|
297 case 1: // Normal audio
|
|
298 printf("Normal Caption ");
|
|
299 break;
|
|
300 case 2: // visually imparied
|
|
301 printf("Audio for visually impaired ");
|
|
302 break;
|
|
303 case 3: // Directors 1
|
|
304 printf("Director's comments 1 ");
|
|
305 break;
|
|
306 case 4: // Directors 2
|
|
307 printf("Director's comments 2 ");
|
|
308 break;
|
|
309 //case 4: // Music score ?
|
|
310 default:
|
|
311 printf("(please send a bug report) ");
|
|
312 }
|
|
313
|
|
314 printf("%d ", attr->unknown1);
|
|
315 printf("%d ", attr->unknown2);
|
|
316 }
|
|
317
|
|
318 static void ifoPrint_subp_attributes(int level, subp_attr_t *attr) {
|
|
319
|
|
320 if(attr->type == 0
|
|
321 && attr->lang_code == 0
|
|
322 && attr->zero1 == 0
|
|
323 && attr->zero2 == 0
|
|
324 && attr->lang_extension== 0) {
|
|
325 printf("-- Unspecified --");
|
|
326 return;
|
|
327 }
|
|
328
|
|
329 printf("type %02x ", attr->type);
|
|
330
|
|
331 if(isalpha((int)(attr->lang_code >> 8))
|
|
332 && isalpha((int)(attr->lang_code & 0xff))) {
|
|
333 printf("%c%c ", attr->lang_code >> 8, attr->lang_code & 0xff);
|
|
334 } else {
|
|
335 printf("%02x%02x ", 0xff & (unsigned)(attr->lang_code >> 8),
|
|
336 0xff & (unsigned)(attr->lang_code & 0xff));
|
|
337 }
|
|
338
|
|
339 printf("%d ", attr->zero1);
|
|
340 printf("%d ", attr->zero2);
|
|
341
|
|
342 switch(attr->lang_extension) {
|
|
343 case 0:
|
|
344 printf("Not specified ");
|
|
345 break;
|
|
346 case 1:
|
|
347 printf("Caption with normal size character ");
|
|
348 break;
|
|
349 case 2:
|
|
350 printf("Caption with bigger size character ");
|
|
351 break;
|
|
352 case 3:
|
|
353 printf("Caption for children ");
|
|
354 break;
|
|
355 case 4:
|
|
356 printf("reserved ");
|
|
357 break;
|
|
358 case 5:
|
|
359 printf("Closed Caption with normal size character ");
|
|
360 break;
|
|
361 case 6:
|
|
362 printf("Closed Caption with bigger size character ");
|
|
363 break;
|
|
364 case 7:
|
|
365 printf("Closed Caption for children ");
|
|
366 break;
|
|
367 case 8:
|
|
368 printf("reserved ");
|
|
369 break;
|
|
370 case 9:
|
|
371 printf("Forced Caption");
|
|
372 break;
|
|
373 case 10:
|
|
374 printf("reserved ");
|
|
375 break;
|
|
376 case 11:
|
|
377 printf("reserved ");
|
|
378 break;
|
|
379 case 12:
|
|
380 printf("reserved ");
|
|
381 break;
|
|
382 case 13:
|
|
383 printf("Director's comments with normal size character ");
|
|
384 break;
|
|
385 case 14:
|
|
386 printf("Director's comments with bigger size character ");
|
|
387 break;
|
|
388 case 15:
|
|
389 printf("Director's comments for children ");
|
|
390 break;
|
|
391 default:
|
|
392 printf("(please send a bug report) ");
|
|
393 }
|
|
394
|
|
395 }
|
|
396
|
|
397
|
|
398 static void ifoPrint_USER_OPS(user_ops_t *user_ops) {
|
|
399 uint32_t uops;
|
|
400 unsigned char *ptr = (unsigned char *)user_ops;
|
|
401
|
|
402 uops = (*ptr++ << 24);
|
|
403 uops |= (*ptr++ << 16);
|
|
404 uops |= (*ptr++ << 8);
|
|
405 uops |= (*ptr++);
|
|
406
|
|
407 if(uops == 0) {
|
|
408 printf("None\n");
|
|
409 } else if(uops == 0x01ffffff) {
|
|
410 printf("All\n");
|
|
411 } else {
|
|
412 if(user_ops->title_or_time_play)
|
|
413 printf("Title or Time Play, ");
|
|
414 if(user_ops->chapter_search_or_play)
|
|
415 printf("Chapter Search or Play, ");
|
|
416 if(user_ops->title_play)
|
|
417 printf("Title Play, ");
|
|
418 if(user_ops->stop)
|
|
419 printf("Stop, ");
|
|
420 if(user_ops->go_up)
|
|
421 printf("Go Up, ");
|
|
422 if(user_ops->time_or_chapter_search)
|
|
423 printf("Time or Chapter Search, ");
|
|
424 if(user_ops->prev_or_top_pg_search)
|
|
425 printf("Prev or Top PG Search, ");
|
|
426 if(user_ops->next_pg_search)
|
|
427 printf("Next PG Search, ");
|
|
428 if(user_ops->forward_scan)
|
|
429 printf("Forward Scan, ");
|
|
430 if(user_ops->backward_scan)
|
|
431 printf("Backward Scan, ");
|
|
432 if(user_ops->title_menu_call)
|
|
433 printf("Title Menu Call, ");
|
|
434 if(user_ops->root_menu_call)
|
|
435 printf("Root Menu Call, ");
|
|
436 if(user_ops->subpic_menu_call)
|
|
437 printf("SubPic Menu Call, ");
|
|
438 if(user_ops->audio_menu_call)
|
|
439 printf("Audio Menu Call, ");
|
|
440 if(user_ops->angle_menu_call)
|
|
441 printf("Angle Menu Call, ");
|
|
442 if(user_ops->chapter_menu_call)
|
|
443 printf("Chapter Menu Call, ");
|
|
444 if(user_ops->resume)
|
|
445 printf("Resume, ");
|
|
446 if(user_ops->button_select_or_activate)
|
|
447 printf("Button Select or Activate, ");
|
|
448 if(user_ops->still_off)
|
|
449 printf("Still Off, ");
|
|
450 if(user_ops->pause_on)
|
|
451 printf("Pause On, ");
|
|
452 if(user_ops->audio_stream_change)
|
|
453 printf("Audio Stream Change, ");
|
|
454 if(user_ops->subpic_stream_change)
|
|
455 printf("SubPic Stream Change, ");
|
|
456 if(user_ops->angle_change)
|
|
457 printf("Angle Change, ");
|
|
458 if(user_ops->karaoke_audio_pres_mode_change)
|
|
459 printf("Karaoke Audio Pres Mode Change, ");
|
|
460 if(user_ops->video_pres_mode_change)
|
|
461 printf("Video Pres Mode Change, ");
|
|
462 printf("\n");
|
|
463 }
|
|
464 }
|
|
465
|
|
466
|
|
467 void ifoPrint_VMGI_MAT(vmgi_mat_t *vmgi_mat) {
|
|
468
|
|
469 printf("VMG Identifier: %.12s\n", vmgi_mat->vmg_identifier);
|
|
470 printf("Last Sector of VMG: %08x\n", vmgi_mat->vmg_last_sector);
|
|
471 printf("Last Sector of VMGI: %08x\n", vmgi_mat->vmgi_last_sector);
|
|
472 printf("Specification version number: %01x.%01x\n",
|
|
473 vmgi_mat->specification_version >> 4,
|
|
474 vmgi_mat->specification_version & 0xf);
|
|
475 /* Byte 2 of 'VMG Category' (00xx0000) is the Region Code */
|
|
476 printf("VMG Category: %08x\n", vmgi_mat->vmg_category);
|
|
477 printf("VMG Number of Volumes: %i\n", vmgi_mat->vmg_nr_of_volumes);
|
|
478 printf("VMG This Volume: %i\n", vmgi_mat->vmg_this_volume_nr);
|
|
479 printf("Disc side %i\n", vmgi_mat->disc_side);
|
|
480 printf("VMG Number of Title Sets %i\n", vmgi_mat->vmg_nr_of_title_sets);
|
|
481 printf("Provider ID: %.32s\n", vmgi_mat->provider_identifier);
|
|
482 printf("VMG POS Code: %08x", (uint32_t)(vmgi_mat->vmg_pos_code >> 32));
|
|
483 printf("%08x\n", (uint32_t)vmgi_mat->vmg_pos_code);
|
|
484 printf("End byte of VMGI_MAT: %08x\n", vmgi_mat->vmgi_last_byte);
|
|
485 printf("Start byte of First Play PGC FP PGC: %08x\n",
|
|
486 vmgi_mat->first_play_pgc);
|
|
487 printf("Start sector of VMGM_VOBS: %08x\n", vmgi_mat->vmgm_vobs);
|
|
488 printf("Start sector of TT_SRPT: %08x\n", vmgi_mat->tt_srpt);
|
|
489 printf("Start sector of VMGM_PGCI_UT: %08x\n", vmgi_mat->vmgm_pgci_ut);
|
|
490 printf("Start sector of PTL_MAIT: %08x\n", vmgi_mat->ptl_mait);
|
|
491 printf("Start sector of VTS_ATRT: %08x\n", vmgi_mat->vts_atrt);
|
|
492 printf("Start sector of TXTDT_MG: %08x\n", vmgi_mat->txtdt_mgi);
|
|
493 printf("Start sector of VMGM_C_ADT: %08x\n", vmgi_mat->vmgm_c_adt);
|
|
494 printf("Start sector of VMGM_VOBU_ADMAP: %08x\n",
|
|
495 vmgi_mat->vmgm_vobu_admap);
|
|
496 printf("Video attributes of VMGM_VOBS: ");
|
|
497 ifoPrint_video_attributes(5, &vmgi_mat->vmgm_video_attr);
|
|
498 printf("\n");
|
|
499 printf("VMGM Number of Audio attributes: %i\n",
|
|
500 vmgi_mat->nr_of_vmgm_audio_streams);
|
|
501 if(vmgi_mat->nr_of_vmgm_audio_streams > 0) {
|
|
502 printf("\tstream %i status: ", 1);
|
|
503 ifoPrint_audio_attributes(5, &vmgi_mat->vmgm_audio_attr);
|
|
504 printf("\n");
|
|
505 }
|
|
506 printf("VMGM Number of Sub-picture attributes: %i\n",
|
|
507 vmgi_mat->nr_of_vmgm_subp_streams);
|
|
508 if(vmgi_mat->nr_of_vmgm_subp_streams > 0) {
|
|
509 printf("\tstream %2i status: ", 1);
|
|
510 ifoPrint_subp_attributes(5, &vmgi_mat->vmgm_subp_attr);
|
|
511 printf("\n");
|
|
512 }
|
|
513 }
|
|
514
|
|
515
|
|
516 void ifoPrint_VTSI_MAT(vtsi_mat_t *vtsi_mat) {
|
|
517 int i;
|
|
518
|
|
519 printf("VTS Identifier: %.12s\n", vtsi_mat->vts_identifier);
|
|
520 printf("Last Sector of VTS: %08x\n", vtsi_mat->vts_last_sector);
|
|
521 printf("Last Sector of VTSI: %08x\n", vtsi_mat->vtsi_last_sector);
|
|
522 printf("Specification version number: %01x.%01x\n",
|
|
523 vtsi_mat->specification_version>>4,
|
|
524 vtsi_mat->specification_version&0xf);
|
|
525 printf("VTS Category: %08x\n", vtsi_mat->vts_category);
|
|
526 printf("End byte of VTSI_MAT: %08x\n", vtsi_mat->vtsi_last_byte);
|
|
527 printf("Start sector of VTSM_VOBS: %08x\n", vtsi_mat->vtsm_vobs);
|
|
528 printf("Start sector of VTSTT_VOBS: %08x\n", vtsi_mat->vtstt_vobs);
|
|
529 printf("Start sector of VTS_PTT_SRPT: %08x\n", vtsi_mat->vts_ptt_srpt);
|
|
530 printf("Start sector of VTS_PGCIT: %08x\n", vtsi_mat->vts_pgcit);
|
|
531 printf("Start sector of VTSM_PGCI_UT: %08x\n", vtsi_mat->vtsm_pgci_ut);
|
|
532 printf("Start sector of VTS_TMAPT: %08x\n", vtsi_mat->vts_tmapt);
|
|
533 printf("Start sector of VTSM_C_ADT: %08x\n", vtsi_mat->vtsm_c_adt);
|
|
534 printf("Start sector of VTSM_VOBU_ADMAP: %08x\n",vtsi_mat->vtsm_vobu_admap);
|
|
535 printf("Start sector of VTS_C_ADT: %08x\n", vtsi_mat->vts_c_adt);
|
|
536 printf("Start sector of VTS_VOBU_ADMAP: %08x\n", vtsi_mat->vts_vobu_admap);
|
|
537
|
|
538 printf("Video attributes of VTSM_VOBS: ");
|
|
539 ifoPrint_video_attributes(5, &vtsi_mat->vtsm_video_attr);
|
|
540 printf("\n");
|
|
541
|
|
542 printf("VTSM Number of Audio attributes: %i\n",
|
|
543 vtsi_mat->nr_of_vtsm_audio_streams);
|
|
544 if(vtsi_mat->nr_of_vtsm_audio_streams > 0) {
|
|
545 printf("\tstream %i status: ", 1);
|
|
546 ifoPrint_audio_attributes(5, &vtsi_mat->vtsm_audio_attr);
|
|
547 printf("\n");
|
|
548 }
|
|
549
|
|
550 printf("VTSM Number of Sub-picture attributes: %i\n",
|
|
551 vtsi_mat->nr_of_vtsm_subp_streams);
|
|
552 if(vtsi_mat->nr_of_vtsm_subp_streams > 0) {
|
|
553 printf("\tstream %2i status: ", 1);
|
|
554 ifoPrint_subp_attributes(5, &vtsi_mat->vtsm_subp_attr);
|
|
555 printf("\n");
|
|
556 }
|
|
557
|
|
558 printf("Video attributes of VTS_VOBS: ");
|
|
559 ifoPrint_video_attributes(5, &vtsi_mat->vts_video_attr);
|
|
560 printf("\n");
|
|
561
|
|
562 printf("VTS Number of Audio attributes: %i\n",
|
|
563 vtsi_mat->nr_of_vts_audio_streams);
|
|
564 for(i = 0; i < vtsi_mat->nr_of_vts_audio_streams; i++) {
|
|
565 printf("\tstream %i status: ", i);
|
|
566 ifoPrint_audio_attributes(5, &vtsi_mat->vts_audio_attr[i]);
|
|
567 printf("\n");
|
|
568 }
|
|
569
|
|
570 printf("VTS Number of Subpicture attributes: %i\n",
|
|
571 vtsi_mat->nr_of_vts_subp_streams);
|
|
572 for(i = 0; i < vtsi_mat->nr_of_vts_subp_streams; i++) {
|
|
573 printf("\tstream %2i status: ", i);
|
|
574 ifoPrint_subp_attributes(5, &vtsi_mat->vts_subp_attr[i]);
|
|
575 printf("\n");
|
|
576 }
|
|
577 }
|
|
578
|
|
579
|
|
580 static void ifoPrint_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl) {
|
|
581 int i;
|
|
582
|
|
583 if(cmd_tbl == NULL) {
|
|
584 printf("No Command table present\n");
|
|
585 return;
|
|
586 }
|
|
587
|
|
588 printf("Number of Pre commands: %i\n", cmd_tbl->nr_of_pre);
|
|
589 for(i = 0; i < cmd_tbl->nr_of_pre; i++) {
|
|
590 ifoPrint_CMD(i, &cmd_tbl->pre_cmds[i]);
|
|
591 }
|
|
592
|
|
593 printf("Number of Post commands: %i\n", cmd_tbl->nr_of_post);
|
|
594 for(i = 0; i < cmd_tbl->nr_of_post; i++) {
|
|
595 ifoPrint_CMD(i, &cmd_tbl->post_cmds[i]);
|
|
596 }
|
|
597
|
|
598 printf("Number of Cell commands: %i\n", cmd_tbl->nr_of_cell);
|
|
599 for(i = 0; i < cmd_tbl->nr_of_cell; i++) {
|
|
600 ifoPrint_CMD(i, &cmd_tbl->cell_cmds[i]);
|
|
601 }
|
|
602 }
|
|
603
|
|
604
|
|
605 static void ifoPrint_PGC_PROGRAM_MAP(pgc_program_map_t *program_map, int nr) {
|
|
606 int i;
|
|
607
|
|
608 if(program_map == NULL) {
|
|
609 printf("No Program map present\n");
|
|
610 return;
|
|
611 }
|
|
612
|
|
613 for(i = 0; i < nr; i++) {
|
|
614 printf("Program %3i Entry Cell: %3i\n", i + 1, program_map[i]);
|
|
615 }
|
|
616 }
|
|
617
|
|
618
|
|
619 static void ifoPrint_CELL_PLAYBACK(cell_playback_t *cell_playback, int nr) {
|
|
620 int i;
|
|
621
|
|
622 if(cell_playback == NULL) {
|
|
623 printf("No Cell Playback info present\n");
|
|
624 return;
|
|
625 }
|
|
626
|
|
627 for(i=0;i<nr;i++) {
|
|
628 printf("Cell: %3i ", i + 1);
|
|
629
|
|
630 ifoPrint_time(5, &cell_playback[i].playback_time);
|
|
631 printf("\t");
|
|
632
|
|
633 if(cell_playback[i].block_mode || cell_playback[i].block_type) {
|
|
634 const char *s;
|
|
635 switch(cell_playback[i].block_mode) {
|
|
636 case 0:
|
|
637 s = "not a"; break;
|
|
638 case 1:
|
|
639 s = "the first"; break;
|
|
640 case 2:
|
|
641 default:
|
|
642 s = ""; break;
|
|
643 case 3:
|
|
644 s = "last"; break;
|
|
645 }
|
|
646 printf("%s cell in the block ", s);
|
|
647
|
|
648 switch(cell_playback[i].block_type) {
|
|
649 case 0:
|
|
650 printf("not part of the block ");
|
|
651 break;
|
|
652 case 1:
|
|
653 printf("angle block ");
|
|
654 break;
|
|
655 case 2:
|
|
656 case 3:
|
|
657 printf("(send bug repport) ");
|
|
658 break;
|
|
659 }
|
|
660 }
|
|
661 if(cell_playback[i].seamless_play)
|
|
662 printf("presented seamlessly ");
|
|
663 if(cell_playback[i].interleaved)
|
|
664 printf("cell is interleaved ");
|
|
665 if(cell_playback[i].stc_discontinuity)
|
|
666 printf("STC_discontinuty ");
|
|
667 if(cell_playback[i].seamless_angle)
|
|
668 printf("only seamless angle ");
|
|
669 if(cell_playback[i].restricted)
|
|
670 printf("restricted cell ");
|
|
671
|
|
672 if(cell_playback[i].still_time)
|
|
673 printf("still time %d ", cell_playback[i].still_time);
|
|
674 if(cell_playback[i].cell_cmd_nr)
|
|
675 printf("cell command %d", cell_playback[i].cell_cmd_nr);
|
|
676
|
|
677 printf("\n\tStart sector: %08x\tFirst ILVU end sector: %08x\n",
|
|
678 cell_playback[i].first_sector,
|
|
679 cell_playback[i].first_ilvu_end_sector);
|
|
680 printf("\tEnd sector: %08x\tLast VOBU start sector: %08x\n",
|
|
681 cell_playback[i].last_sector,
|
|
682 cell_playback[i].last_vobu_start_sector);
|
|
683 }
|
|
684 }
|
|
685
|
|
686 static void ifoPrint_CELL_POSITION(cell_position_t *cell_position, int nr) {
|
|
687 int i;
|
|
688
|
|
689 if(cell_position == NULL) {
|
|
690 printf("No Cell Position info present\n");
|
|
691 return;
|
|
692 }
|
|
693
|
|
694 for(i=0;i<nr;i++) {
|
|
695 printf("Cell: %3i has VOB ID: %3i, Cell ID: %3i\n", i + 1,
|
|
696 cell_position[i].vob_id_nr, cell_position[i].cell_nr);
|
|
697 }
|
|
698 }
|
|
699
|
|
700
|
|
701 void ifoPrint_PGC(pgc_t *pgc) {
|
|
702 int i;
|
|
703
|
|
704 printf("Number of Programs: %i\n", pgc->nr_of_programs);
|
|
705 printf("Number of Cells: %i\n", pgc->nr_of_cells);
|
|
706 /* Check that time is 0:0:0:0 also if nr_of_programs==0 */
|
|
707 printf("Playback time: ");
|
|
708 ifoPrint_time(5, &pgc->playback_time); printf("\n");
|
|
709
|
|
710 /* If no programs/no time then does this mean anything? */
|
|
711 printf("Prohibited user operations: ");
|
|
712 ifoPrint_USER_OPS(&pgc->prohibited_ops);
|
|
713
|
|
714 for(i = 0; i < 8; i++) {
|
|
715 if(pgc->audio_control[i] & 0x8000) { /* The 'is present' bit */
|
|
716 printf("Audio stream %i control: %04x\n",
|
|
717 i, pgc->audio_control[i]);
|
|
718 }
|
|
719 }
|
|
720
|
|
721 for(i = 0; i < 32; i++) {
|
|
722 if(pgc->subp_control[i] & 0x80000000) { /* The 'is present' bit */
|
|
723 printf("Subpicture stream %2i control: %08x\n",
|
|
724 i, pgc->subp_control[i]);
|
|
725 }
|
|
726 }
|
|
727
|
|
728 printf("Next PGC number: %i\n", pgc->next_pgc_nr);
|
|
729 printf("Prev PGC number: %i\n", pgc->prev_pgc_nr);
|
|
730 printf("GoUp PGC number: %i\n", pgc->goup_pgc_nr);
|
|
731 if(pgc->nr_of_programs != 0) {
|
|
732 printf("Still time: %i seconds (255=inf)\n", pgc->still_time);
|
|
733 printf("PG Playback mode %02x\n", pgc->pg_playback_mode);
|
|
734 }
|
|
735
|
|
736 if(pgc->nr_of_programs != 0) {
|
|
737 for(i = 0; i < 16; i++) {
|
|
738 printf("Color %2i: %08x\n", i, pgc->palette[i]);
|
|
739 }
|
|
740 }
|
|
741
|
|
742 /* Memmory offsets to div. tables. */
|
|
743 ifoPrint_PGC_COMMAND_TBL(pgc->command_tbl);
|
|
744 ifoPrint_PGC_PROGRAM_MAP(pgc->program_map, pgc->nr_of_programs);
|
|
745 ifoPrint_CELL_PLAYBACK(pgc->cell_playback, pgc->nr_of_cells);
|
|
746 ifoPrint_CELL_POSITION(pgc->cell_position, pgc->nr_of_cells);
|
|
747 }
|
|
748
|
|
749
|
|
750 void ifoPrint_TT_SRPT(tt_srpt_t *tt_srpt) {
|
|
751 int i;
|
|
752
|
|
753 printf("Number of TitleTrack search pointers: %i\n",
|
|
754 tt_srpt->nr_of_srpts);
|
|
755 for(i=0;i<tt_srpt->nr_of_srpts;i++) {
|
|
756 printf("Title Track index %i\n", i + 1);
|
|
757 printf("\tTitle set number (VTS): %i",
|
|
758 tt_srpt->title[i].title_set_nr);
|
|
759 printf("\tVTS_TTN: %i\n", tt_srpt->title[i].vts_ttn);
|
|
760 printf("\tNumber of PTTs: %i\n", tt_srpt->title[i].nr_of_ptts);
|
|
761 printf("\tNumber of angles: %i\n",
|
|
762 tt_srpt->title[i].nr_of_angles);
|
|
763 printf("\tTitle playback type: %02x\n", /* XXX: TODO FIXME */
|
|
764 *(uint8_t *)&(tt_srpt->title[i].pb_ty));
|
|
765 printf("\tParental ID field: %04x\n",
|
|
766 tt_srpt->title[i].parental_id);
|
|
767 printf("\tTitle set starting sector %08x\n",
|
|
768 tt_srpt->title[i].title_set_sector);
|
|
769 }
|
|
770 }
|
|
771
|
|
772
|
|
773 void ifoPrint_VTS_PTT_SRPT(vts_ptt_srpt_t *vts_ptt_srpt) {
|
|
774 int i, j;
|
|
775 printf(" nr_of_srpts %i last byte %i\n",
|
|
776 vts_ptt_srpt->nr_of_srpts,
|
|
777 vts_ptt_srpt->last_byte);
|
|
778 for(i=0;i<vts_ptt_srpt->nr_of_srpts;i++) {
|
|
779 for(j=0;j<vts_ptt_srpt->title[i].nr_of_ptts;j++) {
|
|
780 printf("VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
|
|
781 i + 1, j + 1,
|
|
782 vts_ptt_srpt->title[i].ptt[j].pgcn,
|
|
783 vts_ptt_srpt->title[i].ptt[j].pgn );
|
|
784 }
|
|
785 }
|
|
786 }
|
|
787
|
|
788
|
|
789 static void hexdump(uint8_t *ptr, int len) {
|
|
790 while(len--)
|
|
791 printf("%02x ", *ptr++);
|
|
792 }
|
|
793
|
|
794 void ifoPrint_PTL_MAIT(ptl_mait_t *ptl_mait) {
|
|
795 int i, j;
|
|
796
|
|
797 printf("Number of Countries: %i\n", ptl_mait->nr_of_countries);
|
|
798 printf("Number of VTSs: %i\n", ptl_mait->nr_of_vtss);
|
|
799 //printf("Last byte: %i\n", ptl_mait->last_byte);
|
|
800
|
|
801 for(i = 0; i < ptl_mait->nr_of_countries; i++) {
|
|
802 printf("Country code: %c%c\n",
|
|
803 ptl_mait->countries[i].country_code >> 8,
|
|
804 ptl_mait->countries[i].country_code & 0xff);
|
|
805 /*
|
|
806 printf("Start byte: %04x %i\n",
|
|
807 ptl_mait->countries[i].pf_ptl_mai_start_byte,
|
|
808 ptl_mait->countries[i].pf_ptl_mai_start_byte);
|
|
809 */
|
|
810 /* This seems to be pointing at a array with 8 2byte fields per VTS
|
|
811 ? and one extra for the menu? always an odd number of VTSs on
|
|
812 all the dics I tested so it might be padding to even also.
|
|
813 If it is for the menu it probably the first entry. */
|
|
814 for(j=0;j<8;j++) {
|
|
815 hexdump( (uint8_t *)ptl_mait->countries - PTL_MAIT_COUNTRY_SIZE
|
|
816 + ptl_mait->countries[i].pf_ptl_mai_start_byte
|
|
817 + j*(ptl_mait->nr_of_vtss+1)*2, (ptl_mait->nr_of_vtss+1)*2);
|
|
818 printf("\n");
|
|
819 }
|
|
820 }
|
|
821 }
|
|
822
|
|
823
|
|
824 void ifoPrint_C_ADT(c_adt_t *c_adt) {
|
|
825 int i, entries;
|
|
826
|
|
827 printf("Number of VOBs in this VOBS: %i\n", c_adt->nr_of_vobs);
|
|
828 //entries = c_adt->nr_of_vobs;
|
|
829 entries = (c_adt->last_byte + 1 - C_ADT_SIZE)/sizeof(c_adt_t);
|
|
830
|
|
831 for(i = 0; i < entries; i++) {
|
|
832 printf("VOB ID: %3i, Cell ID: %3i ",
|
|
833 c_adt->cell_adr_table[i].vob_id, c_adt->cell_adr_table[i].cell_id);
|
|
834 printf("Sector (first): 0x%08x (last): 0x%08x\n",
|
|
835 c_adt->cell_adr_table[i].start_sector,
|
|
836 c_adt->cell_adr_table[i].last_sector);
|
|
837 }
|
|
838 }
|
|
839
|
|
840
|
|
841 void ifoPrint_VOBU_ADMAP(vobu_admap_t *vobu_admap) {
|
|
842 int i, entries;
|
|
843
|
|
844 entries = (vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE)/4;
|
|
845 for(i = 0; i < entries; i++) {
|
|
846 printf("VOBU %5i First sector: 0x%08x\n", i + 1,
|
|
847 vobu_admap->vobu_start_sectors[i]);
|
|
848 }
|
|
849 }
|
|
850
|
|
851
|
|
852 void ifoPrint_PGCIT(pgcit_t *pgcit) {
|
|
853 int i;
|
|
854
|
|
855 for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
|
|
856 printf("\nProgram (PGC): %3i\t", i + 1);
|
|
857 printf("PGC Category: Entry id 0x%02x, ", pgcit->pgci_srp[i].entry_id);
|
|
858 printf("Parental ID mask 0x%04x\n", pgcit->pgci_srp[i].ptl_id_mask);
|
|
859 ifoPrint_PGC(pgcit->pgci_srp[i].pgc);
|
|
860 }
|
|
861 }
|
|
862
|
|
863
|
|
864 void ifoPrint_PGCI_UT(pgci_ut_t *pgci_ut) {
|
|
865 int i;
|
|
866
|
|
867 printf("Number of Menu Language Units (PGCI_LU): %3i\n", pgci_ut->nr_of_lus);
|
|
868 for(i = 0; i < pgci_ut->nr_of_lus; i++) {
|
|
869 printf("\nMenu Language Code: %c%c\n",
|
|
870 pgci_ut->lu[i].lang_code >> 8,
|
|
871 pgci_ut->lu[i].lang_code & 0xff);
|
|
872 printf("Menu Existence: %02x\n", pgci_ut->lu[i].exists);
|
|
873 ifoPrint_PGCIT(pgci_ut->lu[i].pgcit);
|
|
874 }
|
|
875 }
|
|
876
|
|
877
|
|
878 static void ifoPrint_VTS_ATTRIBUTES(vts_attributes_t *vts_attributes) {
|
|
879 int i;
|
|
880
|
|
881 printf("VTS_CAT Application type: %08x\n", vts_attributes->vts_cat);
|
|
882
|
|
883 printf("Video attributes of VTSM_VOBS: ");
|
|
884 ifoPrint_video_attributes(5, &vts_attributes->vtsm_vobs_attr);
|
|
885 printf("\n");
|
|
886 printf("Number of Audio streams: %i\n",
|
|
887 vts_attributes->nr_of_vtsm_audio_streams);
|
|
888 if(vts_attributes->nr_of_vtsm_audio_streams > 0) {
|
|
889 printf("\tstream %i attributes: ", 1);
|
|
890 ifoPrint_audio_attributes(5, &vts_attributes->vtsm_audio_attr);
|
|
891 printf("\n");
|
|
892 }
|
|
893 printf("Number of Subpicture streams: %i\n",
|
|
894 vts_attributes->nr_of_vtsm_subp_streams);
|
|
895 if(vts_attributes->nr_of_vtsm_subp_streams > 0) {
|
|
896 printf("\tstream %2i attributes: ", 1);
|
|
897 ifoPrint_subp_attributes(5, &vts_attributes->vtsm_subp_attr);
|
|
898 printf("\n");
|
|
899 }
|
|
900
|
|
901 printf("Video attributes of VTSTT_VOBS: ");
|
|
902 ifoPrint_video_attributes(5, &vts_attributes->vtstt_vobs_video_attr);
|
|
903 printf("\n");
|
|
904 printf("Number of Audio streams: %i\n",
|
|
905 vts_attributes->nr_of_vtstt_audio_streams);
|
|
906 for(i = 0; i < vts_attributes->nr_of_vtstt_audio_streams; i++) {
|
|
907 printf("\tstream %i attributes: ", i);
|
|
908 ifoPrint_audio_attributes(5, &vts_attributes->vtstt_audio_attr[i]);
|
|
909 printf("\n");
|
|
910 }
|
|
911
|
|
912 printf("Number of Subpicture streams: %i\n",
|
|
913 vts_attributes->nr_of_vtstt_subp_streams);
|
|
914 for(i = 0; i < vts_attributes->nr_of_vtstt_subp_streams; i++) {
|
|
915 printf("\tstream %2i attributes: ", i);
|
|
916 ifoPrint_subp_attributes(5, &vts_attributes->vtstt_subp_attr[i]);
|
|
917 printf("\n");
|
|
918 }
|
|
919 }
|
|
920
|
|
921
|
|
922 void ifoPrint_VTS_ATRT(vts_atrt_t *vts_atrt) {
|
|
923 int i;
|
|
924
|
|
925 printf("Number of Video Title Sets: %3i\n", vts_atrt->nr_of_vtss);
|
|
926 for(i = 0; i < vts_atrt->nr_of_vtss; i++) {
|
|
927 printf("\nVideo Title Set %i\n", i + 1);
|
|
928 ifoPrint_VTS_ATTRIBUTES(&vts_atrt->vts[i]);
|
|
929 }
|
|
930 }
|
|
931
|
|
932
|
|
933 void ifoPrint(dvd_reader_t *dvd, int title) {
|
|
934 ifo_handle_t *ifohandle;
|
|
935
|
|
936 ifohandle = ifoOpen(dvd, title);
|
|
937 if(!ifohandle) {
|
|
938 fprintf(stderr, "Can't open info file for title %d\n", title);
|
|
939 return;
|
|
940 }
|
|
941
|
|
942
|
|
943 if(ifohandle->vmgi_mat) {
|
|
944
|
|
945 printf("VMG top level\n-------------\n");
|
|
946 ifoPrint_VMGI_MAT(ifohandle->vmgi_mat);
|
|
947
|
|
948 printf("\nFirst Play PGC\n--------------\n");
|
|
949 ifoPrint_PGC(ifohandle->first_play_pgc);
|
|
950
|
|
951 printf("\nTitle Track search pointer table\n");
|
|
952 printf( "------------------------------------------------\n");
|
|
953 ifoPrint_TT_SRPT(ifohandle->tt_srpt);
|
|
954
|
|
955 printf("\nMenu PGCI Unit table\n");
|
|
956 printf( "--------------------\n");
|
|
957 if(ifohandle->pgci_ut) {
|
|
958 ifoPrint_PGCI_UT(ifohandle->pgci_ut);
|
|
959 } else {
|
|
960 printf("No PGCI Unit table present\n");
|
|
961 }
|
|
962
|
|
963 printf("\nParental Manegment Information table\n");
|
|
964 printf( "------------------------------------\n");
|
|
965 if(ifohandle->ptl_mait) {
|
|
966 ifoPrint_PTL_MAIT(ifohandle->ptl_mait);
|
|
967 } else {
|
|
968 printf("No Parental Management Information present\n");
|
|
969 }
|
|
970
|
|
971 printf("\nVideo Title Set Attribute Table\n");
|
|
972 printf( "-------------------------------\n");
|
|
973 ifoPrint_VTS_ATRT(ifohandle->vts_atrt);
|
|
974
|
|
975 printf("\nText Data Manager Information\n");
|
|
976 printf( "-----------------------------\n");
|
|
977 if(ifohandle->txtdt_mgi) {
|
|
978 //ifoPrint_TXTDT_MGI(&(vmgi->txtdt_mgi));
|
|
979 } else {
|
|
980 printf("No Text Data Manager Information present\n");
|
|
981 }
|
|
982
|
|
983 printf("\nMenu Cell Adress table\n");
|
|
984 printf( "-----------------\n");
|
|
985 if(ifohandle->menu_c_adt) {
|
|
986 ifoPrint_C_ADT(ifohandle->menu_c_adt);
|
|
987 } else {
|
|
988 printf("No Menu Cell Adress table present\n");
|
|
989 }
|
|
990
|
|
991 printf("\nVideo Manager Menu VOBU address map\n");
|
|
992 printf( "-----------------\n");
|
|
993 if(ifohandle->menu_vobu_admap) {
|
|
994 ifoPrint_VOBU_ADMAP(ifohandle->menu_vobu_admap);
|
|
995 } else {
|
|
996 printf("No Menu VOBU address map present\n");
|
|
997 }
|
|
998 }
|
|
999
|
|
1000
|
|
1001 if(ifohandle->vtsi_mat) {
|
|
1002
|
|
1003 printf("VTS top level\n-------------\n");
|
|
1004 ifoPrint_VTSI_MAT(ifohandle->vtsi_mat);
|
|
1005
|
|
1006 printf("\nPart of Title Track search pointer table\n");
|
|
1007 printf( "----------------------------------------------\n");
|
|
1008 ifoPrint_VTS_PTT_SRPT(ifohandle->vts_ptt_srpt);
|
|
1009
|
|
1010 printf("\nPGCI Unit table\n");
|
|
1011 printf( "--------------------\n");
|
|
1012 ifoPrint_PGCIT(ifohandle->vts_pgcit);
|
|
1013
|
|
1014 printf("\nMenu PGCI Unit table\n");
|
|
1015 printf( "--------------------\n");
|
|
1016 if(ifohandle->pgci_ut) {
|
|
1017 ifoPrint_PGCI_UT(ifohandle->pgci_ut);
|
|
1018 } else {
|
|
1019 printf("No Menu PGCI Unit table present\n");
|
|
1020 }
|
|
1021
|
|
1022 printf("\nMenu Cell Adress table\n");
|
|
1023 printf( "-----------------\n");
|
|
1024 if(ifohandle->menu_c_adt) {
|
|
1025 ifoPrint_C_ADT(ifohandle->menu_c_adt);
|
|
1026 } else {
|
|
1027 printf("No Cell Adress table present\n");
|
|
1028 }
|
|
1029
|
|
1030 printf("\nVideo Title Set Menu VOBU address map\n");
|
|
1031 printf( "-----------------\n");
|
|
1032 if(ifohandle->menu_vobu_admap) {
|
|
1033 ifoPrint_VOBU_ADMAP(ifohandle->menu_vobu_admap);
|
|
1034 } else {
|
|
1035 printf("No Menu VOBU address map present\n");
|
|
1036 }
|
|
1037
|
|
1038 printf("\nCell Adress table\n");
|
|
1039 printf( "-----------------\n");
|
|
1040 ifoPrint_C_ADT(ifohandle->vts_c_adt);
|
|
1041
|
|
1042 printf("\nVideo Title Set VOBU address map\n");
|
|
1043 printf( "-----------------\n");
|
|
1044 ifoPrint_VOBU_ADMAP(ifohandle->vts_vobu_admap);
|
|
1045 }
|
|
1046
|
|
1047 ifoClose(ifohandle);
|
|
1048 }
|
|
1049
|