|
MythTV
0.26-pre
|
00001 /* 00002 * This file is part of libdvdread. 00003 * 00004 * libdvdread is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * libdvdread is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with libdvdread; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00017 */ 00018 00019 #include <stdio.h> 00020 #include <stdlib.h> 00021 #include <unistd.h> 00022 #include <inttypes.h> 00023 #include <string.h> 00024 #include <ctype.h> 00025 #include <assert.h> 00026 00027 #include "dvdread/ifo_types.h" 00028 #include "dvdread/ifo_read.h" 00029 #include "dvdread/ifo_print.h" 00030 00031 /* Put this in some other file / package? It's used in nav_print too. */ 00032 static void ifo_print_time(int level, dvd_time_t *dtime) { 00033 const char *rate; 00034 assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa); 00035 assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa); 00036 assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa); 00037 assert((dtime->frame_u&0xf) < 0xa); 00038 00039 printf("%02x:%02x:%02x.%02x", 00040 dtime->hour, 00041 dtime->minute, 00042 dtime->second, 00043 dtime->frame_u & 0x3f); 00044 switch((dtime->frame_u & 0xc0) >> 6) { 00045 case 1: 00046 rate = "25.00"; 00047 break; 00048 case 3: 00049 rate = "29.97"; 00050 break; 00051 default: 00052 if(dtime->hour == 0 && dtime->minute == 0 00053 && dtime->second == 0 && dtime->frame_u == 0) 00054 rate = "no"; 00055 else 00056 rate = "(please send a bug report)"; 00057 break; 00058 } 00059 printf(" @ %s fps", rate); 00060 } 00061 00062 void dvdread_print_time(dvd_time_t *dtime) { 00063 ifo_print_time(5, dtime); 00064 } 00065 00066 /* Put this in some other file / package? It's used in nav_print too. 00067 Possibly also by the vm / navigator. */ 00068 static void ifo_print_cmd(int row, vm_cmd_t *command) { 00069 int i; 00070 00071 printf("(%03d) ", row + 1); 00072 for(i=0;i<8;i++) 00073 printf("%02x ", command->bytes[i]); 00074 printf("| "); 00075 #if 0 00076 //disabled call of dvdnav function 00077 vm_print_mnemonic(command); 00078 #endif 00079 printf("\n"); 00080 } 00081 00082 static void ifo_print_video_attributes(int level, video_attr_t *attr) { 00083 00084 /* The following test is shorter but not correct ISO C, 00085 memcmp(attr,my_friendly_zeros, sizeof(video_attr_t)) */ 00086 if(attr->mpeg_version == 0 00087 && attr->video_format == 0 00088 && attr->display_aspect_ratio == 0 00089 && attr->permitted_df == 0 00090 && attr->unknown1 == 0 00091 && attr->line21_cc_1 == 0 00092 && attr->line21_cc_2 == 0 00093 && attr->video_format == 0 00094 && attr->letterboxed == 0 00095 && attr->film_mode == 0) { 00096 printf("-- Unspecified --"); 00097 return; 00098 } 00099 00100 switch(attr->mpeg_version) { 00101 case 0: 00102 printf("mpeg1, "); 00103 break; 00104 case 1: 00105 printf("mpeg2, "); 00106 break; 00107 default: 00108 printf("(please send a bug report), "); 00109 } 00110 00111 switch(attr->video_format) { 00112 case 0: 00113 printf("ntsc, "); 00114 break; 00115 case 1: 00116 printf("pal, "); 00117 break; 00118 default: 00119 printf("(please send a bug report), "); 00120 } 00121 00122 switch(attr->display_aspect_ratio) { 00123 case 0: 00124 printf("4:3, "); 00125 break; 00126 case 3: 00127 printf("16:9, "); 00128 break; 00129 default: 00130 printf("(please send a bug report), "); 00131 } 00132 00133 // Wide is always allowed..!!! 00134 switch(attr->permitted_df) { 00135 case 0: 00136 printf("pan&scan+letterboxed, "); 00137 break; 00138 case 1: 00139 printf("only pan&scan, "); //?? 00140 break; 00141 case 2: 00142 printf("only letterboxed, "); 00143 break; 00144 case 3: 00145 printf("not specified, "); 00146 break; 00147 default: 00148 printf("(please send a bug report), "); 00149 } 00150 00151 printf("U%x, ", attr->unknown1); 00152 assert(!attr->unknown1); 00153 00154 if(attr->line21_cc_1 || attr->line21_cc_2) { 00155 printf("NTSC CC "); 00156 if(attr->line21_cc_1) 00157 printf("1, "); 00158 if(attr->line21_cc_2) 00159 printf("2, "); 00160 } 00161 00162 { 00163 int height = 480; 00164 if(attr->video_format != 0) 00165 height = 576; 00166 switch(attr->picture_size) { 00167 case 0: 00168 printf("720x%d, ", height); 00169 break; 00170 case 1: 00171 printf("704x%d, ", height); 00172 break; 00173 case 2: 00174 printf("352x%d, ", height); 00175 break; 00176 case 3: 00177 printf("352x%d, ", height/2); 00178 break; 00179 default: 00180 printf("(please send a bug report), "); 00181 } 00182 } 00183 00184 if(attr->letterboxed) { 00185 printf("source letterboxed, "); 00186 } 00187 00188 if(attr->film_mode) { 00189 printf("film. "); 00190 } else { 00191 printf("video. "); //camera 00192 } 00193 } 00194 00195 static void ifo_print_audio_attributes(int level, audio_attr_t *attr) { 00196 00197 if(attr->audio_format == 0 00198 && attr->multichannel_extension == 0 00199 && attr->lang_type == 0 00200 && attr->application_mode == 0 00201 && attr->quantization == 0 00202 && attr->sample_frequency == 0 00203 && attr->channels == 0 00204 && attr->lang_extension == 0 00205 && attr->unknown1 == 0 00206 && attr->unknown3 == 0) { 00207 printf("-- Unspecified --"); 00208 return; 00209 } 00210 00211 switch(attr->audio_format) { 00212 case 0: 00213 printf("ac3 "); 00214 if(attr->quantization != 3) 00215 printf("(please send a bug report) ac3 quant/drc not 3 (%d)", attr->quantization); 00216 break; 00217 case 1: 00218 printf("(please send a bug report) "); 00219 break; 00220 case 2: 00221 printf("mpeg1 "); 00222 case 3: 00223 printf("mpeg2ext "); 00224 switch(attr->quantization) { 00225 case 0: 00226 printf("no drc "); 00227 break; 00228 case 1: 00229 printf("drc "); 00230 break; 00231 default: 00232 printf("(please send a bug report) mpeg reserved quant/drc (%d)", attr->quantization); 00233 } 00234 break; 00235 case 4: 00236 printf("lpcm "); 00237 switch(attr->quantization) { 00238 case 0: 00239 printf("16bit "); 00240 break; 00241 case 1: 00242 printf("20bit "); 00243 break; 00244 case 2: 00245 printf("24bit "); 00246 break; 00247 case 3: 00248 printf("(please send a bug report) lpcm reserved quant/drc (%d)", attr->quantization); 00249 break; 00250 } 00251 break; 00252 case 5: 00253 printf("(please send a bug report) "); 00254 break; 00255 case 6: 00256 printf("dts "); 00257 if(attr->quantization != 3) 00258 printf("(please send a bug report) dts quant/drc not 3 (%d)", attr->quantization); 00259 break; 00260 default: 00261 printf("(please send a bug report) "); 00262 } 00263 00264 if(attr->multichannel_extension) 00265 printf("multichannel_extension "); 00266 00267 switch(attr->lang_type) { 00268 case 0: 00269 // not specified 00270 assert(attr->lang_code == 0 || attr->lang_code == 0xffff); 00271 break; 00272 case 1: 00273 printf("%c%c ", attr->lang_code>>8, attr->lang_code & 0xff); 00274 break; 00275 default: 00276 printf("(please send a bug report) "); 00277 } 00278 00279 switch(attr->application_mode) { 00280 case 0: 00281 // not specified 00282 break; 00283 case 1: 00284 printf("karaoke mode "); 00285 break; 00286 case 2: 00287 printf("surround sound mode "); 00288 break; 00289 default: 00290 printf("(please send a bug report) "); 00291 } 00292 00293 switch(attr->quantization) { 00294 case 0: 00295 printf("16bit "); 00296 break; 00297 case 1: 00298 printf("20bit "); 00299 break; 00300 case 2: 00301 printf("24bit "); 00302 break; 00303 case 3: 00304 printf("drc "); 00305 break; 00306 default: 00307 printf("(please send a bug report) "); 00308 } 00309 00310 switch(attr->sample_frequency) { 00311 case 0: 00312 printf("48kHz "); 00313 break; 00314 case 1: 00315 printf("??kHz "); 00316 break; 00317 default: 00318 printf("sample_frequency %i (please send a bug report) ", 00319 attr->sample_frequency); 00320 } 00321 00322 printf("%dCh ", attr->channels + 1); 00323 00324 switch(attr->lang_extension) { 00325 case 0: 00326 printf("Not specified "); 00327 break; 00328 case 1: // Normal audio 00329 printf("Normal Caption "); 00330 break; 00331 case 2: // visually impaired 00332 printf("Audio for visually impaired "); 00333 break; 00334 case 3: // Directors 1 00335 printf("Director's comments 1 "); 00336 break; 00337 case 4: // Directors 2 00338 printf("Director's comments 2 "); 00339 break; 00340 //case 4: // Music score ? 00341 default: 00342 printf("(please send a bug report) "); 00343 } 00344 00345 printf("%d ", attr->unknown1); 00346 printf("%d ", attr->unknown3); 00347 } 00348 00349 static void ifo_print_subp_attributes(int level, subp_attr_t *attr) { 00350 00351 if(attr->type == 0 00352 && attr->lang_code == 0 00353 && attr->zero1 == 0 00354 && attr->zero2 == 0 00355 && attr->lang_extension== 0) { 00356 printf("-- Unspecified --"); 00357 return; 00358 } 00359 00360 printf("type %02x ", attr->type); 00361 00362 if(isalpha((int)(attr->lang_code >> 8)) 00363 && isalpha((int)(attr->lang_code & 0xff))) { 00364 printf("%c%c ", attr->lang_code >> 8, attr->lang_code & 0xff); 00365 } else { 00366 printf("%02x%02x ", 0xff & (unsigned)(attr->lang_code >> 8), 00367 0xff & (unsigned)(attr->lang_code & 0xff)); 00368 } 00369 00370 printf("%d ", attr->zero1); 00371 printf("%d ", attr->zero2); 00372 00373 switch(attr->lang_extension) { 00374 case 0: 00375 printf("Not specified "); 00376 break; 00377 case 1: 00378 printf("Caption with normal size character "); 00379 break; 00380 case 2: 00381 printf("Caption with bigger size character "); 00382 break; 00383 case 3: 00384 printf("Caption for children "); 00385 break; 00386 case 4: 00387 printf("reserved "); 00388 break; 00389 case 5: 00390 printf("Closed Caption with normal size character "); 00391 break; 00392 case 6: 00393 printf("Closed Caption with bigger size character "); 00394 break; 00395 case 7: 00396 printf("Closed Caption for children "); 00397 break; 00398 case 8: 00399 printf("reserved "); 00400 break; 00401 case 9: 00402 printf("Forced Caption"); 00403 break; 00404 case 10: 00405 printf("reserved "); 00406 break; 00407 case 11: 00408 printf("reserved "); 00409 break; 00410 case 12: 00411 printf("reserved "); 00412 break; 00413 case 13: 00414 printf("Director's comments with normal size character "); 00415 break; 00416 case 14: 00417 printf("Director's comments with bigger size character "); 00418 break; 00419 case 15: 00420 printf("Director's comments for children "); 00421 break; 00422 default: 00423 printf("(please send a bug report) "); 00424 } 00425 00426 } 00427 00428 00429 static void ifoPrint_USER_OPS(user_ops_t *user_ops) { 00430 uint32_t uops; 00431 unsigned char *ptr = (unsigned char *)user_ops; 00432 00433 uops = (*ptr++ << 24); 00434 uops |= (*ptr++ << 16); 00435 uops |= (*ptr++ << 8); 00436 uops |= (*ptr++); 00437 00438 if(uops == 0) { 00439 printf("None\n"); 00440 } else if(uops == 0x01ffffff) { 00441 printf("All\n"); 00442 } else { 00443 if(user_ops->title_or_time_play) 00444 printf("Title or Time Play, "); 00445 if(user_ops->chapter_search_or_play) 00446 printf("Chapter Search or Play, "); 00447 if(user_ops->title_play) 00448 printf("Title Play, "); 00449 if(user_ops->stop) 00450 printf("Stop, "); 00451 if(user_ops->go_up) 00452 printf("Go Up, "); 00453 if(user_ops->time_or_chapter_search) 00454 printf("Time or Chapter Search, "); 00455 if(user_ops->prev_or_top_pg_search) 00456 printf("Prev or Top PG Search, "); 00457 if(user_ops->next_pg_search) 00458 printf("Next PG Search, "); 00459 if(user_ops->forward_scan) 00460 printf("Forward Scan, "); 00461 if(user_ops->backward_scan) 00462 printf("Backward Scan, "); 00463 if(user_ops->title_menu_call) 00464 printf("Title Menu Call, "); 00465 if(user_ops->root_menu_call) 00466 printf("Root Menu Call, "); 00467 if(user_ops->subpic_menu_call) 00468 printf("SubPic Menu Call, "); 00469 if(user_ops->audio_menu_call) 00470 printf("Audio Menu Call, "); 00471 if(user_ops->angle_menu_call) 00472 printf("Angle Menu Call, "); 00473 if(user_ops->chapter_menu_call) 00474 printf("Chapter Menu Call, "); 00475 if(user_ops->resume) 00476 printf("Resume, "); 00477 if(user_ops->button_select_or_activate) 00478 printf("Button Select or Activate, "); 00479 if(user_ops->still_off) 00480 printf("Still Off, "); 00481 if(user_ops->pause_on) 00482 printf("Pause On, "); 00483 if(user_ops->audio_stream_change) 00484 printf("Audio Stream Change, "); 00485 if(user_ops->subpic_stream_change) 00486 printf("SubPic Stream Change, "); 00487 if(user_ops->angle_change) 00488 printf("Angle Change, "); 00489 if(user_ops->karaoke_audio_pres_mode_change) 00490 printf("Karaoke Audio Pres Mode Change, "); 00491 if(user_ops->video_pres_mode_change) 00492 printf("Video Pres Mode Change, "); 00493 printf("\n"); 00494 } 00495 } 00496 00497 00498 static void ifoPrint_VMGI_MAT(vmgi_mat_t *vmgi_mat) { 00499 00500 printf("VMG Identifier: %.12s\n", vmgi_mat->vmg_identifier); 00501 printf("Last Sector of VMG: %08x\n", vmgi_mat->vmg_last_sector); 00502 printf("Last Sector of VMGI: %08x\n", vmgi_mat->vmgi_last_sector); 00503 printf("Specification version number: %01x.%01x\n", 00504 vmgi_mat->specification_version >> 4, 00505 vmgi_mat->specification_version & 0xf); 00506 /* Byte 2 of 'VMG Category' (00xx0000) is the Region Code */ 00507 printf("VMG Category: %08x (Region Code=%02x)\n", vmgi_mat->vmg_category, ((vmgi_mat->vmg_category >> 16) & 0xff) ^0xff); 00508 printf("VMG Number of Volumes: %i\n", vmgi_mat->vmg_nr_of_volumes); 00509 printf("VMG This Volume: %i\n", vmgi_mat->vmg_this_volume_nr); 00510 printf("Disc side %i\n", vmgi_mat->disc_side); 00511 printf("VMG Number of Title Sets %i\n", vmgi_mat->vmg_nr_of_title_sets); 00512 printf("Provider ID: %.32s\n", vmgi_mat->provider_identifier); 00513 printf("VMG POS Code: %08x", (uint32_t)(vmgi_mat->vmg_pos_code >> 32)); 00514 printf("%08x\n", (uint32_t)vmgi_mat->vmg_pos_code); 00515 printf("End byte of VMGI_MAT: %08x\n", vmgi_mat->vmgi_last_byte); 00516 printf("Start byte of First Play PGC (FP PGC): %08x\n", 00517 vmgi_mat->first_play_pgc); 00518 printf("Start sector of VMGM_VOBS: %08x\n", vmgi_mat->vmgm_vobs); 00519 printf("Start sector of TT_SRPT: %08x\n", vmgi_mat->tt_srpt); 00520 printf("Start sector of VMGM_PGCI_UT: %08x\n", vmgi_mat->vmgm_pgci_ut); 00521 printf("Start sector of PTL_MAIT: %08x\n", vmgi_mat->ptl_mait); 00522 printf("Start sector of VTS_ATRT: %08x\n", vmgi_mat->vts_atrt); 00523 printf("Start sector of TXTDT_MG: %08x\n", vmgi_mat->txtdt_mgi); 00524 printf("Start sector of VMGM_C_ADT: %08x\n", vmgi_mat->vmgm_c_adt); 00525 printf("Start sector of VMGM_VOBU_ADMAP: %08x\n", 00526 vmgi_mat->vmgm_vobu_admap); 00527 printf("Video attributes of VMGM_VOBS: "); 00528 ifo_print_video_attributes(5, &vmgi_mat->vmgm_video_attr); 00529 printf("\n"); 00530 printf("VMGM Number of Audio attributes: %i\n", 00531 vmgi_mat->nr_of_vmgm_audio_streams); 00532 if(vmgi_mat->nr_of_vmgm_audio_streams > 0) { 00533 printf("\tstream %i status: ", 1); 00534 ifo_print_audio_attributes(5, &vmgi_mat->vmgm_audio_attr); 00535 printf("\n"); 00536 } 00537 printf("VMGM Number of Sub-picture attributes: %i\n", 00538 vmgi_mat->nr_of_vmgm_subp_streams); 00539 if(vmgi_mat->nr_of_vmgm_subp_streams > 0) { 00540 printf("\tstream %2i status: ", 1); 00541 ifo_print_subp_attributes(5, &vmgi_mat->vmgm_subp_attr); 00542 printf("\n"); 00543 } 00544 } 00545 00546 00547 static void ifoPrint_VTSI_MAT(vtsi_mat_t *vtsi_mat) { 00548 int i; 00549 00550 printf("VTS Identifier: %.12s\n", vtsi_mat->vts_identifier); 00551 printf("Last Sector of VTS: %08x\n", vtsi_mat->vts_last_sector); 00552 printf("Last Sector of VTSI: %08x\n", vtsi_mat->vtsi_last_sector); 00553 printf("Specification version number: %01x.%01x\n", 00554 vtsi_mat->specification_version>>4, 00555 vtsi_mat->specification_version&0xf); 00556 printf("VTS Category: %08x\n", vtsi_mat->vts_category); 00557 printf("End byte of VTSI_MAT: %08x\n", vtsi_mat->vtsi_last_byte); 00558 printf("Start sector of VTSM_VOBS: %08x\n", vtsi_mat->vtsm_vobs); 00559 printf("Start sector of VTSTT_VOBS: %08x\n", vtsi_mat->vtstt_vobs); 00560 printf("Start sector of VTS_PTT_SRPT: %08x\n", vtsi_mat->vts_ptt_srpt); 00561 printf("Start sector of VTS_PGCIT: %08x\n", vtsi_mat->vts_pgcit); 00562 printf("Start sector of VTSM_PGCI_UT: %08x\n", vtsi_mat->vtsm_pgci_ut); 00563 printf("Start sector of VTS_TMAPT: %08x\n", vtsi_mat->vts_tmapt); 00564 printf("Start sector of VTSM_C_ADT: %08x\n", vtsi_mat->vtsm_c_adt); 00565 printf("Start sector of VTSM_VOBU_ADMAP: %08x\n",vtsi_mat->vtsm_vobu_admap); 00566 printf("Start sector of VTS_C_ADT: %08x\n", vtsi_mat->vts_c_adt); 00567 printf("Start sector of VTS_VOBU_ADMAP: %08x\n", vtsi_mat->vts_vobu_admap); 00568 00569 printf("Video attributes of VTSM_VOBS: "); 00570 ifo_print_video_attributes(5, &vtsi_mat->vtsm_video_attr); 00571 printf("\n"); 00572 00573 printf("VTSM Number of Audio attributes: %i\n", 00574 vtsi_mat->nr_of_vtsm_audio_streams); 00575 if(vtsi_mat->nr_of_vtsm_audio_streams > 0) { 00576 printf("\tstream %i status: ", 1); 00577 ifo_print_audio_attributes(5, &vtsi_mat->vtsm_audio_attr); 00578 printf("\n"); 00579 } 00580 00581 printf("VTSM Number of Sub-picture attributes: %i\n", 00582 vtsi_mat->nr_of_vtsm_subp_streams); 00583 if(vtsi_mat->nr_of_vtsm_subp_streams > 0) { 00584 printf("\tstream %2i status: ", 1); 00585 ifo_print_subp_attributes(5, &vtsi_mat->vtsm_subp_attr); 00586 printf("\n"); 00587 } 00588 00589 printf("Video attributes of VTS_VOBS: "); 00590 ifo_print_video_attributes(5, &vtsi_mat->vts_video_attr); 00591 printf("\n"); 00592 00593 printf("VTS Number of Audio attributes: %i\n", 00594 vtsi_mat->nr_of_vts_audio_streams); 00595 for(i = 0; i < vtsi_mat->nr_of_vts_audio_streams; i++) { 00596 printf("\tstream %i status: ", i); 00597 ifo_print_audio_attributes(5, &vtsi_mat->vts_audio_attr[i]); 00598 printf("\n"); 00599 } 00600 00601 printf("VTS Number of Subpicture attributes: %i\n", 00602 vtsi_mat->nr_of_vts_subp_streams); 00603 for(i = 0; i < vtsi_mat->nr_of_vts_subp_streams; i++) { 00604 printf("\tstream %2i status: ", i); 00605 ifo_print_subp_attributes(5, &vtsi_mat->vts_subp_attr[i]); 00606 printf("\n"); 00607 } 00608 } 00609 00610 00611 static void ifoPrint_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl) { 00612 int i; 00613 00614 if(cmd_tbl == NULL) { 00615 printf("No Command table present\n"); 00616 return; 00617 } 00618 00619 printf("Number of Pre commands: %i\n", cmd_tbl->nr_of_pre); 00620 for(i = 0; i < cmd_tbl->nr_of_pre; i++) { 00621 ifo_print_cmd(i, &cmd_tbl->pre_cmds[i]); 00622 } 00623 00624 printf("Number of Post commands: %i\n", cmd_tbl->nr_of_post); 00625 for(i = 0; i < cmd_tbl->nr_of_post; i++) { 00626 ifo_print_cmd(i, &cmd_tbl->post_cmds[i]); 00627 } 00628 00629 printf("Number of Cell commands: %i\n", cmd_tbl->nr_of_cell); 00630 for(i = 0; i < cmd_tbl->nr_of_cell; i++) { 00631 ifo_print_cmd(i, &cmd_tbl->cell_cmds[i]); 00632 } 00633 } 00634 00635 00636 static void ifoPrint_PGC_PROGRAM_MAP(pgc_program_map_t *program_map, int nr) { 00637 int i; 00638 00639 if(program_map == NULL) { 00640 printf("No Program map present\n"); 00641 return; 00642 } 00643 00644 for(i = 0; i < nr; i++) { 00645 printf("Program %3i Entry Cell: %3i\n", i + 1, program_map[i]); 00646 } 00647 } 00648 00649 00650 static void ifoPrint_CELL_PLAYBACK(cell_playback_t *cell_playback, int nr) { 00651 int i; 00652 00653 if(cell_playback == NULL) { 00654 printf("No Cell Playback info present\n"); 00655 return; 00656 } 00657 00658 for(i=0;i<nr;i++) { 00659 printf("Cell: %3i ", i + 1); 00660 00661 dvdread_print_time(&cell_playback[i].playback_time); 00662 printf("\t"); 00663 00664 if(cell_playback[i].block_mode || cell_playback[i].block_type) { 00665 const char *s; 00666 switch(cell_playback[i].block_mode) { 00667 case 0: 00668 s = "not a"; break; 00669 case 1: 00670 s = "the first"; break; 00671 case 2: 00672 default: 00673 s = ""; break; 00674 case 3: 00675 s = "last"; break; 00676 } 00677 printf("%s cell in the block ", s); 00678 00679 switch(cell_playback[i].block_type) { 00680 case 0: 00681 printf("not part of the block "); 00682 break; 00683 case 1: 00684 printf("angle block "); 00685 break; 00686 case 2: 00687 case 3: 00688 printf("(send bug report) "); 00689 break; 00690 } 00691 } 00692 if(cell_playback[i].seamless_play) 00693 printf("presented seamlessly "); 00694 if(cell_playback[i].interleaved) 00695 printf("cell is interleaved "); 00696 if(cell_playback[i].stc_discontinuity) 00697 printf("STC_discontinuty "); 00698 if(cell_playback[i].seamless_angle) 00699 printf("only seamless angle "); 00700 if(cell_playback[i].playback_mode) 00701 printf("only still VOBUs "); 00702 if(cell_playback[i].restricted) 00703 printf("restricted cell "); 00704 if(cell_playback[i].unknown2) 00705 printf("Unknown 0x%x ", cell_playback[i].unknown2); 00706 if(cell_playback[i].still_time) 00707 printf("still time %d ", cell_playback[i].still_time); 00708 if(cell_playback[i].cell_cmd_nr) 00709 printf("cell command %d", cell_playback[i].cell_cmd_nr); 00710 00711 printf("\n\tStart sector: %08x\tFirst ILVU end sector: %08x\n", 00712 cell_playback[i].first_sector, 00713 cell_playback[i].first_ilvu_end_sector); 00714 printf("\tEnd sector: %08x\tLast VOBU start sector: %08x\n", 00715 cell_playback[i].last_sector, 00716 cell_playback[i].last_vobu_start_sector); 00717 } 00718 } 00719 00720 static void ifoPrint_CELL_POSITION(cell_position_t *cell_position, int nr) { 00721 int i; 00722 00723 if(cell_position == NULL) { 00724 printf("No Cell Position info present\n"); 00725 return; 00726 } 00727 00728 for(i=0;i<nr;i++) { 00729 printf("Cell: %3i has VOB ID: %3i, Cell ID: %3i\n", i + 1, 00730 cell_position[i].vob_id_nr, cell_position[i].cell_nr); 00731 } 00732 } 00733 00734 00735 static void ifoPrint_PGC(pgc_t *pgc) { 00736 int i; 00737 00738 if (!pgc) { 00739 printf("None\n"); 00740 return; 00741 } 00742 printf("Number of Programs: %i\n", pgc->nr_of_programs); 00743 printf("Number of Cells: %i\n", pgc->nr_of_cells); 00744 /* Check that time is 0:0:0:0 also if nr_of_programs==0 */ 00745 printf("Playback time: "); 00746 dvdread_print_time(&pgc->playback_time); printf("\n"); 00747 00748 /* If no programs/no time then does this mean anything? */ 00749 printf("Prohibited user operations: "); 00750 ifoPrint_USER_OPS(&pgc->prohibited_ops); 00751 00752 for(i = 0; i < 8; i++) { 00753 if(pgc->audio_control[i] & 0x8000) { /* The 'is present' bit */ 00754 printf("Audio stream %i control: %04x\n", 00755 i, pgc->audio_control[i]); 00756 } 00757 } 00758 00759 for(i = 0; i < 32; i++) { 00760 if(pgc->subp_control[i] & 0x80000000) { /* The 'is present' bit */ 00761 printf("Subpicture stream %2i control: %08x: 4:3=%d, Wide=%d, Letterbox=%d, Pan-Scan=%d\n", 00762 i, pgc->subp_control[i], 00763 (pgc->subp_control[i] >>24) & 0x1f, 00764 (pgc->subp_control[i] >>16) & 0x1f, 00765 (pgc->subp_control[i] >>8) & 0x1f, 00766 (pgc->subp_control[i] ) & 0x1f); 00767 } 00768 } 00769 00770 printf("Next PGC number: %i\n", pgc->next_pgc_nr); 00771 printf("Prev PGC number: %i\n", pgc->prev_pgc_nr); 00772 printf("GoUp PGC number: %i\n", pgc->goup_pgc_nr); 00773 if(pgc->nr_of_programs != 0) { 00774 printf("Still time: %i seconds (255=inf)\n", pgc->still_time); 00775 printf("PG Playback mode %02x\n", pgc->pg_playback_mode); 00776 } 00777 00778 if(pgc->nr_of_programs != 0) { 00779 for(i = 0; i < 16; i++) { 00780 printf("Color %2i: %08x\n", i, pgc->palette[i]); 00781 } 00782 } 00783 00784 /* Memory offsets to div. tables. */ 00785 ifoPrint_PGC_COMMAND_TBL(pgc->command_tbl); 00786 ifoPrint_PGC_PROGRAM_MAP(pgc->program_map, pgc->nr_of_programs); 00787 ifoPrint_CELL_PLAYBACK(pgc->cell_playback, pgc->nr_of_cells); 00788 ifoPrint_CELL_POSITION(pgc->cell_position, pgc->nr_of_cells); 00789 } 00790 00791 00792 static void ifoPrint_TT_SRPT(tt_srpt_t *tt_srpt) { 00793 int i; 00794 00795 printf("Number of TitleTrack search pointers: %i\n", 00796 tt_srpt->nr_of_srpts); 00797 for(i=0;i<tt_srpt->nr_of_srpts;i++) { 00798 printf("Title Track index %i\n", i + 1); 00799 printf("\tTitle set number (VTS): %i", 00800 tt_srpt->title[i].title_set_nr); 00801 printf("\tVTS_TTN: %i\n", tt_srpt->title[i].vts_ttn); 00802 printf("\tNumber of PTTs: %i\n", tt_srpt->title[i].nr_of_ptts); 00803 printf("\tNumber of angles: %i\n", 00804 tt_srpt->title[i].nr_of_angles); 00805 00806 printf("\tTitle playback type: (%02x)\n", 00807 *(uint8_t *)&(tt_srpt->title[i].pb_ty)); 00808 printf("\t\t%s\n", 00809 tt_srpt->title[i].pb_ty.multi_or_random_pgc_title ? "Random or Shuffle" : "Sequential"); 00810 if (tt_srpt->title[i].pb_ty.jlc_exists_in_cell_cmd) printf("\t\tJump/Link/Call exists in cell cmd\n"); 00811 if (tt_srpt->title[i].pb_ty.jlc_exists_in_prepost_cmd) printf("\t\tJump/Link/Call exists in pre/post cmd\n"); 00812 if (tt_srpt->title[i].pb_ty.jlc_exists_in_button_cmd) printf("\t\tJump/Link/Call exists in button cmd\n"); 00813 if (tt_srpt->title[i].pb_ty.jlc_exists_in_tt_dom) printf("\t\tJump/Link/Call exists in tt_dom cmd\n"); 00814 printf("\t\tTitle or time play:%d\n", tt_srpt->title[i].pb_ty.title_or_time_play); 00815 printf("\t\tChapter search or play:%d\n", tt_srpt->title[i].pb_ty.chapter_search_or_play); 00816 00817 printf("\tParental ID field: %04x\n", 00818 tt_srpt->title[i].parental_id); 00819 printf("\tTitle set starting sector %08x\n", 00820 tt_srpt->title[i].title_set_sector); 00821 } 00822 } 00823 00824 00825 static void ifoPrint_VTS_PTT_SRPT(vts_ptt_srpt_t *vts_ptt_srpt) { 00826 int i, j; 00827 printf(" nr_of_srpts %i last byte %i\n", 00828 vts_ptt_srpt->nr_of_srpts, 00829 vts_ptt_srpt->last_byte); 00830 for(i=0;i<vts_ptt_srpt->nr_of_srpts;i++) { 00831 for(j=0;j<vts_ptt_srpt->title[i].nr_of_ptts;j++) { 00832 printf("VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n", 00833 i + 1, j + 1, 00834 vts_ptt_srpt->title[i].ptt[j].pgcn, 00835 vts_ptt_srpt->title[i].ptt[j].pgn ); 00836 } 00837 } 00838 } 00839 00840 00841 static void hexdump(uint8_t *ptr, int len) { 00842 while(len--) 00843 printf("%02x ", *ptr++); 00844 } 00845 00846 static void ifoPrint_PTL_MAIT(ptl_mait_t *ptl_mait) { 00847 int i, j; 00848 00849 printf("Number of Countries: %i\n", ptl_mait->nr_of_countries); 00850 printf("Number of VTSs: %i\n", ptl_mait->nr_of_vtss); 00851 //printf("Last byte: %i\n", ptl_mait->last_byte); 00852 00853 for(i = 0; i < ptl_mait->nr_of_countries; i++) { 00854 printf("Country code: %c%c\n", 00855 ptl_mait->countries[i].country_code >> 8, 00856 ptl_mait->countries[i].country_code & 0xff); 00857 /* 00858 printf("Start byte: %04x %i\n", 00859 ptl_mait->countries[i].pf_ptl_mai_start_byte, 00860 ptl_mait->countries[i].pf_ptl_mai_start_byte); 00861 */ 00862 /* This seems to be pointing at a array with 8 2byte fields per VTS 00863 ? and one extra for the menu? always an odd number of VTSs on 00864 all the dics I tested so it might be padding to even also. 00865 If it is for the menu it probably the first entry. */ 00866 for(j=0;j<8;j++) { 00867 hexdump( (uint8_t *)ptl_mait->countries - PTL_MAIT_COUNTRY_SIZE 00868 + ptl_mait->countries[i].pf_ptl_mai_start_byte 00869 + j*(ptl_mait->nr_of_vtss+1)*2, (ptl_mait->nr_of_vtss+1)*2); 00870 printf("\n"); 00871 } 00872 } 00873 } 00874 00875 static void ifoPrint_VTS_TMAPT(vts_tmapt_t *vts_tmapt) { 00876 unsigned int timeunit; 00877 int i, j; 00878 00879 printf("Number of VTS_TMAPS: %i\n", vts_tmapt->nr_of_tmaps); 00880 printf("Last byte: %i\n", vts_tmapt->last_byte); 00881 00882 for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) { 00883 printf("TMAP %i (number matches title PGC number.)\n", i + 1); 00884 printf(" offset %d relative to VTS_TMAPTI\n", vts_tmapt->tmap_offset[i]); 00885 printf(" Time unit (seconds): %i\n", vts_tmapt->tmap[i].tmu); 00886 printf(" Number of entries: %i\n", vts_tmapt->tmap[i].nr_of_entries); 00887 timeunit = vts_tmapt->tmap[i].tmu; 00888 for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) { 00889 unsigned int ac_time = timeunit * (j + 1); 00890 printf("Time: %2i:%02i:%02i VOBU Sector: 0x%08x %s\n", 00891 ac_time / (60 * 60), (ac_time / 60) % 60, ac_time % 60, 00892 vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff, 00893 (vts_tmapt->tmap[i].map_ent[j] >> 31) ? "discontinuity" : ""); 00894 } 00895 } 00896 } 00897 00898 static void ifoPrint_C_ADT(c_adt_t *c_adt) { 00899 int i, entries; 00900 00901 printf("Number of VOBs in this VOBS: %i\n", c_adt->nr_of_vobs); 00902 //entries = c_adt->nr_of_vobs; 00903 entries = (c_adt->last_byte + 1 - C_ADT_SIZE)/sizeof(c_adt_t); 00904 00905 for(i = 0; i < entries; i++) { 00906 printf("VOB ID: %3i, Cell ID: %3i ", 00907 c_adt->cell_adr_table[i].vob_id, c_adt->cell_adr_table[i].cell_id); 00908 printf("Sector (first): 0x%08x (last): 0x%08x\n", 00909 c_adt->cell_adr_table[i].start_sector, 00910 c_adt->cell_adr_table[i].last_sector); 00911 } 00912 } 00913 00914 00915 static void ifoPrint_VOBU_ADMAP(vobu_admap_t *vobu_admap) { 00916 int i, entries; 00917 00918 entries = (vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE)/4; 00919 for(i = 0; i < entries; i++) { 00920 printf("VOBU %5i First sector: 0x%08x\n", i + 1, 00921 vobu_admap->vobu_start_sectors[i]); 00922 } 00923 } 00924 00925 static const char *ifo_print_menu_name(int type) { 00926 const char *menu_name; 00927 menu_name=""; 00928 switch (type) { 00929 case 2: 00930 menu_name="Title"; 00931 break; 00932 case 3: 00933 menu_name = "Root"; 00934 break; 00935 case 4: 00936 menu_name = "Sub-Picture"; 00937 break; 00938 case 5: 00939 menu_name = "Audio"; 00940 break; 00941 case 6: 00942 menu_name = "Angle"; 00943 break; 00944 case 7: 00945 menu_name = "PTT (Chapter)"; 00946 break; 00947 default: 00948 menu_name = "Unknown"; 00949 break; 00950 } 00951 return &menu_name[0]; 00952 } 00953 00954 /* pgc_type=1 for menu, 0 for title. */ 00955 static void ifoPrint_PGCIT(pgcit_t *pgcit, int pgc_type) { 00956 int i; 00957 00958 printf("\nNumber of Program Chains: %3i\n", pgcit->nr_of_pgci_srp); 00959 for(i = 0; i < pgcit->nr_of_pgci_srp; i++) { 00960 printf("\nProgram (PGC): %3i\n", i + 1); 00961 if (pgc_type) { 00962 printf("PGC Category: Entry PGC %d, Menu Type=0x%02x:%s (Entry id 0x%02x), ", 00963 pgcit->pgci_srp[i].entry_id >> 7, 00964 pgcit->pgci_srp[i].entry_id & 0xf, 00965 ifo_print_menu_name(pgcit->pgci_srp[i].entry_id & 0xf), 00966 pgcit->pgci_srp[i].entry_id); 00967 } else { 00968 printf("PGC Category: %s VTS_TTN:0x%02x (Entry id 0x%02x), ", 00969 pgcit->pgci_srp[i].entry_id >> 7 ? "At Start of" : "During", 00970 pgcit->pgci_srp[i].entry_id & 0xf, 00971 pgcit->pgci_srp[i].entry_id); 00972 } 00973 printf("Parental ID mask 0x%04x\n", pgcit->pgci_srp[i].ptl_id_mask); 00974 ifoPrint_PGC(pgcit->pgci_srp[i].pgc); 00975 } 00976 } 00977 00978 00979 static void ifoPrint_PGCI_UT(pgci_ut_t *pgci_ut) { 00980 int i, menu; 00981 00982 printf("Number of Menu Language Units (PGCI_LU): %3i\n", pgci_ut->nr_of_lus); 00983 for(i = 0; i < pgci_ut->nr_of_lus; i++) { 00984 printf("\nMenu Language Unit %d\n", i+1); 00985 printf("\nMenu Language Code: %c%c\n", 00986 pgci_ut->lu[i].lang_code >> 8, 00987 pgci_ut->lu[i].lang_code & 0xff); 00988 00989 menu = pgci_ut->lu[i].exists; 00990 printf("Menu Existence: %02x: ", menu); 00991 if (menu == 0) { 00992 printf("No menus "); 00993 } 00994 if (menu & 0x80) { 00995 printf("Root "); 00996 menu^=0x80; 00997 } 00998 if (menu & 0x40) { 00999 printf("Sub-Picture "); 01000 menu^=0x40; 01001 } 01002 if (menu & 0x20) { 01003 printf("Audio "); 01004 menu^=0x20; 01005 } 01006 if (menu & 0x10) { 01007 printf("Angle "); 01008 menu^=0x10; 01009 } 01010 if (menu & 0x08) { 01011 printf("PTT "); 01012 menu^=0x08; 01013 } 01014 if (menu > 0) { 01015 printf("Unknown extra menus "); 01016 menu^=0x08; 01017 } 01018 printf("\n"); 01019 ifoPrint_PGCIT(pgci_ut->lu[i].pgcit, 1); 01020 } 01021 } 01022 01023 01024 static void ifoPrint_VTS_ATTRIBUTES(vts_attributes_t *vts_attributes) { 01025 int i; 01026 01027 printf("VTS_CAT Application type: %08x\n", vts_attributes->vts_cat); 01028 01029 printf("Video attributes of VTSM_VOBS: "); 01030 ifo_print_video_attributes(5, &vts_attributes->vtsm_vobs_attr); 01031 printf("\n"); 01032 printf("Number of Audio streams: %i\n", 01033 vts_attributes->nr_of_vtsm_audio_streams); 01034 if(vts_attributes->nr_of_vtsm_audio_streams > 0) { 01035 printf("\tstream %i attributes: ", 1); 01036 ifo_print_audio_attributes(5, &vts_attributes->vtsm_audio_attr); 01037 printf("\n"); 01038 } 01039 printf("Number of Subpicture streams: %i\n", 01040 vts_attributes->nr_of_vtsm_subp_streams); 01041 if(vts_attributes->nr_of_vtsm_subp_streams > 0) { 01042 printf("\tstream %2i attributes: ", 1); 01043 ifo_print_subp_attributes(5, &vts_attributes->vtsm_subp_attr); 01044 printf("\n"); 01045 } 01046 01047 printf("Video attributes of VTSTT_VOBS: "); 01048 ifo_print_video_attributes(5, &vts_attributes->vtstt_vobs_video_attr); 01049 printf("\n"); 01050 printf("Number of Audio streams: %i\n", 01051 vts_attributes->nr_of_vtstt_audio_streams); 01052 for(i = 0; i < vts_attributes->nr_of_vtstt_audio_streams; i++) { 01053 printf("\tstream %i attributes: ", i); 01054 ifo_print_audio_attributes(5, &vts_attributes->vtstt_audio_attr[i]); 01055 printf("\n"); 01056 } 01057 01058 printf("Number of Subpicture streams: %i\n", 01059 vts_attributes->nr_of_vtstt_subp_streams); 01060 for(i = 0; i < vts_attributes->nr_of_vtstt_subp_streams; i++) { 01061 printf("\tstream %2i attributes: ", i); 01062 ifo_print_subp_attributes(5, &vts_attributes->vtstt_subp_attr[i]); 01063 printf("\n"); 01064 } 01065 } 01066 01067 01068 static void ifoPrint_VTS_ATRT(vts_atrt_t *vts_atrt) { 01069 int i; 01070 01071 printf("Number of Video Title Sets: %3i\n", vts_atrt->nr_of_vtss); 01072 for(i = 0; i < vts_atrt->nr_of_vtss; i++) { 01073 printf("\nVideo Title Set %i\n", i + 1); 01074 ifoPrint_VTS_ATTRIBUTES(&vts_atrt->vts[i]); 01075 } 01076 } 01077 01078 01079 void ifo_print(dvd_reader_t *dvd, int title) { 01080 ifo_handle_t *ifohandle; 01081 printf("Local ifo_print\n"); 01082 ifohandle = ifoOpen(dvd, title); 01083 if(!ifohandle) { 01084 fprintf(stderr, "Can't open info file for title %d\n", title); 01085 return; 01086 } 01087 01088 01089 if(ifohandle->vmgi_mat) { 01090 01091 printf("VMG top level\n-------------\n"); 01092 ifoPrint_VMGI_MAT(ifohandle->vmgi_mat); 01093 01094 printf("\nFirst Play PGC\n--------------\n"); 01095 if(ifohandle->first_play_pgc) 01096 ifoPrint_PGC(ifohandle->first_play_pgc); 01097 else 01098 printf("No First Play PGC present\n"); 01099 01100 printf("\nTitle Track search pointer table\n"); 01101 printf( "------------------------------------------------\n"); 01102 ifoPrint_TT_SRPT(ifohandle->tt_srpt); 01103 01104 printf("\nMenu PGCI Unit table\n"); 01105 printf( "--------------------\n"); 01106 if(ifohandle->pgci_ut) { 01107 ifoPrint_PGCI_UT(ifohandle->pgci_ut); 01108 } else { 01109 printf("No PGCI Unit table present\n"); 01110 } 01111 01112 printf("\nParental Management Information table\n"); 01113 printf( "------------------------------------\n"); 01114 if(ifohandle->ptl_mait) { 01115 ifoPrint_PTL_MAIT(ifohandle->ptl_mait); 01116 } else { 01117 printf("No Parental Management Information present\n"); 01118 } 01119 01120 printf("\nVideo Title Set Attribute Table\n"); 01121 printf( "-------------------------------\n"); 01122 ifoPrint_VTS_ATRT(ifohandle->vts_atrt); 01123 01124 printf("\nText Data Manager Information\n"); 01125 printf( "-----------------------------\n"); 01126 if(ifohandle->txtdt_mgi) { 01127 //ifo_print_TXTDT_MGI(&(vmgi->txtdt_mgi)); 01128 } else { 01129 printf("No Text Data Manager Information present\n"); 01130 } 01131 01132 printf("\nMenu Cell Address table\n"); 01133 printf( "-----------------\n"); 01134 if(ifohandle->menu_c_adt) { 01135 ifoPrint_C_ADT(ifohandle->menu_c_adt); 01136 } else { 01137 printf("No Menu Cell Address table present\n"); 01138 } 01139 01140 printf("\nVideo Manager Menu VOBU address map\n"); 01141 printf( "-----------------\n"); 01142 if(ifohandle->menu_vobu_admap) { 01143 ifoPrint_VOBU_ADMAP(ifohandle->menu_vobu_admap); 01144 } else { 01145 printf("No Menu VOBU address map present\n"); 01146 } 01147 } 01148 01149 01150 if(ifohandle->vtsi_mat) { 01151 01152 printf("VTS top level\n-------------\n"); 01153 ifoPrint_VTSI_MAT(ifohandle->vtsi_mat); 01154 01155 printf("\nPart of Title Track search pointer table\n"); 01156 printf( "----------------------------------------------\n"); 01157 ifoPrint_VTS_PTT_SRPT(ifohandle->vts_ptt_srpt); 01158 01159 printf("\nPGCI Unit table\n"); 01160 printf( "--------------------\n"); 01161 ifoPrint_PGCIT(ifohandle->vts_pgcit, 0); 01162 01163 printf("\nMenu PGCI Unit table\n"); 01164 printf( "--------------------\n"); 01165 if(ifohandle->pgci_ut) { 01166 ifoPrint_PGCI_UT(ifohandle->pgci_ut); 01167 } else { 01168 printf("No Menu PGCI Unit table present\n"); 01169 } 01170 01171 printf("\nVTS Time Map table\n"); 01172 printf( "-----------------\n"); 01173 if(ifohandle->vts_tmapt) { 01174 ifoPrint_VTS_TMAPT(ifohandle->vts_tmapt); 01175 } else { 01176 printf("No VTS Time Map table present\n"); 01177 } 01178 01179 printf("\nMenu Cell Address table\n"); 01180 printf( "-----------------\n"); 01181 if(ifohandle->menu_c_adt) { 01182 ifoPrint_C_ADT(ifohandle->menu_c_adt); 01183 } else { 01184 printf("No Cell Address table present\n"); 01185 } 01186 01187 printf("\nVideo Title Set Menu VOBU address map\n"); 01188 printf( "-----------------\n"); 01189 if(ifohandle->menu_vobu_admap) { 01190 ifoPrint_VOBU_ADMAP(ifohandle->menu_vobu_admap); 01191 } else { 01192 printf("No Menu VOBU address map present\n"); 01193 } 01194 01195 printf("\nCell Adress table\n"); 01196 printf( "-----------------\n"); 01197 ifoPrint_C_ADT(ifohandle->vts_c_adt); 01198 01199 printf("\nVideo Title Set VOBU address map\n"); 01200 printf( "-----------------\n"); 01201 ifoPrint_VOBU_ADMAP(ifohandle->vts_vobu_admap); 01202 } 01203 01204 ifoClose(ifohandle); 01205 }
1.7.6.1