comparison ifo_print.c @ 168:330ef38ad968 src

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