MythTV  0.26-pre
ifo_print.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends