/* * Copyright (C) 2000, 2001, 2002 Björn Englund , * Håkan Hjort * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include //#include #include "config.h" // Needed for WORDS_BIGENDIAN #include "ifo_types.h" #include "ifo_read.h" #include "ifo_print.h" /* Put this in some other file / package? It's used in nav_print too. */ static void ifoPrint_time(int level, dvd_time_t *dtime) { const char *rate; assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa); assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa); assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa); assert((dtime->frame_u&0xf) < 0xa); printf("%02x:%02x:%02x.%02x", dtime->hour, dtime->minute, dtime->second, dtime->frame_u & 0x3f); switch((dtime->frame_u & 0xc0) >> 6) { case 1: rate = "25.00"; break; case 3: rate = "29.97"; break; default: if(dtime->hour == 0 && dtime->minute == 0 && dtime->second == 0 && dtime->frame_u == 0) rate = "no"; else rate = "(please send a bug report)"; break; } printf(" @ %s fps", rate); } /* Put this in some other file / package? It's used in nav_print too. Possibly also by the vm / navigator. */ static void ifoPrint_CMD(int row, vm_cmd_t *command) { int i; printf("(%03d) ", row + 1); for(i=0;i<8;i++) printf("%02x ", command->bytes[i]); printf("| "); //vmcmd(command); printf("\n"); } static void ifoPrint_video_attributes(int level, video_attr_t *attr) { /* The following test is shorter but not correct ISO C, memcmp(attr,my_friendly_zeros, sizeof(video_attr_t)) */ if(attr->mpeg_version == 0 && attr->video_format == 0 && attr->display_aspect_ratio == 0 && attr->permitted_df == 0 && attr->unknown1 == 0 && attr->line21_cc_1 == 0 && attr->line21_cc_2 == 0 && attr->video_format == 0 && attr->letterboxed == 0 && attr->film_mode == 0) { printf("-- Unspecified --"); return; } switch(attr->mpeg_version) { case 0: printf("mpeg1 "); break; case 1: printf("mpeg2 "); break; default: printf("(please send a bug report) "); } switch(attr->video_format) { case 0: printf("ntsc "); break; case 1: printf("pal "); break; default: printf("(please send a bug report) "); } switch(attr->display_aspect_ratio) { case 0: printf("4:3 "); break; case 3: printf("16:9 "); break; default: printf("(please send a bug report) "); } // Wide is allways allowed..!!! switch(attr->permitted_df) { case 0: printf("pan&scan+letterboxed "); break; case 1: printf("only pan&scan "); //?? break; case 2: printf("only letterboxed "); break; case 3: // not specified break; default: printf("(please send a bug report)"); } printf("U%x ", attr->unknown1); assert(!attr->unknown1); if(attr->line21_cc_1 || attr->line21_cc_2) { printf("NTSC CC "); if(attr->line21_cc_1) printf("1 "); if(attr->line21_cc_2) printf("2 "); } { int height = 480; if(attr->video_format != 0) height = 576; switch(attr->picture_size) { case 0: printf("720x%d ", height); break; case 1: printf("704x%d ", height); break; case 2: printf("352x%d ", height); break; case 3: printf("352x%d ", height/2); break; default: printf("(please send a bug report) "); } } if(attr->letterboxed) { printf("source letterboxed "); } if(attr->film_mode) { printf("film"); } else { printf("video"); //camera } } static void ifoPrint_audio_attributes(int level, audio_attr_t *attr) { if(attr->audio_format == 0 && attr->multichannel_extension == 0 && attr->lang_type == 0 && attr->application_mode == 0 && attr->quantization == 0 && attr->sample_frequency == 0 && attr->channels == 0 && attr->lang_extension == 0 && attr->unknown1 == 0 && attr->unknown1 == 0) { printf("-- Unspecified --"); return; } switch(attr->audio_format) { case 0: printf("ac3 "); break; case 1: printf("(please send a bug report) "); break; case 2: printf("mpeg1 "); break; case 3: printf("mpeg2ext "); break; case 4: printf("lpcm "); break; case 5: printf("(please send a bug report) "); break; case 6: printf("dts "); break; default: printf("(please send a bug report) "); } if(attr->multichannel_extension) printf("multichannel_extension "); switch(attr->lang_type) { case 0: // not specified assert(attr->lang_code == 0 || attr->lang_code == 0xffff); break; case 1: printf("%c%c ", attr->lang_code>>8, attr->lang_code & 0xff); break; default: printf("(please send a bug report) "); } switch(attr->application_mode) { case 0: // not specified break; case 1: printf("karaoke mode "); break; case 2: printf("surround sound mode "); break; default: printf("(please send a bug report) "); } switch(attr->quantization) { case 0: printf("16bit "); break; case 1: printf("20bit "); break; case 2: printf("24bit "); break; case 3: printf("drc "); break; default: printf("(please send a bug report) "); } switch(attr->sample_frequency) { case 0: printf("48kHz "); break; case 1: printf("??kHz "); break; default: printf("sample_frequency %i (please send a bug report) ", attr->sample_frequency); } printf("%dCh ", attr->channels + 1); switch(attr->lang_extension) { case 0: printf("Not specified "); break; case 1: // Normal audio printf("Normal Caption "); break; case 2: // visually imparied printf("Audio for visually impaired "); break; case 3: // Directors 1 printf("Director's comments 1 "); break; case 4: // Directors 2 printf("Director's comments 2 "); break; //case 4: // Music score ? default: printf("(please send a bug report) "); } printf("%d ", attr->unknown1); printf("%d ", attr->unknown2); } static void ifoPrint_subp_attributes(int level, subp_attr_t *attr) { if(attr->type == 0 && attr->lang_code == 0 && attr->zero1 == 0 && attr->zero2 == 0 && attr->lang_extension== 0) { printf("-- Unspecified --"); return; } printf("type %02x ", attr->type); if(isalpha((int)(attr->lang_code >> 8)) && isalpha((int)(attr->lang_code & 0xff))) { printf("%c%c ", attr->lang_code >> 8, attr->lang_code & 0xff); } else { printf("%02x%02x ", 0xff & (unsigned)(attr->lang_code >> 8), 0xff & (unsigned)(attr->lang_code & 0xff)); } printf("%d ", attr->zero1); printf("%d ", attr->zero2); switch(attr->lang_extension) { case 0: printf("Not specified "); break; case 1: printf("Caption with normal size character "); break; case 2: printf("Caption with bigger size character "); break; case 3: printf("Caption for children "); break; case 4: printf("reserved "); break; case 5: printf("Closed Caption with normal size character "); break; case 6: printf("Closed Caption with bigger size character "); break; case 7: printf("Closed Caption for children "); break; case 8: printf("reserved "); break; case 9: printf("Forced Caption"); break; case 10: printf("reserved "); break; case 11: printf("reserved "); break; case 12: printf("reserved "); break; case 13: printf("Director's comments with normal size character "); break; case 14: printf("Director's comments with bigger size character "); break; case 15: printf("Director's comments for children "); break; default: printf("(please send a bug report) "); } } static void ifoPrint_USER_OPS(user_ops_t *user_ops) { uint32_t uops; unsigned char *ptr = (unsigned char *)user_ops; uops = (*ptr++ << 24); uops |= (*ptr++ << 16); uops |= (*ptr++ << 8); uops |= (*ptr++); if(uops == 0) { printf("None\n"); } else if(uops == 0x01ffffff) { printf("All\n"); } else { if(user_ops->title_or_time_play) printf("Title or Time Play, "); if(user_ops->chapter_search_or_play) printf("Chapter Search or Play, "); if(user_ops->title_play) printf("Title Play, "); if(user_ops->stop) printf("Stop, "); if(user_ops->go_up) printf("Go Up, "); if(user_ops->time_or_chapter_search) printf("Time or Chapter Search, "); if(user_ops->prev_or_top_pg_search) printf("Prev or Top PG Search, "); if(user_ops->next_pg_search) printf("Next PG Search, "); if(user_ops->forward_scan) printf("Forward Scan, "); if(user_ops->backward_scan) printf("Backward Scan, "); if(user_ops->title_menu_call) printf("Title Menu Call, "); if(user_ops->root_menu_call) printf("Root Menu Call, "); if(user_ops->subpic_menu_call) printf("SubPic Menu Call, "); if(user_ops->audio_menu_call) printf("Audio Menu Call, "); if(user_ops->angle_menu_call) printf("Angle Menu Call, "); if(user_ops->chapter_menu_call) printf("Chapter Menu Call, "); if(user_ops->resume) printf("Resume, "); if(user_ops->button_select_or_activate) printf("Button Select or Activate, "); if(user_ops->still_off) printf("Still Off, "); if(user_ops->pause_on) printf("Pause On, "); if(user_ops->audio_stream_change) printf("Audio Stream Change, "); if(user_ops->subpic_stream_change) printf("SubPic Stream Change, "); if(user_ops->angle_change) printf("Angle Change, "); if(user_ops->karaoke_audio_pres_mode_change) printf("Karaoke Audio Pres Mode Change, "); if(user_ops->video_pres_mode_change) printf("Video Pres Mode Change, "); printf("\n"); } } void ifoPrint_VMGI_MAT(vmgi_mat_t *vmgi_mat) { printf("VMG Identifier: %.12s\n", vmgi_mat->vmg_identifier); printf("Last Sector of VMG: %08x\n", vmgi_mat->vmg_last_sector); printf("Last Sector of VMGI: %08x\n", vmgi_mat->vmgi_last_sector); printf("Specification version number: %01x.%01x\n", vmgi_mat->specification_version >> 4, vmgi_mat->specification_version & 0xf); /* Byte 2 of 'VMG Category' (00xx0000) is the Region Code */ printf("VMG Category: %08x\n", vmgi_mat->vmg_category); printf("VMG Number of Volumes: %i\n", vmgi_mat->vmg_nr_of_volumes); printf("VMG This Volume: %i\n", vmgi_mat->vmg_this_volume_nr); printf("Disc side %i\n", vmgi_mat->disc_side); printf("VMG Number of Title Sets %i\n", vmgi_mat->vmg_nr_of_title_sets); printf("Provider ID: %.32s\n", vmgi_mat->provider_identifier); printf("VMG POS Code: %08x", (uint32_t)(vmgi_mat->vmg_pos_code >> 32)); printf("%08x\n", (uint32_t)vmgi_mat->vmg_pos_code); printf("End byte of VMGI_MAT: %08x\n", vmgi_mat->vmgi_last_byte); printf("Start byte of First Play PGC FP PGC: %08x\n", vmgi_mat->first_play_pgc); printf("Start sector of VMGM_VOBS: %08x\n", vmgi_mat->vmgm_vobs); printf("Start sector of TT_SRPT: %08x\n", vmgi_mat->tt_srpt); printf("Start sector of VMGM_PGCI_UT: %08x\n", vmgi_mat->vmgm_pgci_ut); printf("Start sector of PTL_MAIT: %08x\n", vmgi_mat->ptl_mait); printf("Start sector of VTS_ATRT: %08x\n", vmgi_mat->vts_atrt); printf("Start sector of TXTDT_MG: %08x\n", vmgi_mat->txtdt_mgi); printf("Start sector of VMGM_C_ADT: %08x\n", vmgi_mat->vmgm_c_adt); printf("Start sector of VMGM_VOBU_ADMAP: %08x\n", vmgi_mat->vmgm_vobu_admap); printf("Video attributes of VMGM_VOBS: "); ifoPrint_video_attributes(5, &vmgi_mat->vmgm_video_attr); printf("\n"); printf("VMGM Number of Audio attributes: %i\n", vmgi_mat->nr_of_vmgm_audio_streams); if(vmgi_mat->nr_of_vmgm_audio_streams > 0) { printf("\tstream %i status: ", 1); ifoPrint_audio_attributes(5, &vmgi_mat->vmgm_audio_attr); printf("\n"); } printf("VMGM Number of Sub-picture attributes: %i\n", vmgi_mat->nr_of_vmgm_subp_streams); if(vmgi_mat->nr_of_vmgm_subp_streams > 0) { printf("\tstream %2i status: ", 1); ifoPrint_subp_attributes(5, &vmgi_mat->vmgm_subp_attr); printf("\n"); } } void ifoPrint_VTSI_MAT(vtsi_mat_t *vtsi_mat) { int i; printf("VTS Identifier: %.12s\n", vtsi_mat->vts_identifier); printf("Last Sector of VTS: %08x\n", vtsi_mat->vts_last_sector); printf("Last Sector of VTSI: %08x\n", vtsi_mat->vtsi_last_sector); printf("Specification version number: %01x.%01x\n", vtsi_mat->specification_version>>4, vtsi_mat->specification_version&0xf); printf("VTS Category: %08x\n", vtsi_mat->vts_category); printf("End byte of VTSI_MAT: %08x\n", vtsi_mat->vtsi_last_byte); printf("Start sector of VTSM_VOBS: %08x\n", vtsi_mat->vtsm_vobs); printf("Start sector of VTSTT_VOBS: %08x\n", vtsi_mat->vtstt_vobs); printf("Start sector of VTS_PTT_SRPT: %08x\n", vtsi_mat->vts_ptt_srpt); printf("Start sector of VTS_PGCIT: %08x\n", vtsi_mat->vts_pgcit); printf("Start sector of VTSM_PGCI_UT: %08x\n", vtsi_mat->vtsm_pgci_ut); printf("Start sector of VTS_TMAPT: %08x\n", vtsi_mat->vts_tmapt); printf("Start sector of VTSM_C_ADT: %08x\n", vtsi_mat->vtsm_c_adt); printf("Start sector of VTSM_VOBU_ADMAP: %08x\n",vtsi_mat->vtsm_vobu_admap); printf("Start sector of VTS_C_ADT: %08x\n", vtsi_mat->vts_c_adt); printf("Start sector of VTS_VOBU_ADMAP: %08x\n", vtsi_mat->vts_vobu_admap); printf("Video attributes of VTSM_VOBS: "); ifoPrint_video_attributes(5, &vtsi_mat->vtsm_video_attr); printf("\n"); printf("VTSM Number of Audio attributes: %i\n", vtsi_mat->nr_of_vtsm_audio_streams); if(vtsi_mat->nr_of_vtsm_audio_streams > 0) { printf("\tstream %i status: ", 1); ifoPrint_audio_attributes(5, &vtsi_mat->vtsm_audio_attr); printf("\n"); } printf("VTSM Number of Sub-picture attributes: %i\n", vtsi_mat->nr_of_vtsm_subp_streams); if(vtsi_mat->nr_of_vtsm_subp_streams > 0) { printf("\tstream %2i status: ", 1); ifoPrint_subp_attributes(5, &vtsi_mat->vtsm_subp_attr); printf("\n"); } printf("Video attributes of VTS_VOBS: "); ifoPrint_video_attributes(5, &vtsi_mat->vts_video_attr); printf("\n"); printf("VTS Number of Audio attributes: %i\n", vtsi_mat->nr_of_vts_audio_streams); for(i = 0; i < vtsi_mat->nr_of_vts_audio_streams; i++) { printf("\tstream %i status: ", i); ifoPrint_audio_attributes(5, &vtsi_mat->vts_audio_attr[i]); printf("\n"); } printf("VTS Number of Subpicture attributes: %i\n", vtsi_mat->nr_of_vts_subp_streams); for(i = 0; i < vtsi_mat->nr_of_vts_subp_streams; i++) { printf("\tstream %2i status: ", i); ifoPrint_subp_attributes(5, &vtsi_mat->vts_subp_attr[i]); printf("\n"); } } static void ifoPrint_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl) { int i; if(cmd_tbl == NULL) { printf("No Command table present\n"); return; } printf("Number of Pre commands: %i\n", cmd_tbl->nr_of_pre); for(i = 0; i < cmd_tbl->nr_of_pre; i++) { ifoPrint_CMD(i, &cmd_tbl->pre_cmds[i]); } printf("Number of Post commands: %i\n", cmd_tbl->nr_of_post); for(i = 0; i < cmd_tbl->nr_of_post; i++) { ifoPrint_CMD(i, &cmd_tbl->post_cmds[i]); } printf("Number of Cell commands: %i\n", cmd_tbl->nr_of_cell); for(i = 0; i < cmd_tbl->nr_of_cell; i++) { ifoPrint_CMD(i, &cmd_tbl->cell_cmds[i]); } } static void ifoPrint_PGC_PROGRAM_MAP(pgc_program_map_t *program_map, int nr) { int i; if(program_map == NULL) { printf("No Program map present\n"); return; } for(i = 0; i < nr; i++) { printf("Program %3i Entry Cell: %3i\n", i + 1, program_map[i]); } } static void ifoPrint_CELL_PLAYBACK(cell_playback_t *cell_playback, int nr) { int i; if(cell_playback == NULL) { printf("No Cell Playback info present\n"); return; } for(i=0;inr_of_programs); printf("Number of Cells: %i\n", pgc->nr_of_cells); /* Check that time is 0:0:0:0 also if nr_of_programs==0 */ printf("Playback time: "); ifoPrint_time(5, &pgc->playback_time); printf("\n"); /* If no programs/no time then does this mean anything? */ printf("Prohibited user operations: "); ifoPrint_USER_OPS(&pgc->prohibited_ops); for(i = 0; i < 8; i++) { if(pgc->audio_control[i] & 0x8000) { /* The 'is present' bit */ printf("Audio stream %i control: %04x\n", i, pgc->audio_control[i]); } } for(i = 0; i < 32; i++) { if(pgc->subp_control[i] & 0x80000000) { /* The 'is present' bit */ printf("Subpicture stream %2i control: %08x\n", i, pgc->subp_control[i]); } } printf("Next PGC number: %i\n", pgc->next_pgc_nr); printf("Prev PGC number: %i\n", pgc->prev_pgc_nr); printf("GoUp PGC number: %i\n", pgc->goup_pgc_nr); if(pgc->nr_of_programs != 0) { printf("Still time: %i seconds (255=inf)\n", pgc->still_time); printf("PG Playback mode %02x\n", pgc->pg_playback_mode); } if(pgc->nr_of_programs != 0) { for(i = 0; i < 16; i++) { printf("Color %2i: %08x\n", i, pgc->palette[i]); } } /* Memmory offsets to div. tables. */ ifoPrint_PGC_COMMAND_TBL(pgc->command_tbl); ifoPrint_PGC_PROGRAM_MAP(pgc->program_map, pgc->nr_of_programs); ifoPrint_CELL_PLAYBACK(pgc->cell_playback, pgc->nr_of_cells); ifoPrint_CELL_POSITION(pgc->cell_position, pgc->nr_of_cells); } void ifoPrint_TT_SRPT(tt_srpt_t *tt_srpt) { int i; printf("Number of TitleTrack search pointers: %i\n", tt_srpt->nr_of_srpts); for(i=0;inr_of_srpts;i++) { printf("Title Track index %i\n", i + 1); printf("\tTitle set number (VTS): %i", tt_srpt->title[i].title_set_nr); printf("\tVTS_TTN: %i\n", tt_srpt->title[i].vts_ttn); printf("\tNumber of PTTs: %i\n", tt_srpt->title[i].nr_of_ptts); printf("\tNumber of angles: %i\n", tt_srpt->title[i].nr_of_angles); printf("\tTitle playback type: %02x\n", /* XXX: TODO FIXME */ *(uint8_t *)&(tt_srpt->title[i].pb_ty)); printf("\tParental ID field: %04x\n", tt_srpt->title[i].parental_id); printf("\tTitle set starting sector %08x\n", tt_srpt->title[i].title_set_sector); } } void ifoPrint_VTS_PTT_SRPT(vts_ptt_srpt_t *vts_ptt_srpt) { int i, j; printf(" nr_of_srpts %i last byte %i\n", vts_ptt_srpt->nr_of_srpts, vts_ptt_srpt->last_byte); for(i=0;inr_of_srpts;i++) { for(j=0;jtitle[i].nr_of_ptts;j++) { printf("VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n", i + 1, j + 1, vts_ptt_srpt->title[i].ptt[j].pgcn, vts_ptt_srpt->title[i].ptt[j].pgn ); } } } static void hexdump(uint8_t *ptr, int len) { while(len--) printf("%02x ", *ptr++); } void ifoPrint_PTL_MAIT(ptl_mait_t *ptl_mait) { int i, j; printf("Number of Countries: %i\n", ptl_mait->nr_of_countries); printf("Number of VTSs: %i\n", ptl_mait->nr_of_vtss); //printf("Last byte: %i\n", ptl_mait->last_byte); for(i = 0; i < ptl_mait->nr_of_countries; i++) { printf("Country code: %c%c\n", ptl_mait->countries[i].country_code >> 8, ptl_mait->countries[i].country_code & 0xff); /* printf("Start byte: %04x %i\n", ptl_mait->countries[i].pf_ptl_mai_start_byte, ptl_mait->countries[i].pf_ptl_mai_start_byte); */ /* This seems to be pointing at a array with 8 2byte fields per VTS ? and one extra for the menu? always an odd number of VTSs on all the dics I tested so it might be padding to even also. If it is for the menu it probably the first entry. */ for(j=0;j<8;j++) { hexdump( (uint8_t *)ptl_mait->countries - PTL_MAIT_COUNTRY_SIZE + ptl_mait->countries[i].pf_ptl_mai_start_byte + j*(ptl_mait->nr_of_vtss+1)*2, (ptl_mait->nr_of_vtss+1)*2); printf("\n"); } } } void ifoPrint_C_ADT(c_adt_t *c_adt) { int i, entries; printf("Number of VOBs in this VOBS: %i\n", c_adt->nr_of_vobs); //entries = c_adt->nr_of_vobs; entries = (c_adt->last_byte + 1 - C_ADT_SIZE)/sizeof(c_adt_t); for(i = 0; i < entries; i++) { printf("VOB ID: %3i, Cell ID: %3i ", c_adt->cell_adr_table[i].vob_id, c_adt->cell_adr_table[i].cell_id); printf("Sector (first): 0x%08x (last): 0x%08x\n", c_adt->cell_adr_table[i].start_sector, c_adt->cell_adr_table[i].last_sector); } } void ifoPrint_VOBU_ADMAP(vobu_admap_t *vobu_admap) { int i, entries; entries = (vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE)/4; for(i = 0; i < entries; i++) { printf("VOBU %5i First sector: 0x%08x\n", i + 1, vobu_admap->vobu_start_sectors[i]); } } void ifoPrint_PGCIT(pgcit_t *pgcit) { int i; for(i = 0; i < pgcit->nr_of_pgci_srp; i++) { printf("\nProgram (PGC): %3i\t", i + 1); printf("PGC Category: Entry id 0x%02x, ", pgcit->pgci_srp[i].entry_id); printf("Parental ID mask 0x%04x\n", pgcit->pgci_srp[i].ptl_id_mask); ifoPrint_PGC(pgcit->pgci_srp[i].pgc); } } void ifoPrint_PGCI_UT(pgci_ut_t *pgci_ut) { int i; printf("Number of Menu Language Units (PGCI_LU): %3i\n", pgci_ut->nr_of_lus); for(i = 0; i < pgci_ut->nr_of_lus; i++) { printf("\nMenu Language Code: %c%c\n", pgci_ut->lu[i].lang_code >> 8, pgci_ut->lu[i].lang_code & 0xff); printf("Menu Existence: %02x\n", pgci_ut->lu[i].exists); ifoPrint_PGCIT(pgci_ut->lu[i].pgcit); } } static void ifoPrint_VTS_ATTRIBUTES(vts_attributes_t *vts_attributes) { int i; printf("VTS_CAT Application type: %08x\n", vts_attributes->vts_cat); printf("Video attributes of VTSM_VOBS: "); ifoPrint_video_attributes(5, &vts_attributes->vtsm_vobs_attr); printf("\n"); printf("Number of Audio streams: %i\n", vts_attributes->nr_of_vtsm_audio_streams); if(vts_attributes->nr_of_vtsm_audio_streams > 0) { printf("\tstream %i attributes: ", 1); ifoPrint_audio_attributes(5, &vts_attributes->vtsm_audio_attr); printf("\n"); } printf("Number of Subpicture streams: %i\n", vts_attributes->nr_of_vtsm_subp_streams); if(vts_attributes->nr_of_vtsm_subp_streams > 0) { printf("\tstream %2i attributes: ", 1); ifoPrint_subp_attributes(5, &vts_attributes->vtsm_subp_attr); printf("\n"); } printf("Video attributes of VTSTT_VOBS: "); ifoPrint_video_attributes(5, &vts_attributes->vtstt_vobs_video_attr); printf("\n"); printf("Number of Audio streams: %i\n", vts_attributes->nr_of_vtstt_audio_streams); for(i = 0; i < vts_attributes->nr_of_vtstt_audio_streams; i++) { printf("\tstream %i attributes: ", i); ifoPrint_audio_attributes(5, &vts_attributes->vtstt_audio_attr[i]); printf("\n"); } printf("Number of Subpicture streams: %i\n", vts_attributes->nr_of_vtstt_subp_streams); for(i = 0; i < vts_attributes->nr_of_vtstt_subp_streams; i++) { printf("\tstream %2i attributes: ", i); ifoPrint_subp_attributes(5, &vts_attributes->vtstt_subp_attr[i]); printf("\n"); } } void ifoPrint_VTS_ATRT(vts_atrt_t *vts_atrt) { int i; printf("Number of Video Title Sets: %3i\n", vts_atrt->nr_of_vtss); for(i = 0; i < vts_atrt->nr_of_vtss; i++) { printf("\nVideo Title Set %i\n", i + 1); ifoPrint_VTS_ATTRIBUTES(&vts_atrt->vts[i]); } } void ifoPrint(dvd_reader_t *dvd, int title) { ifo_handle_t *ifohandle; ifohandle = ifoOpen(dvd, title); if(!ifohandle) { fprintf(stderr, "Can't open info file for title %d\n", title); return; } if(ifohandle->vmgi_mat) { printf("VMG top level\n-------------\n"); ifoPrint_VMGI_MAT(ifohandle->vmgi_mat); printf("\nFirst Play PGC\n--------------\n"); ifoPrint_PGC(ifohandle->first_play_pgc); printf("\nTitle Track search pointer table\n"); printf( "------------------------------------------------\n"); ifoPrint_TT_SRPT(ifohandle->tt_srpt); printf("\nMenu PGCI Unit table\n"); printf( "--------------------\n"); if(ifohandle->pgci_ut) { ifoPrint_PGCI_UT(ifohandle->pgci_ut); } else { printf("No PGCI Unit table present\n"); } printf("\nParental Manegment Information table\n"); printf( "------------------------------------\n"); if(ifohandle->ptl_mait) { ifoPrint_PTL_MAIT(ifohandle->ptl_mait); } else { printf("No Parental Management Information present\n"); } printf("\nVideo Title Set Attribute Table\n"); printf( "-------------------------------\n"); ifoPrint_VTS_ATRT(ifohandle->vts_atrt); printf("\nText Data Manager Information\n"); printf( "-----------------------------\n"); if(ifohandle->txtdt_mgi) { //ifoPrint_TXTDT_MGI(&(vmgi->txtdt_mgi)); } else { printf("No Text Data Manager Information present\n"); } printf("\nMenu Cell Adress table\n"); printf( "-----------------\n"); if(ifohandle->menu_c_adt) { ifoPrint_C_ADT(ifohandle->menu_c_adt); } else { printf("No Menu Cell Adress table present\n"); } printf("\nVideo Manager Menu VOBU address map\n"); printf( "-----------------\n"); if(ifohandle->menu_vobu_admap) { ifoPrint_VOBU_ADMAP(ifohandle->menu_vobu_admap); } else { printf("No Menu VOBU address map present\n"); } } if(ifohandle->vtsi_mat) { printf("VTS top level\n-------------\n"); ifoPrint_VTSI_MAT(ifohandle->vtsi_mat); printf("\nPart of Title Track search pointer table\n"); printf( "----------------------------------------------\n"); ifoPrint_VTS_PTT_SRPT(ifohandle->vts_ptt_srpt); printf("\nPGCI Unit table\n"); printf( "--------------------\n"); ifoPrint_PGCIT(ifohandle->vts_pgcit); printf("\nMenu PGCI Unit table\n"); printf( "--------------------\n"); if(ifohandle->pgci_ut) { ifoPrint_PGCI_UT(ifohandle->pgci_ut); } else { printf("No Menu PGCI Unit table present\n"); } printf("\nMenu Cell Adress table\n"); printf( "-----------------\n"); if(ifohandle->menu_c_adt) { ifoPrint_C_ADT(ifohandle->menu_c_adt); } else { printf("No Cell Adress table present\n"); } printf("\nVideo Title Set Menu VOBU address map\n"); printf( "-----------------\n"); if(ifohandle->menu_vobu_admap) { ifoPrint_VOBU_ADMAP(ifohandle->menu_vobu_admap); } else { printf("No Menu VOBU address map present\n"); } printf("\nCell Adress table\n"); printf( "-----------------\n"); ifoPrint_C_ADT(ifohandle->vts_c_adt); printf("\nVideo Title Set VOBU address map\n"); printf( "-----------------\n"); ifoPrint_VOBU_ADMAP(ifohandle->vts_vobu_admap); } ifoClose(ifohandle); }