00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
00067
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
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
00085
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
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. ");
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
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
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:
00329 printf("Normal Caption ");
00330 break;
00331 case 2:
00332 printf("Audio for visually impaired ");
00333 break;
00334 case 3:
00335 printf("Director's comments 1 ");
00336 break;
00337 case 4:
00338 printf("Director's comments 2 ");
00339 break;
00340
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
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
00745 printf("Playback time: ");
00746 dvdread_print_time(&pgc->playback_time); printf("\n");
00747
00748
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) {
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) {
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
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
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
00859
00860
00861
00862
00863
00864
00865
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
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
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
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 }