diff libmpdvdkit2/ifo_print.c @ 15874:483e955893b8

update libdvdread to v0.9.4
author aurel
date Thu, 30 Jun 2005 22:48:26 +0000
parents 25df9508f9a8
children e1d6fbd607e0
line wrap: on
line diff
--- a/libmpdvdkit2/ifo_print.c	Thu Jun 30 22:41:40 2005 +0000
+++ b/libmpdvdkit2/ifo_print.c	Thu Jun 30 22:48:26 2005 +0000
@@ -1,10 +1,7 @@
 /* 
- * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn@dtek.chalmers.se>, 
- *                                Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
- * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
- * $Id$
+ * Copyright (C) 2000, 2001, 2002, 2003
+ *               Björn Englund <d4bjorn@dtek.chalmers.se>, 
+ *               Håkan Hjort <d95hjort@dtek.chalmers.se>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,26 +18,27 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <inttypes.h>
 #include <string.h>
 #include <ctype.h>
-//#include <assert.h>
 
-#include "config.h" // Needed for WORDS_BIGENDIAN
 #include "ifo_types.h"
 #include "ifo_read.h"
 #include "ifo_print.h"
+#include "dvdread_internal.h"
 
 /* Put this in some other file / package?  It's used in nav_print too. */
-static void ifoPrint_time(int level, dvd_time_t *dtime) {
+static void ifoPrint_time(dvd_time_t *dtime) {
   const char *rate;
-  assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
-  assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
-  assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
-  assert((dtime->frame_u&0xf) < 0xa);
+  CHECK_VALUE((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
+  CHECK_VALUE((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
+  CHECK_VALUE((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
+  CHECK_VALUE((dtime->frame_u&0xf) < 0xa);
   
   printf("%02x:%02x:%02x.%02x", 
 	 dtime->hour,
@@ -79,7 +77,7 @@
   printf("\n");
 }
 
-static void ifoPrint_video_attributes(int level, video_attr_t *attr) {
+static void ifoPrint_video_attributes(video_attr_t *attr) {
   
   /* The following test is shorter but not correct ISO C,
      memcmp(attr,my_friendly_zeros, sizeof(video_attr_t)) */
@@ -90,6 +88,7 @@
      && attr->unknown1 == 0 
      && attr->line21_cc_1 == 0 
      && attr->line21_cc_2 == 0 
+     && attr->bit_rate == 0 
      && attr->video_format == 0 
      && attr->letterboxed == 0 
      && attr->film_mode == 0) {
@@ -149,7 +148,7 @@
   }
   
   printf("U%x ", attr->unknown1);
-  assert(!attr->unknown1);
+  CHECK_VALUE(!attr->unknown1);
   
   if(attr->line21_cc_1 || attr->line21_cc_2) {
     printf("NTSC CC ");
@@ -158,6 +157,17 @@
     if(attr->line21_cc_2)
       printf("2 ");
   }
+
+  switch(attr->bit_rate) {
+    case 0:
+      printf("Variable Bit Rate ");
+      break;
+    case 1:
+      printf("Constant Bit Rate ");
+      break;
+    default:
+      printf("(please send a bug report)");
+  }
   
   {
     int height = 480;
@@ -192,7 +202,7 @@
   }
 }
 
-static void ifoPrint_audio_attributes(int level, audio_attr_t *attr) {
+static void ifoPrint_audio_attributes(audio_attr_t *attr) {
   
   if(attr->audio_format == 0
      && attr->multichannel_extension == 0
@@ -201,8 +211,10 @@
      && attr->quantization == 0
      && attr->sample_frequency == 0
      && attr->channels == 0
+     && attr->lang_code == 0
      && attr->lang_extension == 0
-     && attr->unknown1 == 0
+     && attr->code_extension == 0
+     && attr->unknown3 == 0
      && attr->unknown1 == 0) {
     printf("-- Unspecified --");
     return;
@@ -240,10 +252,11 @@
   switch(attr->lang_type) {
   case 0:
     // not specified
-    assert(attr->lang_code == 0 || attr->lang_code == 0xffff);
+    CHECK_VALUE(attr->lang_code == 0 || attr->lang_code == 0xffff);
     break;
   case 1:
-    printf("%c%c ", attr->lang_code>>8, attr->lang_code & 0xff);
+    printf("%c%c (%c) ", attr->lang_code>>8, attr->lang_code & 0xff,
+           attr->lang_extension ? attr->lang_extension : ' ');
     break;
   default:
     printf("(please send a bug report) ");
@@ -294,7 +307,7 @@
   
   printf("%dCh ", attr->channels + 1);
   
-  switch(attr->lang_extension) {
+  switch(attr->code_extension) {
   case 0:
     printf("Not specified ");
     break;
@@ -315,34 +328,64 @@
     printf("(please send a bug report) ");
   }
     
-  printf("%d ", attr->unknown1);
-  printf("%d ", attr->unknown2);
+  printf("%d ", attr->unknown3);
+  if(attr->application_mode == 1) {
+    printf("ca=%d ", attr->app_info.karaoke.channel_assignment);
+    printf("%d ", attr->app_info.karaoke.version);
+    if(attr->app_info.karaoke.mc_intro) 
+      printf("mc intro ");
+    printf("%s ", attr->app_info.karaoke.mode ? "duet" : "solo");
+    printf("%d ", attr->app_info.karaoke.unknown4);
+  }
+  if(attr->application_mode == 2) {
+    if(attr->app_info.surround.dolby_encoded) {
+      printf("dolby surround ");
+    }
+    printf("%d ", attr->app_info.surround.unknown5);
+    printf("%d ", attr->app_info.surround.unknown6);
+  }    
 }
 
-static void ifoPrint_subp_attributes(int level, subp_attr_t *attr) {
+static void ifoPrint_subp_attributes(subp_attr_t *attr) {
   
   if(attr->type == 0
+     && attr->code_mode == 0
      && attr->lang_code == 0
+     && attr->lang_extension == 0
      && attr->zero1 == 0
      && attr->zero2 == 0
-     && attr->lang_extension== 0) {
+     && attr->code_extension == 0) {
     printf("-- Unspecified --");
     return;
   }
   
-  printf("type %02x ", attr->type);
-  
-  if(isalpha((int)(attr->lang_code >> 8))
-     && isalpha((int)(attr->lang_code & 0xff))) {
-    printf("%c%c ", attr->lang_code >> 8, attr->lang_code & 0xff);
+  switch(attr->code_mode) {
+  case 0:
+    printf("Coding Mode RLE ");
+    break;
+  case 1:
+    printf("Coding Mode Extended ");
+    break;
+  default:
+    printf("(please send a bug report) ");
+  }    
+ 
+  if(attr->type == 1) {
+    if(isalpha((int)(attr->lang_code >> 8))
+       && isalpha((int)(attr->lang_code & 0xff))) {
+      printf("%c%c ", attr->lang_code >> 8, attr->lang_code & 0xff);
+    } else {
+      printf("%02x%02x ", attr->lang_code >> 8, attr->lang_code & 0xff);
+    }
   } else {
-    printf("%02x%02x ", 0xff & (unsigned)(attr->lang_code >> 8), 
-	   0xff & (unsigned)(attr->lang_code & 0xff));
+      printf("lang not specified ");
   }
   
   printf("%d ", attr->zero1);
   printf("%d ", attr->zero2);
-
+  printf("%d ", attr->code_extension);
+  
+  /* Is this correct?  should it not be subp_code_ext here instead? */
   switch(attr->lang_extension) {
   case 0:
     printf("Not specified ");
@@ -498,20 +541,20 @@
   printf("Start sector of VMGM_VOBU_ADMAP: %08x\n", 
 	 vmgi_mat->vmgm_vobu_admap);
   printf("Video attributes of VMGM_VOBS: ");
-  ifoPrint_video_attributes(5, &vmgi_mat->vmgm_video_attr);
+  ifoPrint_video_attributes(&vmgi_mat->vmgm_video_attr);
   printf("\n");
   printf("VMGM Number of Audio attributes: %i\n", 
 	 vmgi_mat->nr_of_vmgm_audio_streams);
   if(vmgi_mat->nr_of_vmgm_audio_streams > 0) {
     printf("\tstream %i status: ", 1);
-    ifoPrint_audio_attributes(5, &vmgi_mat->vmgm_audio_attr);
+    ifoPrint_audio_attributes(&vmgi_mat->vmgm_audio_attr);
     printf("\n");
   }
   printf("VMGM Number of Sub-picture attributes: %i\n", 
 	 vmgi_mat->nr_of_vmgm_subp_streams);
   if(vmgi_mat->nr_of_vmgm_subp_streams > 0) {
     printf("\tstream %2i status: ", 1);
-    ifoPrint_subp_attributes(5, &vmgi_mat->vmgm_subp_attr);
+    ifoPrint_subp_attributes(&vmgi_mat->vmgm_subp_attr);
     printf("\n");
   }
 }
@@ -540,14 +583,14 @@
   printf("Start sector of VTS_VOBU_ADMAP:  %08x\n", vtsi_mat->vts_vobu_admap);
 
   printf("Video attributes of VTSM_VOBS: ");
-  ifoPrint_video_attributes(5, &vtsi_mat->vtsm_video_attr);
+  ifoPrint_video_attributes(&vtsi_mat->vtsm_video_attr);
   printf("\n");
   
   printf("VTSM Number of Audio attributes: %i\n", 
 	 vtsi_mat->nr_of_vtsm_audio_streams);
   if(vtsi_mat->nr_of_vtsm_audio_streams > 0) {
     printf("\tstream %i status: ", 1);
-    ifoPrint_audio_attributes(5, &vtsi_mat->vtsm_audio_attr);
+    ifoPrint_audio_attributes(&vtsi_mat->vtsm_audio_attr);
     printf("\n");
   }
   
@@ -555,19 +598,19 @@
 	 vtsi_mat->nr_of_vtsm_subp_streams);
   if(vtsi_mat->nr_of_vtsm_subp_streams > 0) {
     printf("\tstream %2i status: ", 1);
-    ifoPrint_subp_attributes(5, &vtsi_mat->vtsm_subp_attr);
+    ifoPrint_subp_attributes(&vtsi_mat->vtsm_subp_attr);
     printf("\n");
   }
   
   printf("Video attributes of VTS_VOBS: ");
-  ifoPrint_video_attributes(5, &vtsi_mat->vts_video_attr);
+  ifoPrint_video_attributes(&vtsi_mat->vts_video_attr);
   printf("\n");
   
   printf("VTS Number of Audio attributes: %i\n", 
 	 vtsi_mat->nr_of_vts_audio_streams);
   for(i = 0; i < vtsi_mat->nr_of_vts_audio_streams; i++) {
     printf("\tstream %i status: ", i);
-    ifoPrint_audio_attributes(5, &vtsi_mat->vts_audio_attr[i]);
+    ifoPrint_audio_attributes(&vtsi_mat->vts_audio_attr[i]);
     printf("\n");
   }
   
@@ -575,9 +618,11 @@
 	 vtsi_mat->nr_of_vts_subp_streams);
   for(i = 0; i < vtsi_mat->nr_of_vts_subp_streams; i++) {
     printf("\tstream %2i status: ", i);
-    ifoPrint_subp_attributes(5, &vtsi_mat->vts_subp_attr[i]);
+    ifoPrint_subp_attributes(&vtsi_mat->vts_subp_attr[i]);
     printf("\n");
   }
+  
+  /* FIXME:  Add printing of MultiChannel Extension */
 }
 
 
@@ -631,7 +676,7 @@
   for(i=0;i<nr;i++) {
     printf("Cell: %3i ", i + 1);
 
-    ifoPrint_time(5, &cell_playback[i].playback_time);
+    ifoPrint_time(&cell_playback[i].playback_time);
     printf("\t");
 
     if(cell_playback[i].block_mode || cell_playback[i].block_type) {
@@ -709,7 +754,7 @@
   printf("Number of Cells: %i\n", pgc->nr_of_cells);
   /* Check that time is 0:0:0:0 also if nr_of_programs==0 */
   printf("Playback time: ");
-  ifoPrint_time(5, &pgc->playback_time); printf("\n");
+  ifoPrint_time(&pgc->playback_time); printf("\n");
 
   /* If no programs/no time then does this mean anything? */
   printf("Prohibited user operations: ");
@@ -734,7 +779,12 @@
   printf("GoUp PGC number: %i\n", pgc->goup_pgc_nr);
   if(pgc->nr_of_programs != 0) {
     printf("Still time: %i seconds (255=inf)\n", pgc->still_time);
-    printf("PG Playback mode %02x\n", pgc->pg_playback_mode);
+    if(pgc->pg_playback_mode == 0)
+      printf("PG Playback mode: Sequential\n");
+    else if(!(pgc->pg_playback_mode & 0x80))
+      printf("PG Playback mode: Random %i\n", pgc->pg_playback_mode);
+    else
+      printf("PG Playback mode: Shuffle %i\n", pgc->pg_playback_mode & 0x7f );
   }
   
   if(pgc->nr_of_programs != 0) {
@@ -764,8 +814,23 @@
     printf("\tNumber of PTTs: %i\n", tt_srpt->title[i].nr_of_ptts);
     printf("\tNumber of angles: %i\n", 
 	   tt_srpt->title[i].nr_of_angles);
-    printf("\tTitle playback type: %02x\n",     /* XXX: TODO FIXME */
-	   *(uint8_t *)&(tt_srpt->title[i].pb_ty));
+    printf("\tTitle playback type: %s%s%s%s%s%s%s\n",
+	   tt_srpt->title[i].pb_ty.multi_or_random_pgc_title ? 
+	   " One Random PGC Title or Multi PGC Title" : 
+	   " One Sequential PGC Title",
+	   tt_srpt->title[i].pb_ty.jlc_exists_in_cell_cmd ?
+	   "" : ", No Link/Jump/Call exists in Cell command",
+	   tt_srpt->title[i].pb_ty.jlc_exists_in_prepost_cmd ?
+	   "" : ", No Link/Jump/Call exists in Pre- and/or Post-command",
+	   tt_srpt->title[i].pb_ty.jlc_exists_in_button_cmd ?
+	   "" : ", No Link/Jump/Call exists in Button command",
+	   tt_srpt->title[i].pb_ty.jlc_exists_in_tt_dom ?
+	   "" : ", No Link/Jump/Call exists in TT_DOM",
+	   tt_srpt->title[i].pb_ty.chapter_search_or_play ?
+	   ", UOP1 (TT_Play and PTT_Search) prohibited" : "",
+	   tt_srpt->title[i].pb_ty.title_or_time_play ?
+	   ", UOP0 (Time_Play and Time_Search) prohibited" : ""
+	   );    
     printf("\tParental ID field: %04x\n",
 	   tt_srpt->title[i].parental_id);
     printf("\tTitle set starting sector %08x\n", 
@@ -780,6 +845,8 @@
 	 vts_ptt_srpt->nr_of_srpts, 
 	 vts_ptt_srpt->last_byte);
   for(i=0;i<vts_ptt_srpt->nr_of_srpts;i++) {
+    printf("\nVTS_PTT number %d has a offset %d relative to VTS_PTT_SRPT\n", 
+				i + 1, vts_ptt_srpt->ttu_offset[i]);
     for(j=0;j<vts_ptt_srpt->title[i].nr_of_ptts;j++) {
       printf("VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
 	     i + 1, j + 1, 
@@ -790,40 +857,57 @@
 }
 
 
-static void hexdump(uint8_t *ptr, int len) {
-  while(len--)
-    printf("%02x ", *ptr++);
-}
-
 void ifoPrint_PTL_MAIT(ptl_mait_t *ptl_mait) {
-  int i, j;
+  int i, level, vts;
   
   printf("Number of Countries: %i\n", ptl_mait->nr_of_countries);
   printf("Number of VTSs: %i\n", ptl_mait->nr_of_vtss);
-  //printf("Last byte: %i\n", ptl_mait->last_byte);
+  printf("Last byte: %i\n", ptl_mait->last_byte);
   
   for(i = 0; i < ptl_mait->nr_of_countries; i++) {
-    printf("Country code: %c%c\n", 
+    
+    printf("Start byte: %i\n", ptl_mait->countries[i].pf_ptl_mai_start_byte);
+    printf("Parental Masks for country: %c%c\n",
 	   ptl_mait->countries[i].country_code >> 8,
 	   ptl_mait->countries[i].country_code & 0xff);
-    /*
-      printf("Start byte: %04x %i\n", 
-      ptl_mait->countries[i].pf_ptl_mai_start_byte, 
-      ptl_mait->countries[i].pf_ptl_mai_start_byte);
-    */
-    /* This seems to be pointing at a array with 8 2byte fields per VTS
-       ? and one extra for the menu? always an odd number of VTSs on
-       all the dics I tested so it might be padding to even also.
-       If it is for the menu it probably the first entry.  */
-    for(j=0;j<8;j++) {
-      hexdump( (uint8_t *)ptl_mait->countries - PTL_MAIT_COUNTRY_SIZE 
-	       + ptl_mait->countries[i].pf_ptl_mai_start_byte
-	       + j*(ptl_mait->nr_of_vtss+1)*2, (ptl_mait->nr_of_vtss+1)*2);
+    
+    for(vts = 0; vts <= ptl_mait->nr_of_vtss; vts++) {
+      if( vts == 0 ) {
+	printf("VMG    "); 
+      } else {
+	printf("VTS %2d ", vts);
+      }
+      for(level = 0; level < 8; level++) {
+	printf("%d: %04x  ", level,
+	       ptl_mait->countries[i].pf_ptl_mai[vts][level] );
+      }
       printf("\n");
     }
   }
 }
 
+void ifoPrint_VTS_TMAPT(vts_tmapt_t *vts_tmapt) {
+  unsigned int timeunit;
+  int i, j;
+  
+  printf("Number of VTS_TMAPS: %i\n", vts_tmapt->nr_of_tmaps);
+  printf("Last byte: %i\n", vts_tmapt->last_byte);
+
+  for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
+    printf("TMAP %i\n", i + 1);
+    printf("  offset %d relative to VTS_TMAPTI\n", vts_tmapt->tmap_offset[i]);
+    printf("  Time unit (seconds): %i\n", vts_tmapt->tmap[i].tmu);
+    printf("  Number of entries: %i\n", vts_tmapt->tmap[i].nr_of_entries);
+    timeunit = vts_tmapt->tmap[i].tmu;
+    for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) {
+      unsigned int ac_time = timeunit * (j + 1);
+      printf("Time: %2i:%02i:%02i  VOBU Sector: 0x%08x %s\n", 
+	     ac_time / (60 * 60), (ac_time / 60) % 60, ac_time % 60,
+	     vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff,
+	     (vts_tmapt->tmap[i].map_ent[j] >> 31) ? "discontinuity" : "");
+    }
+  }
+}
 
 void ifoPrint_C_ADT(c_adt_t *c_adt) {
   int i, entries;
@@ -870,9 +954,10 @@
   
   printf("Number of Menu Language Units (PGCI_LU): %3i\n", pgci_ut->nr_of_lus);
   for(i = 0; i < pgci_ut->nr_of_lus; i++) {
-    printf("\nMenu Language Code: %c%c\n",
+    printf("\nMenu Language Code: %c%c (%c)\n",
 	   pgci_ut->lu[i].lang_code >> 8,
-	   pgci_ut->lu[i].lang_code & 0xff);
+	   pgci_ut->lu[i].lang_code & 0xff,
+	   pgci_ut->lu[i].lang_extension ? pgci_ut->lu[i].lang_extension :' ');
     printf("Menu Existence: %02x\n", pgci_ut->lu[i].exists);
     ifoPrint_PGCIT(pgci_ut->lu[i].pgcit);
   }
@@ -885,31 +970,31 @@
   printf("VTS_CAT Application type: %08x\n", vts_attributes->vts_cat);
  
   printf("Video attributes of VTSM_VOBS: ");
-  ifoPrint_video_attributes(5, &vts_attributes->vtsm_vobs_attr);
+  ifoPrint_video_attributes(&vts_attributes->vtsm_vobs_attr);
   printf("\n");
   printf("Number of Audio streams: %i\n", 
 	 vts_attributes->nr_of_vtsm_audio_streams);
   if(vts_attributes->nr_of_vtsm_audio_streams > 0) {
     printf("\tstream %i attributes: ", 1);
-    ifoPrint_audio_attributes(5, &vts_attributes->vtsm_audio_attr);
+    ifoPrint_audio_attributes(&vts_attributes->vtsm_audio_attr);
     printf("\n");
   }
   printf("Number of Subpicture streams: %i\n", 
 	 vts_attributes->nr_of_vtsm_subp_streams);
   if(vts_attributes->nr_of_vtsm_subp_streams > 0) {
     printf("\tstream %2i attributes: ", 1);
-    ifoPrint_subp_attributes(5, &vts_attributes->vtsm_subp_attr);
+    ifoPrint_subp_attributes(&vts_attributes->vtsm_subp_attr);
     printf("\n");
   }
    
   printf("Video attributes of VTSTT_VOBS: ");
-  ifoPrint_video_attributes(5, &vts_attributes->vtstt_vobs_video_attr);
+  ifoPrint_video_attributes(&vts_attributes->vtstt_vobs_video_attr);
   printf("\n");
   printf("Number of Audio streams: %i\n", 
 	 vts_attributes->nr_of_vtstt_audio_streams);
   for(i = 0; i < vts_attributes->nr_of_vtstt_audio_streams; i++) {
     printf("\tstream %i attributes: ", i);
-    ifoPrint_audio_attributes(5, &vts_attributes->vtstt_audio_attr[i]);
+    ifoPrint_audio_attributes(&vts_attributes->vtstt_audio_attr[i]);
     printf("\n");
   }
   
@@ -917,7 +1002,7 @@
 	 vts_attributes->nr_of_vtstt_subp_streams);
   for(i = 0; i < vts_attributes->nr_of_vtstt_subp_streams; i++) {
     printf("\tstream %2i attributes: ", i);    
-    ifoPrint_subp_attributes(5, &vts_attributes->vtstt_subp_attr[i]);
+    ifoPrint_subp_attributes(&vts_attributes->vtstt_subp_attr[i]);
     printf("\n");
   }
 }
@@ -929,6 +1014,8 @@
   printf("Number of Video Title Sets: %3i\n", vts_atrt->nr_of_vtss);
   for(i = 0; i < vts_atrt->nr_of_vtss; i++) {
     printf("\nVideo Title Set %i\n", i + 1);
+    printf("  offset %d relative to VMG_VTS_ATRT\n", 
+	   vts_atrt->vts_atrt_offsets[i]);
     ifoPrint_VTS_ATTRIBUTES(&vts_atrt->vts[i]);
   }
 }
@@ -1022,6 +1109,14 @@
     } else {
       printf("No Menu PGCI Unit table present\n");
     }
+    
+    printf("\nTime Search table\n");
+    printf(  "-----------------\n");
+    if(ifohandle->vts_tmapt) {
+      ifoPrint_VTS_TMAPT(ifohandle->vts_tmapt);
+    } else {
+      printf("No Time Search table present\n");
+    }
 
     printf("\nMenu Cell Adress table\n");
     printf(  "-----------------\n");