2 * Copyright (C) 2000, 2001, 2002, 2003
3 * Björn Englund <d4bjorn@dtek.chalmers.se>,
4 * Håkan Hjort <d95hjort@dtek.chalmers.se>
6 * Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
7 * detailed changelog at http://svn.mplayerhq.hu/mplayer/trunk/
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "ifo_types.h"
36 #include "ifo_print.h"
37 #include "dvdread_internal.h"
39 /* Put this in some other file / package? It's used in nav_print too. */
40 static void ifoPrint_time(dvd_time_t
*dtime
) {
42 CHECK_VALUE((dtime
->hour
>>4) < 0xa && (dtime
->hour
&0xf) < 0xa);
43 CHECK_VALUE((dtime
->minute
>>4) < 0x7 && (dtime
->minute
&0xf) < 0xa);
44 CHECK_VALUE((dtime
->second
>>4) < 0x7 && (dtime
->second
&0xf) < 0xa);
45 CHECK_VALUE((dtime
->frame_u
&0xf) < 0xa);
47 printf("%02x:%02x:%02x.%02x",
51 dtime
->frame_u
& 0x3f);
52 switch((dtime
->frame_u
& 0xc0) >> 6) {
60 if(dtime
->hour
== 0 && dtime
->minute
== 0
61 && dtime
->second
== 0 && dtime
->frame_u
== 0)
64 rate
= "(please send a bug report)";
67 printf(" @ %s fps", rate
);
70 /* Put this in some other file / package? It's used in nav_print too.
71 Possibly also by the vm / navigator. */
72 static void ifoPrint_CMD(int row
, vm_cmd_t
*command
) {
75 printf("(%03d) ", row
+ 1);
77 printf("%02x ", command
->bytes
[i
]);
84 static void ifoPrint_video_attributes(video_attr_t
*attr
) {
86 /* The following test is shorter but not correct ISO C,
87 memcmp(attr,my_friendly_zeros, sizeof(video_attr_t)) */
88 if(attr
->mpeg_version
== 0
89 && attr
->video_format
== 0
90 && attr
->display_aspect_ratio
== 0
91 && attr
->permitted_df
== 0
92 && attr
->unknown1
== 0
93 && attr
->line21_cc_1
== 0
94 && attr
->line21_cc_2
== 0
95 && attr
->bit_rate
== 0
96 && attr
->video_format
== 0
97 && attr
->letterboxed
== 0
98 && attr
->film_mode
== 0) {
99 printf("-- Unspecified --");
103 switch(attr
->mpeg_version
) {
111 printf("(please send a bug report) ");
114 switch(attr
->video_format
) {
122 printf("(please send a bug report) ");
125 switch(attr
->display_aspect_ratio
) {
133 printf("(please send a bug report) ");
136 // Wide is allways allowed..!!!
137 switch(attr
->permitted_df
) {
139 printf("pan&scan+letterboxed ");
142 printf("only pan&scan "); //??
145 printf("only letterboxed ");
151 printf("(please send a bug report)");
154 printf("U%x ", attr
->unknown1
);
155 CHECK_VALUE(!attr
->unknown1
);
157 if(attr
->line21_cc_1
|| attr
->line21_cc_2
) {
159 if(attr
->line21_cc_1
)
161 if(attr
->line21_cc_2
)
165 switch(attr
->bit_rate
) {
167 printf("Variable Bit Rate ");
170 printf("Constant Bit Rate ");
173 printf("(please send a bug report)");
178 if(attr
->video_format
!= 0)
180 switch(attr
->picture_size
) {
182 printf("720x%d ", height
);
185 printf("704x%d ", height
);
188 printf("352x%d ", height
);
191 printf("352x%d ", height
/2);
194 printf("(please send a bug report) ");
198 if(attr
->letterboxed
) {
199 printf("source letterboxed ");
202 if(attr
->film_mode
) {
205 printf("video"); //camera
209 static void ifoPrint_audio_attributes(audio_attr_t
*attr
) {
211 if(attr
->audio_format
== 0
212 && attr
->multichannel_extension
== 0
213 && attr
->lang_type
== 0
214 && attr
->application_mode
== 0
215 && attr
->quantization
== 0
216 && attr
->sample_frequency
== 0
217 && attr
->channels
== 0
218 && attr
->lang_code
== 0
219 && attr
->lang_extension
== 0
220 && attr
->code_extension
== 0
221 && attr
->unknown3
== 0
222 && attr
->unknown1
== 0) {
223 printf("-- Unspecified --");
227 switch(attr
->audio_format
) {
232 printf("(please send a bug report) ");
244 printf("(please send a bug report) ");
250 printf("(please send a bug report) ");
253 if(attr
->multichannel_extension
)
254 printf("multichannel_extension ");
256 switch(attr
->lang_type
) {
259 CHECK_VALUE(attr
->lang_code
== 0 || attr
->lang_code
== 0xffff);
262 printf("%c%c (%c) ", attr
->lang_code
>>8, attr
->lang_code
& 0xff,
263 attr
->lang_extension
? attr
->lang_extension
: ' ');
266 printf("(please send a bug report) ");
269 switch(attr
->application_mode
) {
274 printf("karaoke mode ");
277 printf("surround sound mode ");
280 printf("(please send a bug report) ");
283 switch(attr
->quantization
) {
297 printf("(please send a bug report) ");
300 switch(attr
->sample_frequency
) {
308 printf("sample_frequency %i (please send a bug report) ",
309 attr
->sample_frequency
);
312 printf("%dCh ", attr
->channels
+ 1);
314 switch(attr
->code_extension
) {
316 printf("Not specified ");
318 case 1: // Normal audio
319 printf("Normal Caption ");
321 case 2: // visually imparied
322 printf("Audio for visually impaired ");
324 case 3: // Directors 1
325 printf("Director's comments 1 ");
327 case 4: // Directors 2
328 printf("Director's comments 2 ");
330 //case 4: // Music score ?
332 printf("(please send a bug report) ");
335 printf("%d ", attr
->unknown3
);
336 if(attr
->application_mode
== 1) {
337 printf("ca=%d ", attr
->app_info
.karaoke
.channel_assignment
);
338 printf("%d ", attr
->app_info
.karaoke
.version
);
339 if(attr
->app_info
.karaoke
.mc_intro
)
341 printf("%s ", attr
->app_info
.karaoke
.mode
? "duet" : "solo");
342 printf("%d ", attr
->app_info
.karaoke
.unknown4
);
344 if(attr
->application_mode
== 2) {
345 if(attr
->app_info
.surround
.dolby_encoded
) {
346 printf("dolby surround ");
348 printf("%d ", attr
->app_info
.surround
.unknown5
);
349 printf("%d ", attr
->app_info
.surround
.unknown6
);
353 static void ifoPrint_subp_attributes(subp_attr_t
*attr
) {
356 && attr
->code_mode
== 0
357 && attr
->lang_code
== 0
358 && attr
->lang_extension
== 0
361 && attr
->code_extension
== 0) {
362 printf("-- Unspecified --");
366 switch(attr
->code_mode
) {
368 printf("Coding Mode RLE ");
371 printf("Coding Mode Extended ");
374 printf("(please send a bug report) ");
377 if(attr
->type
== 1) {
378 if(isalpha((int)(attr
->lang_code
>> 8))
379 && isalpha((int)(attr
->lang_code
& 0xff))) {
380 printf("%c%c ", attr
->lang_code
>> 8, attr
->lang_code
& 0xff);
382 printf("%02x%02x ", attr
->lang_code
>> 8, attr
->lang_code
& 0xff);
385 printf("lang not specified ");
388 printf("%d ", attr
->zero1
);
389 printf("%d ", attr
->zero2
);
390 printf("%d ", attr
->code_extension
);
392 /* Is this correct? should it not be subp_code_ext here instead? */
393 switch(attr
->lang_extension
) {
395 printf("Not specified ");
398 printf("Caption with normal size character ");
401 printf("Caption with bigger size character ");
404 printf("Caption for children ");
410 printf("Closed Caption with normal size character ");
413 printf("Closed Caption with bigger size character ");
416 printf("Closed Caption for children ");
422 printf("Forced Caption");
434 printf("Director's comments with normal size character ");
437 printf("Director's comments with bigger size character ");
440 printf("Director's comments for children ");
443 printf("(please send a bug report) ");
449 static void ifoPrint_USER_OPS(user_ops_t
*user_ops
) {
451 unsigned char *ptr
= (unsigned char *)user_ops
;
453 uops
= (*ptr
++ << 24);
454 uops
|= (*ptr
++ << 16);
455 uops
|= (*ptr
++ << 8);
460 } else if(uops
== 0x01ffffff) {
463 if(user_ops
->title_or_time_play
)
464 printf("Title or Time Play, ");
465 if(user_ops
->chapter_search_or_play
)
466 printf("Chapter Search or Play, ");
467 if(user_ops
->title_play
)
468 printf("Title Play, ");
473 if(user_ops
->time_or_chapter_search
)
474 printf("Time or Chapter Search, ");
475 if(user_ops
->prev_or_top_pg_search
)
476 printf("Prev or Top PG Search, ");
477 if(user_ops
->next_pg_search
)
478 printf("Next PG Search, ");
479 if(user_ops
->forward_scan
)
480 printf("Forward Scan, ");
481 if(user_ops
->backward_scan
)
482 printf("Backward Scan, ");
483 if(user_ops
->title_menu_call
)
484 printf("Title Menu Call, ");
485 if(user_ops
->root_menu_call
)
486 printf("Root Menu Call, ");
487 if(user_ops
->subpic_menu_call
)
488 printf("SubPic Menu Call, ");
489 if(user_ops
->audio_menu_call
)
490 printf("Audio Menu Call, ");
491 if(user_ops
->angle_menu_call
)
492 printf("Angle Menu Call, ");
493 if(user_ops
->chapter_menu_call
)
494 printf("Chapter Menu Call, ");
497 if(user_ops
->button_select_or_activate
)
498 printf("Button Select or Activate, ");
499 if(user_ops
->still_off
)
500 printf("Still Off, ");
501 if(user_ops
->pause_on
)
502 printf("Pause On, ");
503 if(user_ops
->audio_stream_change
)
504 printf("Audio Stream Change, ");
505 if(user_ops
->subpic_stream_change
)
506 printf("SubPic Stream Change, ");
507 if(user_ops
->angle_change
)
508 printf("Angle Change, ");
509 if(user_ops
->karaoke_audio_pres_mode_change
)
510 printf("Karaoke Audio Pres Mode Change, ");
511 if(user_ops
->video_pres_mode_change
)
512 printf("Video Pres Mode Change, ");
518 void ifoPrint_VMGI_MAT(vmgi_mat_t
*vmgi_mat
) {
520 printf("VMG Identifier: %.12s\n", vmgi_mat
->vmg_identifier
);
521 printf("Last Sector of VMG: %08x\n", vmgi_mat
->vmg_last_sector
);
522 printf("Last Sector of VMGI: %08x\n", vmgi_mat
->vmgi_last_sector
);
523 printf("Specification version number: %01x.%01x\n",
524 vmgi_mat
->specification_version
>> 4,
525 vmgi_mat
->specification_version
& 0xf);
526 /* Byte 2 of 'VMG Category' (00xx0000) is the Region Code */
527 printf("VMG Category: %08x\n", vmgi_mat
->vmg_category
);
528 printf("VMG Number of Volumes: %i\n", vmgi_mat
->vmg_nr_of_volumes
);
529 printf("VMG This Volume: %i\n", vmgi_mat
->vmg_this_volume_nr
);
530 printf("Disc side %i\n", vmgi_mat
->disc_side
);
531 printf("VMG Number of Title Sets %i\n", vmgi_mat
->vmg_nr_of_title_sets
);
532 printf("Provider ID: %.32s\n", vmgi_mat
->provider_identifier
);
533 printf("VMG POS Code: %08x", (uint32_t)(vmgi_mat
->vmg_pos_code
>> 32));
534 printf("%08x\n", (uint32_t)vmgi_mat
->vmg_pos_code
);
535 printf("End byte of VMGI_MAT: %08x\n", vmgi_mat
->vmgi_last_byte
);
536 printf("Start byte of First Play PGC FP PGC: %08x\n",
537 vmgi_mat
->first_play_pgc
);
538 printf("Start sector of VMGM_VOBS: %08x\n", vmgi_mat
->vmgm_vobs
);
539 printf("Start sector of TT_SRPT: %08x\n", vmgi_mat
->tt_srpt
);
540 printf("Start sector of VMGM_PGCI_UT: %08x\n", vmgi_mat
->vmgm_pgci_ut
);
541 printf("Start sector of PTL_MAIT: %08x\n", vmgi_mat
->ptl_mait
);
542 printf("Start sector of VTS_ATRT: %08x\n", vmgi_mat
->vts_atrt
);
543 printf("Start sector of TXTDT_MG: %08x\n", vmgi_mat
->txtdt_mgi
);
544 printf("Start sector of VMGM_C_ADT: %08x\n", vmgi_mat
->vmgm_c_adt
);
545 printf("Start sector of VMGM_VOBU_ADMAP: %08x\n",
546 vmgi_mat
->vmgm_vobu_admap
);
547 printf("Video attributes of VMGM_VOBS: ");
548 ifoPrint_video_attributes(&vmgi_mat
->vmgm_video_attr
);
550 printf("VMGM Number of Audio attributes: %i\n",
551 vmgi_mat
->nr_of_vmgm_audio_streams
);
552 if(vmgi_mat
->nr_of_vmgm_audio_streams
> 0) {
553 printf("\tstream %i status: ", 1);
554 ifoPrint_audio_attributes(&vmgi_mat
->vmgm_audio_attr
);
557 printf("VMGM Number of Sub-picture attributes: %i\n",
558 vmgi_mat
->nr_of_vmgm_subp_streams
);
559 if(vmgi_mat
->nr_of_vmgm_subp_streams
> 0) {
560 printf("\tstream %2i status: ", 1);
561 ifoPrint_subp_attributes(&vmgi_mat
->vmgm_subp_attr
);
567 void ifoPrint_VTSI_MAT(vtsi_mat_t
*vtsi_mat
) {
570 printf("VTS Identifier: %.12s\n", vtsi_mat
->vts_identifier
);
571 printf("Last Sector of VTS: %08x\n", vtsi_mat
->vts_last_sector
);
572 printf("Last Sector of VTSI: %08x\n", vtsi_mat
->vtsi_last_sector
);
573 printf("Specification version number: %01x.%01x\n",
574 vtsi_mat
->specification_version
>>4,
575 vtsi_mat
->specification_version
&0xf);
576 printf("VTS Category: %08x\n", vtsi_mat
->vts_category
);
577 printf("End byte of VTSI_MAT: %08x\n", vtsi_mat
->vtsi_last_byte
);
578 printf("Start sector of VTSM_VOBS: %08x\n", vtsi_mat
->vtsm_vobs
);
579 printf("Start sector of VTSTT_VOBS: %08x\n", vtsi_mat
->vtstt_vobs
);
580 printf("Start sector of VTS_PTT_SRPT: %08x\n", vtsi_mat
->vts_ptt_srpt
);
581 printf("Start sector of VTS_PGCIT: %08x\n", vtsi_mat
->vts_pgcit
);
582 printf("Start sector of VTSM_PGCI_UT: %08x\n", vtsi_mat
->vtsm_pgci_ut
);
583 printf("Start sector of VTS_TMAPT: %08x\n", vtsi_mat
->vts_tmapt
);
584 printf("Start sector of VTSM_C_ADT: %08x\n", vtsi_mat
->vtsm_c_adt
);
585 printf("Start sector of VTSM_VOBU_ADMAP: %08x\n",vtsi_mat
->vtsm_vobu_admap
);
586 printf("Start sector of VTS_C_ADT: %08x\n", vtsi_mat
->vts_c_adt
);
587 printf("Start sector of VTS_VOBU_ADMAP: %08x\n", vtsi_mat
->vts_vobu_admap
);
589 printf("Video attributes of VTSM_VOBS: ");
590 ifoPrint_video_attributes(&vtsi_mat
->vtsm_video_attr
);
593 printf("VTSM Number of Audio attributes: %i\n",
594 vtsi_mat
->nr_of_vtsm_audio_streams
);
595 if(vtsi_mat
->nr_of_vtsm_audio_streams
> 0) {
596 printf("\tstream %i status: ", 1);
597 ifoPrint_audio_attributes(&vtsi_mat
->vtsm_audio_attr
);
601 printf("VTSM Number of Sub-picture attributes: %i\n",
602 vtsi_mat
->nr_of_vtsm_subp_streams
);
603 if(vtsi_mat
->nr_of_vtsm_subp_streams
> 0) {
604 printf("\tstream %2i status: ", 1);
605 ifoPrint_subp_attributes(&vtsi_mat
->vtsm_subp_attr
);
609 printf("Video attributes of VTS_VOBS: ");
610 ifoPrint_video_attributes(&vtsi_mat
->vts_video_attr
);
613 printf("VTS Number of Audio attributes: %i\n",
614 vtsi_mat
->nr_of_vts_audio_streams
);
615 for(i
= 0; i
< vtsi_mat
->nr_of_vts_audio_streams
; i
++) {
616 printf("\tstream %i status: ", i
);
617 ifoPrint_audio_attributes(&vtsi_mat
->vts_audio_attr
[i
]);
621 printf("VTS Number of Subpicture attributes: %i\n",
622 vtsi_mat
->nr_of_vts_subp_streams
);
623 for(i
= 0; i
< vtsi_mat
->nr_of_vts_subp_streams
; i
++) {
624 printf("\tstream %2i status: ", i
);
625 ifoPrint_subp_attributes(&vtsi_mat
->vts_subp_attr
[i
]);
629 /* FIXME: Add printing of MultiChannel Extension */
633 static void ifoPrint_PGC_COMMAND_TBL(pgc_command_tbl_t
*cmd_tbl
) {
636 if(cmd_tbl
== NULL
) {
637 printf("No Command table present\n");
641 printf("Number of Pre commands: %i\n", cmd_tbl
->nr_of_pre
);
642 for(i
= 0; i
< cmd_tbl
->nr_of_pre
; i
++) {
643 ifoPrint_CMD(i
, &cmd_tbl
->pre_cmds
[i
]);
646 printf("Number of Post commands: %i\n", cmd_tbl
->nr_of_post
);
647 for(i
= 0; i
< cmd_tbl
->nr_of_post
; i
++) {
648 ifoPrint_CMD(i
, &cmd_tbl
->post_cmds
[i
]);
651 printf("Number of Cell commands: %i\n", cmd_tbl
->nr_of_cell
);
652 for(i
= 0; i
< cmd_tbl
->nr_of_cell
; i
++) {
653 ifoPrint_CMD(i
, &cmd_tbl
->cell_cmds
[i
]);
658 static void ifoPrint_PGC_PROGRAM_MAP(pgc_program_map_t
*program_map
, int nr
) {
661 if(program_map
== NULL
) {
662 printf("No Program map present\n");
666 for(i
= 0; i
< nr
; i
++) {
667 printf("Program %3i Entry Cell: %3i\n", i
+ 1, program_map
[i
]);
672 static void ifoPrint_CELL_PLAYBACK(cell_playback_t
*cell_playback
, int nr
) {
675 if(cell_playback
== NULL
) {
676 printf("No Cell Playback info present\n");
681 printf("Cell: %3i ", i
+ 1);
683 ifoPrint_time(&cell_playback
[i
].playback_time
);
686 if(cell_playback
[i
].block_mode
|| cell_playback
[i
].block_type
) {
688 switch(cell_playback
[i
].block_mode
) {
692 s
= "the first"; break;
699 printf("%s cell in the block ", s
);
701 switch(cell_playback
[i
].block_type
) {
703 printf("not part of the block ");
706 printf("angle block ");
710 printf("(send bug repport) ");
714 if(cell_playback
[i
].seamless_play
)
715 printf("presented seamlessly ");
716 if(cell_playback
[i
].interleaved
)
717 printf("cell is interleaved ");
718 if(cell_playback
[i
].stc_discontinuity
)
719 printf("STC_discontinuty ");
720 if(cell_playback
[i
].seamless_angle
)
721 printf("only seamless angle ");
722 if(cell_playback
[i
].restricted
)
723 printf("restricted cell ");
725 if(cell_playback
[i
].still_time
)
726 printf("still time %d ", cell_playback
[i
].still_time
);
727 if(cell_playback
[i
].cell_cmd_nr
)
728 printf("cell command %d", cell_playback
[i
].cell_cmd_nr
);
730 printf("\n\tStart sector: %08x\tFirst ILVU end sector: %08x\n",
731 cell_playback
[i
].first_sector
,
732 cell_playback
[i
].first_ilvu_end_sector
);
733 printf("\tEnd sector: %08x\tLast VOBU start sector: %08x\n",
734 cell_playback
[i
].last_sector
,
735 cell_playback
[i
].last_vobu_start_sector
);
739 static void ifoPrint_CELL_POSITION(cell_position_t
*cell_position
, int nr
) {
742 if(cell_position
== NULL
) {
743 printf("No Cell Position info present\n");
748 printf("Cell: %3i has VOB ID: %3i, Cell ID: %3i\n", i
+ 1,
749 cell_position
[i
].vob_id_nr
, cell_position
[i
].cell_nr
);
754 void ifoPrint_PGC(pgc_t
*pgc
) {
757 printf("Number of Programs: %i\n", pgc
->nr_of_programs
);
758 printf("Number of Cells: %i\n", pgc
->nr_of_cells
);
759 /* Check that time is 0:0:0:0 also if nr_of_programs==0 */
760 printf("Playback time: ");
761 ifoPrint_time(&pgc
->playback_time
); printf("\n");
763 /* If no programs/no time then does this mean anything? */
764 printf("Prohibited user operations: ");
765 ifoPrint_USER_OPS(&pgc
->prohibited_ops
);
767 for(i
= 0; i
< 8; i
++) {
768 if(pgc
->audio_control
[i
].present
) {
769 printf("Audio stream %i control: %04x\n",
770 i
, pgc
->audio_control
[i
]);
774 for(i
= 0; i
< 32; i
++) {
775 if(pgc
->subp_control
[i
].present
) {
776 printf("Subpicture stream %2i control: %08x\n",
777 i
, pgc
->subp_control
[i
]);
781 printf("Next PGC number: %i\n", pgc
->next_pgc_nr
);
782 printf("Prev PGC number: %i\n", pgc
->prev_pgc_nr
);
783 printf("GoUp PGC number: %i\n", pgc
->goup_pgc_nr
);
784 if(pgc
->nr_of_programs
!= 0) {
785 printf("Still time: %i seconds (255=inf)\n", pgc
->still_time
);
786 if(pgc
->pg_playback_mode
== 0)
787 printf("PG Playback mode: Sequential\n");
788 else if(!(pgc
->pg_playback_mode
& 0x80))
789 printf("PG Playback mode: Random %i\n", pgc
->pg_playback_mode
);
791 printf("PG Playback mode: Shuffle %i\n", pgc
->pg_playback_mode
& 0x7f );
794 if(pgc
->nr_of_programs
!= 0) {
795 for(i
= 0; i
< 16; i
++) {
796 printf("Color %2i: %08x\n", i
, pgc
->palette
[i
]);
800 /* Memmory offsets to div. tables. */
801 ifoPrint_PGC_COMMAND_TBL(pgc
->command_tbl
);
802 ifoPrint_PGC_PROGRAM_MAP(pgc
->program_map
, pgc
->nr_of_programs
);
803 ifoPrint_CELL_PLAYBACK(pgc
->cell_playback
, pgc
->nr_of_cells
);
804 ifoPrint_CELL_POSITION(pgc
->cell_position
, pgc
->nr_of_cells
);
808 void ifoPrint_TT_SRPT(tt_srpt_t
*tt_srpt
) {
811 printf("Number of TitleTrack search pointers: %i\n",
812 tt_srpt
->nr_of_srpts
);
813 for(i
=0;i
<tt_srpt
->nr_of_srpts
;i
++) {
814 printf("Title Track index %i\n", i
+ 1);
815 printf("\tTitle set number (VTS): %i",
816 tt_srpt
->title
[i
].title_set_nr
);
817 printf("\tVTS_TTN: %i\n", tt_srpt
->title
[i
].vts_ttn
);
818 printf("\tNumber of PTTs: %i\n", tt_srpt
->title
[i
].nr_of_ptts
);
819 printf("\tNumber of angles: %i\n",
820 tt_srpt
->title
[i
].nr_of_angles
);
821 printf("\tTitle playback type: %s%s%s%s%s%s%s\n",
822 tt_srpt
->title
[i
].pb_ty
.multi_or_random_pgc_title
?
823 " One Random PGC Title or Multi PGC Title" :
824 " One Sequential PGC Title",
825 tt_srpt
->title
[i
].pb_ty
.jlc_exists_in_cell_cmd
?
826 "" : ", No Link/Jump/Call exists in Cell command",
827 tt_srpt
->title
[i
].pb_ty
.jlc_exists_in_prepost_cmd
?
828 "" : ", No Link/Jump/Call exists in Pre- and/or Post-command",
829 tt_srpt
->title
[i
].pb_ty
.jlc_exists_in_button_cmd
?
830 "" : ", No Link/Jump/Call exists in Button command",
831 tt_srpt
->title
[i
].pb_ty
.jlc_exists_in_tt_dom
?
832 "" : ", No Link/Jump/Call exists in TT_DOM",
833 tt_srpt
->title
[i
].pb_ty
.chapter_search_or_play
?
834 ", UOP1 (TT_Play and PTT_Search) prohibited" : "",
835 tt_srpt
->title
[i
].pb_ty
.title_or_time_play
?
836 ", UOP0 (Time_Play and Time_Search) prohibited" : ""
838 printf("\tParental ID field: %04x\n",
839 tt_srpt
->title
[i
].parental_id
);
840 printf("\tTitle set starting sector %08x\n",
841 tt_srpt
->title
[i
].title_set_sector
);
846 void ifoPrint_VTS_PTT_SRPT(vts_ptt_srpt_t
*vts_ptt_srpt
) {
848 printf(" nr_of_srpts %i last byte %i\n",
849 vts_ptt_srpt
->nr_of_srpts
,
850 vts_ptt_srpt
->last_byte
);
851 for(i
=0;i
<vts_ptt_srpt
->nr_of_srpts
;i
++) {
852 printf("\nVTS_PTT number %d has a offset %d relative to VTS_PTT_SRPT\n",
853 i
+ 1, vts_ptt_srpt
->ttu_offset
[i
]);
854 for(j
=0;j
<vts_ptt_srpt
->title
[i
].nr_of_ptts
;j
++) {
855 printf("VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
857 vts_ptt_srpt
->title
[i
].ptt
[j
].pgcn
,
858 vts_ptt_srpt
->title
[i
].ptt
[j
].pgn
);
864 void ifoPrint_PTL_MAIT(ptl_mait_t
*ptl_mait
) {
867 printf("Number of Countries: %i\n", ptl_mait
->nr_of_countries
);
868 printf("Number of VTSs: %i\n", ptl_mait
->nr_of_vtss
);
869 printf("Last byte: %i\n", ptl_mait
->last_byte
);
871 for(i
= 0; i
< ptl_mait
->nr_of_countries
; i
++) {
873 printf("Start byte: %i\n", ptl_mait
->countries
[i
].pf_ptl_mai_start_byte
);
874 printf("Parental Masks for country: %c%c\n",
875 ptl_mait
->countries
[i
].country_code
>> 8,
876 ptl_mait
->countries
[i
].country_code
& 0xff);
878 for(vts
= 0; vts
<= ptl_mait
->nr_of_vtss
; vts
++) {
882 printf("VTS %2d ", vts
);
884 for(level
= 0; level
< 8; level
++) {
885 printf("%d: %04x ", level
,
886 ptl_mait
->countries
[i
].pf_ptl_mai
[vts
][level
] );
893 void ifoPrint_VTS_TMAPT(vts_tmapt_t
*vts_tmapt
) {
894 unsigned int timeunit
;
897 printf("Number of VTS_TMAPS: %i\n", vts_tmapt
->nr_of_tmaps
);
898 printf("Last byte: %i\n", vts_tmapt
->last_byte
);
900 for(i
= 0; i
< vts_tmapt
->nr_of_tmaps
; i
++) {
901 printf("TMAP %i\n", i
+ 1);
902 printf(" offset %d relative to VTS_TMAPTI\n", vts_tmapt
->tmap_offset
[i
]);
903 printf(" Time unit (seconds): %i\n", vts_tmapt
->tmap
[i
].tmu
);
904 printf(" Number of entries: %i\n", vts_tmapt
->tmap
[i
].nr_of_entries
);
905 timeunit
= vts_tmapt
->tmap
[i
].tmu
;
906 for(j
= 0; j
< vts_tmapt
->tmap
[i
].nr_of_entries
; j
++) {
907 unsigned int ac_time
= timeunit
* (j
+ 1);
908 printf("Time: %2i:%02i:%02i VOBU Sector: 0x%08x %s\n",
909 ac_time
/ (60 * 60), (ac_time
/ 60) % 60, ac_time
% 60,
910 vts_tmapt
->tmap
[i
].map_ent
[j
] & 0x7fffffff,
911 (vts_tmapt
->tmap
[i
].map_ent
[j
] >> 31) ? "discontinuity" : "");
916 void ifoPrint_C_ADT(c_adt_t
*c_adt
) {
919 printf("Number of VOBs in this VOBS: %i\n", c_adt
->nr_of_vobs
);
920 //entries = c_adt->nr_of_vobs;
921 entries
= (c_adt
->last_byte
+ 1 - C_ADT_SIZE
)/sizeof(c_adt_t
);
923 for(i
= 0; i
< entries
; i
++) {
924 printf("VOB ID: %3i, Cell ID: %3i ",
925 c_adt
->cell_adr_table
[i
].vob_id
, c_adt
->cell_adr_table
[i
].cell_id
);
926 printf("Sector (first): 0x%08x (last): 0x%08x\n",
927 c_adt
->cell_adr_table
[i
].start_sector
,
928 c_adt
->cell_adr_table
[i
].last_sector
);
933 void ifoPrint_VOBU_ADMAP(vobu_admap_t
*vobu_admap
) {
936 entries
= (vobu_admap
->last_byte
+ 1 - VOBU_ADMAP_SIZE
)/4;
937 for(i
= 0; i
< entries
; i
++) {
938 printf("VOBU %5i First sector: 0x%08x\n", i
+ 1,
939 vobu_admap
->vobu_start_sectors
[i
]);
944 void ifoPrint_PGCIT(pgcit_t
*pgcit
) {
947 for(i
= 0; i
< pgcit
->nr_of_pgci_srp
; i
++) {
948 printf("\nProgram (PGC): %3i\t", i
+ 1);
949 printf("PGC Category: Entry id 0x%02x, ", pgcit
->pgci_srp
[i
].entry_id
);
950 printf("Parental ID mask 0x%04x\n", pgcit
->pgci_srp
[i
].ptl_id_mask
);
951 ifoPrint_PGC(pgcit
->pgci_srp
[i
].pgc
);
956 void ifoPrint_PGCI_UT(pgci_ut_t
*pgci_ut
) {
959 printf("Number of Menu Language Units (PGCI_LU): %3i\n", pgci_ut
->nr_of_lus
);
960 for(i
= 0; i
< pgci_ut
->nr_of_lus
; i
++) {
961 printf("\nMenu Language Code: %c%c (%c)\n",
962 pgci_ut
->lu
[i
].lang_code
>> 8,
963 pgci_ut
->lu
[i
].lang_code
& 0xff,
964 pgci_ut
->lu
[i
].lang_extension
? pgci_ut
->lu
[i
].lang_extension
:' ');
965 printf("Menu Existence: %02x\n", pgci_ut
->lu
[i
].exists
);
966 ifoPrint_PGCIT(pgci_ut
->lu
[i
].pgcit
);
971 static void ifoPrint_VTS_ATTRIBUTES(vts_attributes_t
*vts_attributes
) {
974 printf("VTS_CAT Application type: %08x\n", vts_attributes
->vts_cat
);
976 printf("Video attributes of VTSM_VOBS: ");
977 ifoPrint_video_attributes(&vts_attributes
->vtsm_vobs_attr
);
979 printf("Number of Audio streams: %i\n",
980 vts_attributes
->nr_of_vtsm_audio_streams
);
981 if(vts_attributes
->nr_of_vtsm_audio_streams
> 0) {
982 printf("\tstream %i attributes: ", 1);
983 ifoPrint_audio_attributes(&vts_attributes
->vtsm_audio_attr
);
986 printf("Number of Subpicture streams: %i\n",
987 vts_attributes
->nr_of_vtsm_subp_streams
);
988 if(vts_attributes
->nr_of_vtsm_subp_streams
> 0) {
989 printf("\tstream %2i attributes: ", 1);
990 ifoPrint_subp_attributes(&vts_attributes
->vtsm_subp_attr
);
994 printf("Video attributes of VTSTT_VOBS: ");
995 ifoPrint_video_attributes(&vts_attributes
->vtstt_vobs_video_attr
);
997 printf("Number of Audio streams: %i\n",
998 vts_attributes
->nr_of_vtstt_audio_streams
);
999 for(i
= 0; i
< vts_attributes
->nr_of_vtstt_audio_streams
; i
++) {
1000 printf("\tstream %i attributes: ", i
);
1001 ifoPrint_audio_attributes(&vts_attributes
->vtstt_audio_attr
[i
]);
1005 printf("Number of Subpicture streams: %i\n",
1006 vts_attributes
->nr_of_vtstt_subp_streams
);
1007 for(i
= 0; i
< vts_attributes
->nr_of_vtstt_subp_streams
; i
++) {
1008 printf("\tstream %2i attributes: ", i
);
1009 ifoPrint_subp_attributes(&vts_attributes
->vtstt_subp_attr
[i
]);
1015 void ifoPrint_VTS_ATRT(vts_atrt_t
*vts_atrt
) {
1018 printf("Number of Video Title Sets: %3i\n", vts_atrt
->nr_of_vtss
);
1019 for(i
= 0; i
< vts_atrt
->nr_of_vtss
; i
++) {
1020 printf("\nVideo Title Set %i\n", i
+ 1);
1021 printf(" offset %d relative to VMG_VTS_ATRT\n",
1022 vts_atrt
->vts_atrt_offsets
[i
]);
1023 ifoPrint_VTS_ATTRIBUTES(&vts_atrt
->vts
[i
]);
1028 void ifoPrint(dvd_reader_t
*dvd
, int title
) {
1029 ifo_handle_t
*ifohandle
;
1031 ifohandle
= ifoOpen(dvd
, title
);
1033 fprintf(stderr
, "Can't open info file for title %d\n", title
);
1038 if(ifohandle
->vmgi_mat
) {
1040 printf("VMG top level\n-------------\n");
1041 ifoPrint_VMGI_MAT(ifohandle
->vmgi_mat
);
1043 printf("\nFirst Play PGC\n--------------\n");
1044 ifoPrint_PGC(ifohandle
->first_play_pgc
);
1046 printf("\nTitle Track search pointer table\n");
1047 printf( "------------------------------------------------\n");
1048 ifoPrint_TT_SRPT(ifohandle
->tt_srpt
);
1050 printf("\nMenu PGCI Unit table\n");
1051 printf( "--------------------\n");
1052 if(ifohandle
->pgci_ut
) {
1053 ifoPrint_PGCI_UT(ifohandle
->pgci_ut
);
1055 printf("No PGCI Unit table present\n");
1058 printf("\nParental Manegment Information table\n");
1059 printf( "------------------------------------\n");
1060 if(ifohandle
->ptl_mait
) {
1061 ifoPrint_PTL_MAIT(ifohandle
->ptl_mait
);
1063 printf("No Parental Management Information present\n");
1066 printf("\nVideo Title Set Attribute Table\n");
1067 printf( "-------------------------------\n");
1068 ifoPrint_VTS_ATRT(ifohandle
->vts_atrt
);
1070 printf("\nText Data Manager Information\n");
1071 printf( "-----------------------------\n");
1072 if(ifohandle
->txtdt_mgi
) {
1073 //ifoPrint_TXTDT_MGI(&(vmgi->txtdt_mgi));
1075 printf("No Text Data Manager Information present\n");
1078 printf("\nMenu Cell Adress table\n");
1079 printf( "-----------------\n");
1080 if(ifohandle
->menu_c_adt
) {
1081 ifoPrint_C_ADT(ifohandle
->menu_c_adt
);
1083 printf("No Menu Cell Adress table present\n");
1086 printf("\nVideo Manager Menu VOBU address map\n");
1087 printf( "-----------------\n");
1088 if(ifohandle
->menu_vobu_admap
) {
1089 ifoPrint_VOBU_ADMAP(ifohandle
->menu_vobu_admap
);
1091 printf("No Menu VOBU address map present\n");
1096 if(ifohandle
->vtsi_mat
) {
1098 printf("VTS top level\n-------------\n");
1099 ifoPrint_VTSI_MAT(ifohandle
->vtsi_mat
);
1101 printf("\nPart of Title Track search pointer table\n");
1102 printf( "----------------------------------------------\n");
1103 ifoPrint_VTS_PTT_SRPT(ifohandle
->vts_ptt_srpt
);
1105 printf("\nPGCI Unit table\n");
1106 printf( "--------------------\n");
1107 ifoPrint_PGCIT(ifohandle
->vts_pgcit
);
1109 printf("\nMenu PGCI Unit table\n");
1110 printf( "--------------------\n");
1111 if(ifohandle
->pgci_ut
) {
1112 ifoPrint_PGCI_UT(ifohandle
->pgci_ut
);
1114 printf("No Menu PGCI Unit table present\n");
1117 printf("\nTime Search table\n");
1118 printf( "-----------------\n");
1119 if(ifohandle
->vts_tmapt
) {
1120 ifoPrint_VTS_TMAPT(ifohandle
->vts_tmapt
);
1122 printf("No Time Search table present\n");
1125 printf("\nMenu Cell Adress table\n");
1126 printf( "-----------------\n");
1127 if(ifohandle
->menu_c_adt
) {
1128 ifoPrint_C_ADT(ifohandle
->menu_c_adt
);
1130 printf("No Cell Adress table present\n");
1133 printf("\nVideo Title Set Menu VOBU address map\n");
1134 printf( "-----------------\n");
1135 if(ifohandle
->menu_vobu_admap
) {
1136 ifoPrint_VOBU_ADMAP(ifohandle
->menu_vobu_admap
);
1138 printf("No Menu VOBU address map present\n");
1141 printf("\nCell Adress table\n");
1142 printf( "-----------------\n");
1143 ifoPrint_C_ADT(ifohandle
->vts_c_adt
);
1145 printf("\nVideo Title Set VOBU address map\n");
1146 printf( "-----------------\n");
1147 ifoPrint_VOBU_ADMAP(ifohandle
->vts_vobu_admap
);
1150 ifoClose(ifohandle
);