2 * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn@dtek.chalmers.se>,
3 * Håkan Hjort <d95hjort@dtek.chalmers.se>
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.
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.
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
28 #include "config.h" // Needed for WORDS_BIGENDIAN
29 #include "ifo_types.h"
31 #include "ifo_print.h"
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
) {
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);
41 printf("%02x:%02x:%02x.%02x",
45 dtime
->frame_u
& 0x3f);
46 switch((dtime
->frame_u
& 0xc0) >> 6) {
54 if(dtime
->hour
== 0 && dtime
->minute
== 0
55 && dtime
->second
== 0 && dtime
->frame_u
== 0)
58 rate
= "(please send a bug report)";
61 printf(" @ %s fps", rate
);
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
) {
69 printf("(%03d) ", row
+ 1);
71 printf("%02x ", command
->bytes
[i
]);
78 static void ifoPrint_video_attributes(int level
, video_attr_t
*attr
) {
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 --");
96 switch(attr
->mpeg_version
) {
104 printf("(please send a bug report) ");
107 switch(attr
->video_format
) {
115 printf("(please send a bug report) ");
118 switch(attr
->display_aspect_ratio
) {
126 printf("(please send a bug report) ");
129 // Wide is allways allowed..!!!
130 switch(attr
->permitted_df
) {
132 printf("pan&scan+letterboxed ");
135 printf("only pan&scan "); //??
138 printf("only letterboxed ");
144 printf("(please send a bug report)");
147 printf("U%x ", attr
->unknown1
);
148 assert(!attr
->unknown1
);
150 if(attr
->line21_cc_1
|| attr
->line21_cc_2
) {
152 if(attr
->line21_cc_1
)
154 if(attr
->line21_cc_2
)
160 if(attr
->video_format
!= 0)
162 switch(attr
->picture_size
) {
164 printf("720x%d ", height
);
167 printf("704x%d ", height
);
170 printf("352x%d ", height
);
173 printf("352x%d ", height
/2);
176 printf("(please send a bug report) ");
180 if(attr
->letterboxed
) {
181 printf("source letterboxed ");
184 if(attr
->film_mode
) {
187 printf("video"); //camera
191 static void ifoPrint_audio_attributes(int level
, audio_attr_t
*attr
) {
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 --");
207 switch(attr
->audio_format
) {
212 printf("(please send a bug report) ");
224 printf("(please send a bug report) ");
230 printf("(please send a bug report) ");
233 if(attr
->multichannel_extension
)
234 printf("multichannel_extension ");
236 switch(attr
->lang_type
) {
239 assert(attr
->lang_code
== 0 || attr
->lang_code
== 0xffff);
242 printf("%c%c ", attr
->lang_code
>>8, attr
->lang_code
& 0xff);
245 printf("(please send a bug report) ");
248 switch(attr
->application_mode
) {
253 printf("karaoke mode ");
256 printf("surround sound mode ");
259 printf("(please send a bug report) ");
262 switch(attr
->quantization
) {
276 printf("(please send a bug report) ");
279 switch(attr
->sample_frequency
) {
287 printf("sample_frequency %i (please send a bug report) ",
288 attr
->sample_frequency
);
291 printf("%dCh ", attr
->channels
+ 1);
293 switch(attr
->lang_extension
) {
295 printf("Not specified ");
297 case 1: // Normal audio
298 printf("Normal Caption ");
300 case 2: // visually imparied
301 printf("Audio for visually impaired ");
303 case 3: // Directors 1
304 printf("Director's comments 1 ");
306 case 4: // Directors 2
307 printf("Director's comments 2 ");
309 //case 4: // Music score ?
311 printf("(please send a bug report) ");
314 printf("%d ", attr
->unknown1
);
315 printf("%d ", attr
->unknown2
);
318 static void ifoPrint_subp_attributes(int level
, subp_attr_t
*attr
) {
321 && attr
->lang_code
== 0
324 && attr
->lang_extension
== 0) {
325 printf("-- Unspecified --");
329 printf("type %02x ", attr
->type
);
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);
335 printf("%02x%02x ", 0xff & (unsigned)(attr
->lang_code
>> 8),
336 0xff & (unsigned)(attr
->lang_code
& 0xff));
339 printf("%d ", attr
->zero1
);
340 printf("%d ", attr
->zero2
);
342 switch(attr
->lang_extension
) {
344 printf("Not specified ");
347 printf("Caption with normal size character ");
350 printf("Caption with bigger size character ");
353 printf("Caption for children ");
359 printf("Closed Caption with normal size character ");
362 printf("Closed Caption with bigger size character ");
365 printf("Closed Caption for children ");
371 printf("Forced Caption");
383 printf("Director's comments with normal size character ");
386 printf("Director's comments with bigger size character ");
389 printf("Director's comments for children ");
392 printf("(please send a bug report) ");
398 static void ifoPrint_USER_OPS(user_ops_t
*user_ops
) {
400 unsigned char *ptr
= (unsigned char *)user_ops
;
402 uops
= (*ptr
++ << 24);
403 uops
|= (*ptr
++ << 16);
404 uops
|= (*ptr
++ << 8);
409 } else if(uops
== 0x01ffffff) {
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, ");
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, ");
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, ");
467 void ifoPrint_VMGI_MAT(vmgi_mat_t
*vmgi_mat
) {
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
);
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
);
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
);
516 void ifoPrint_VTSI_MAT(vtsi_mat_t
*vtsi_mat
) {
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
);
538 printf("Video attributes of VTSM_VOBS: ");
539 ifoPrint_video_attributes(5, &vtsi_mat
->vtsm_video_attr
);
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
);
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
);
558 printf("Video attributes of VTS_VOBS: ");
559 ifoPrint_video_attributes(5, &vtsi_mat
->vts_video_attr
);
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
]);
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
]);
580 static void ifoPrint_PGC_COMMAND_TBL(pgc_command_tbl_t
*cmd_tbl
) {
583 if(cmd_tbl
== NULL
) {
584 printf("No Command table present\n");
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
]);
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
]);
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
]);
605 static void ifoPrint_PGC_PROGRAM_MAP(pgc_program_map_t
*program_map
, int nr
) {
608 if(program_map
== NULL
) {
609 printf("No Program map present\n");
613 for(i
= 0; i
< nr
; i
++) {
614 printf("Program %3i Entry Cell: %3i\n", i
+ 1, program_map
[i
]);
619 static void ifoPrint_CELL_PLAYBACK(cell_playback_t
*cell_playback
, int nr
) {
622 if(cell_playback
== NULL
) {
623 printf("No Cell Playback info present\n");
628 printf("Cell: %3i ", i
+ 1);
630 ifoPrint_time(5, &cell_playback
[i
].playback_time
);
633 if(cell_playback
[i
].block_mode
|| cell_playback
[i
].block_type
) {
635 switch(cell_playback
[i
].block_mode
) {
639 s
= "the first"; break;
646 printf("%s cell in the block ", s
);
648 switch(cell_playback
[i
].block_type
) {
650 printf("not part of the block ");
653 printf("angle block ");
657 printf("(send bug repport) ");
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 ");
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
);
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
);
686 static void ifoPrint_CELL_POSITION(cell_position_t
*cell_position
, int nr
) {
689 if(cell_position
== NULL
) {
690 printf("No Cell Position info present\n");
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
);
701 void ifoPrint_PGC(pgc_t
*pgc
) {
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");
710 /* If no programs/no time then does this mean anything? */
711 printf("Prohibited user operations: ");
712 ifoPrint_USER_OPS(&pgc
->prohibited_ops
);
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
]);
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
]);
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
);
736 if(pgc
->nr_of_programs
!= 0) {
737 for(i
= 0; i
< 16; i
++) {
738 printf("Color %2i: %08x\n", i
, pgc
->palette
[i
]);
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
);
750 void ifoPrint_TT_SRPT(tt_srpt_t
*tt_srpt
) {
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
);
773 void ifoPrint_VTS_PTT_SRPT(vts_ptt_srpt_t
*vts_ptt_srpt
) {
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",
782 vts_ptt_srpt
->title
[i
].ptt
[j
].pgcn
,
783 vts_ptt_srpt
->title
[i
].ptt
[j
].pgn
);
789 static void hexdump(uint8_t *ptr
, int len
) {
791 printf("%02x ", *ptr
++);
794 void ifoPrint_PTL_MAIT(ptl_mait_t
*ptl_mait
) {
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);
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);
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);
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. */
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);
824 void ifoPrint_C_ADT(c_adt_t
*c_adt
) {
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
);
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
);
841 void ifoPrint_VOBU_ADMAP(vobu_admap_t
*vobu_admap
) {
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
]);
852 void ifoPrint_PGCIT(pgcit_t
*pgcit
) {
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
);
864 void ifoPrint_PGCI_UT(pgci_ut_t
*pgci_ut
) {
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
);
878 static void ifoPrint_VTS_ATTRIBUTES(vts_attributes_t
*vts_attributes
) {
881 printf("VTS_CAT Application type: %08x\n", vts_attributes
->vts_cat
);
883 printf("Video attributes of VTSM_VOBS: ");
884 ifoPrint_video_attributes(5, &vts_attributes
->vtsm_vobs_attr
);
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
);
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
);
901 printf("Video attributes of VTSTT_VOBS: ");
902 ifoPrint_video_attributes(5, &vts_attributes
->vtstt_vobs_video_attr
);
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
]);
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
]);
922 void ifoPrint_VTS_ATRT(vts_atrt_t
*vts_atrt
) {
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
]);
933 void ifoPrint(dvd_reader_t
*dvd
, int title
) {
934 ifo_handle_t
*ifohandle
;
936 ifohandle
= ifoOpen(dvd
, title
);
938 fprintf(stderr
, "Can't open info file for title %d\n", title
);
943 if(ifohandle
->vmgi_mat
) {
945 printf("VMG top level\n-------------\n");
946 ifoPrint_VMGI_MAT(ifohandle
->vmgi_mat
);
948 printf("\nFirst Play PGC\n--------------\n");
949 ifoPrint_PGC(ifohandle
->first_play_pgc
);
951 printf("\nTitle Track search pointer table\n");
952 printf( "------------------------------------------------\n");
953 ifoPrint_TT_SRPT(ifohandle
->tt_srpt
);
955 printf("\nMenu PGCI Unit table\n");
956 printf( "--------------------\n");
957 if(ifohandle
->pgci_ut
) {
958 ifoPrint_PGCI_UT(ifohandle
->pgci_ut
);
960 printf("No PGCI Unit table present\n");
963 printf("\nParental Manegment Information table\n");
964 printf( "------------------------------------\n");
965 if(ifohandle
->ptl_mait
) {
966 ifoPrint_PTL_MAIT(ifohandle
->ptl_mait
);
968 printf("No Parental Management Information present\n");
971 printf("\nVideo Title Set Attribute Table\n");
972 printf( "-------------------------------\n");
973 ifoPrint_VTS_ATRT(ifohandle
->vts_atrt
);
975 printf("\nText Data Manager Information\n");
976 printf( "-----------------------------\n");
977 if(ifohandle
->txtdt_mgi
) {
978 //ifoPrint_TXTDT_MGI(&(vmgi->txtdt_mgi));
980 printf("No Text Data Manager Information present\n");
983 printf("\nMenu Cell Adress table\n");
984 printf( "-----------------\n");
985 if(ifohandle
->menu_c_adt
) {
986 ifoPrint_C_ADT(ifohandle
->menu_c_adt
);
988 printf("No Menu Cell Adress table present\n");
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
);
996 printf("No Menu VOBU address map present\n");
1001 if(ifohandle
->vtsi_mat
) {
1003 printf("VTS top level\n-------------\n");
1004 ifoPrint_VTSI_MAT(ifohandle
->vtsi_mat
);
1006 printf("\nPart of Title Track search pointer table\n");
1007 printf( "----------------------------------------------\n");
1008 ifoPrint_VTS_PTT_SRPT(ifohandle
->vts_ptt_srpt
);
1010 printf("\nPGCI Unit table\n");
1011 printf( "--------------------\n");
1012 ifoPrint_PGCIT(ifohandle
->vts_pgcit
);
1014 printf("\nMenu PGCI Unit table\n");
1015 printf( "--------------------\n");
1016 if(ifohandle
->pgci_ut
) {
1017 ifoPrint_PGCI_UT(ifohandle
->pgci_ut
);
1019 printf("No Menu PGCI Unit table present\n");
1022 printf("\nMenu Cell Adress table\n");
1023 printf( "-----------------\n");
1024 if(ifohandle
->menu_c_adt
) {
1025 ifoPrint_C_ADT(ifohandle
->menu_c_adt
);
1027 printf("No Cell Adress table present\n");
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
);
1035 printf("No Menu VOBU address map present\n");
1038 printf("\nCell Adress table\n");
1039 printf( "-----------------\n");
1040 ifoPrint_C_ADT(ifohandle
->vts_c_adt
);
1042 printf("\nVideo Title Set VOBU address map\n");
1043 printf( "-----------------\n");
1044 ifoPrint_VOBU_ADMAP(ifohandle
->vts_vobu_admap
);
1047 ifoClose(ifohandle
);