[libdvdnav-devel] [Git][videolan/libdvdread][master] 8 commits: Refactor: Rename variables to match DVD-VR patent

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Tue Feb 17 22:58:23 UTC 2026



Jean-Baptiste Kempf pushed to branch master at VideoLAN / libdvdread


Commits:
8731baae by Saifelden Mohamed Ismail at 2026-01-30T10:29:15+02:00
Refactor: Rename variables to match DVD-VR patent

- - - - -
ca769622 by Saifelden Mohamed Ismail at 2026-01-30T10:29:18+02:00
DVD-VR: fix PGC_GI seeking behavior

- - - - -
31816d3f by Saifelden Mohamed Ismail at 2026-01-30T10:29:18+02:00
DVD-VR: split data64 in rtav_vmgi_mat

- - - - -
3fcb6aee by Saifelden Mohamed Ismail at 2026-02-01T15:27:07+02:00
DVD-VR: remove unnecessary pointer free

- - - - -
6f61061b by Saifelden Mohamed Ismail at 2026-02-01T15:27:10+02:00
DVD-VR: add user defined cell ifo types

- - - - -
81971a35 by Saifelden Mohamed Ismail at 2026-02-01T15:27:10+02:00
DVD-VR: add user defined cell map ifo reads and close

- - - - -
8c671e14 by Saifelden Mohamed Ismail at 2026-02-01T15:27:10+02:00
DVD-VR: add tmap entry fields

- - - - -
3803c92f by Saifelden Mohamed Ismail at 2026-02-01T15:31:21+02:00
DVD-VR: add additional null check

- - - - -


4 changed files:

- src/dvdread/ifo_read.h
- src/dvdread/ifo_types.h
- src/ifo_print.c
- src/ifo_read.c


Changes:

=====================================
src/dvdread/ifo_read.h
=====================================
@@ -246,36 +246,36 @@ DVDREAD_API ifo_handle_t *ifoOpenSAMG(dvd_reader_t *ctx);
 DVDREAD_API ifo_handle_t *ifoOpenASVS(dvd_reader_t *ctx);
 
 /**
- * okay = ifoRead_PGIT(ifofile);
+ * okay = ifoRead_PGCI(ifofile);
  *
- * Reads the Program Information Table (PGIT).
+ * Reads the Program Chain Information Table (pgci).
  * This structure contains the technical definitions for the recordings, including
  * video attributes (aspect ratio, resolution), audio stream counts, and formats.
  * Use this data to configure the decoder element (ES format) before playback starts.
  */
-DVDREAD_API int ifoRead_PGIT(ifo_handle_t *ifofile);
+DVDREAD_API int ifoRead_PGCI(ifo_handle_t *ifofile);
 
 /**
- * okay = ifoRead_PG_GI(ifofile);
+ * okay = ifoRead_PGC_GI(ifofile);
  *
- * Reads the Program General Information (PG_GI).
+ * Reads the Program Chain General Information (pgc_gi).
  * This is the master database of all physical video clips ("Programs") on the disc.
  * It provides the raw byte offsets, durations, and timestamps (PGTM) for every
  * recording. This is required to locate content sectors and to generate "Title 0"
  * (the raw/original timeline).
  */
-DVDREAD_API int ifoRead_PG_GI(ifo_handle_t *ifofile);
+DVDREAD_API int ifoRead_PGC_GI(ifo_handle_t *ifofile);
 
 /**
- * okay = ifoRead_PS_GI(ifofile);
+ * okay = ifoRead_UD_PGCIT(ifofile);
  *
- * Reads the Program Set General Information (PS_GI).
+ * Reads the Program Set General Information (ud_pgcit).
  * This defines the user-created "Titles" (Playlists) and their text labels.
- * It maps logical groupings of content to the physical programs found in PG_GI.
+ * It maps logical groupings of content to the physical programs found in pgc_gi.
  * Use this to build the main navigation menu and "Next/Prev" chapter logic
  * intended by the user.
  */
-DVDREAD_API int ifoRead_PS_GI(ifo_handle_t *ifofile);
+DVDREAD_API int ifoRead_UD_PGCIT(ifo_handle_t *ifofile);
 
 /**
  * The following functions are used for freeing parsed sections of the
@@ -297,7 +297,7 @@ DVDREAD_API void ifoFree_VOBU_ADMAP(ifo_handle_t *);
 DVDREAD_API void ifoFree_TITLE_VOBU_ADMAP(ifo_handle_t *);
 DVDREAD_API void ifoFree_TXTDT_MGI(ifo_handle_t *);
 DVDREAD_API void ifoFree_TT(ifo_handle_t *);
-DVDREAD_API void ifoFree_PG_GI(ifo_handle_t *);
+DVDREAD_API void ifoFree_PGC_GI(ifo_handle_t *);
 
 #ifdef __cplusplus
 };


=====================================
src/dvdread/ifo_types.h
=====================================
@@ -1114,7 +1114,8 @@ typedef struct {
   uint16_t version;        /* specification version */
   /* 34 */                 /* Different from DVD-Video from here */
   uint8_t  zero_34[30];
-  uint8_t  data_64[3];
+  uint8_t  tm_zone;        /* time zone */
+  uint16_t still_tm;       /* still time for still pictures */
   uint8_t  txt_encoding;   /* as per VideoTextDataUsage.pdf */
   uint8_t  data_68[30];
   /* 98 */
@@ -1122,21 +1123,21 @@ typedef struct {
   char     disc_info2[64]; /* format name, time or user label.. */
   uint8_t  zero_226[30];
   /* 256 */
-  uint32_t pgit_sa;        /* program info table start address */
-  uint32_t org_pgci_sa;    /* start address for the original raw recordings? */
+  uint32_t org_pgci_sa;    /* original program chain start address */
+  uint32_t org_pgci_ea;    /* end address for the org_pgci */
   uint8_t  zero_264[7];
   cprm_info_t cprm_info;
   uint8_t  zero_280[24];
   /* 304 */
-  uint32_t def_psi_sa;     /* default program set info start address, user defined */
+  uint32_t ud_pgcit_sa;     /* user defined program chain information table */
   uint32_t info_308_sa;    /* ? start address */
-  uint32_t info_312_sa;    /* user defined program set info start address? */
+  uint32_t info_312_sa;
   uint32_t info_316_sa;    /* ? start address */
   uint8_t  zero_320[32];
-  uint32_t txt_attr_sa;    /* extra attributes for programs (chan id etc.) */
-  uint32_t info_356_sa;    /* ? start address */
+  uint32_t txtdt_mg_sa;    /* extra attributes for programs (chan id etc.) */
+  uint32_t mnfit_sa;       /* manufacturer information table */
   uint8_t  zero_360[152];
-} ATTRIBUTE_PACKED rtav_vmgi_t; /*Real Time AV (from DVD_RTAV dir)*/
+} ATTRIBUTE_PACKED rtav_vmgi_t;
 #define RTAV_VMGI_SIZE 512U
 
 typedef struct {
@@ -1158,7 +1159,9 @@ typedef struct {
 #define ADJ_VOB_SIZE 12U
 
 typedef struct {
-  uint8_t  data[7];
+  uint16_t  vobu_entn; /* entry vobu */
+  uint8_t   tm_diff;   /* time difference */
+  uint32_t  vobu_adr;  /* time difference */
 } ATTRIBUTE_PACKED time_info_t;
 #define TIME_INFO_SIZE 7U
 
@@ -1201,7 +1204,7 @@ typedef struct {
   /* optional */
 
   vobu_map_t  map;          /* The Time Map */
-} program_t;
+} pgi_t;
 
 typedef struct {
   uint16_t video_attr;
@@ -1218,20 +1221,19 @@ typedef struct {
   uint16_t zero1;
   uint8_t  nr_of_pgi;
   uint8_t  nr_of_vob_formats;
-  uint32_t pgit_ea;
+  uint32_t len_org_pgci; /* length of PGCI + PGC_GI */
 
   vob_format_t* vob_formats;
-} ATTRIBUTE_PACKED pgit_t; /* Program Info Table */
-#define PGIT_SIZE 8U
+} ATTRIBUTE_PACKED pgci_t; /* Program Info Table */
+#define PGCI_SIZE 8U
 
 /* this defines individual video recordings (clips, programs) */
 typedef struct {
-  uint16_t nr_of_programs;
-
+  uint16_t  nr_of_programs;
   uint32_t* program_offsets; /* vobu start addresses */
-  program_t* programs;
-} ATTRIBUTE_PACKED pg_gi_t; /* program locations table */
-#define PG_GI_SIZE 2U
+  pgi_t*    pgi;
+} ATTRIBUTE_PACKED pgc_gi_t; /* program locations table */
+#define PGC_GI_SIZE 2U
 
 typedef struct  {
   uint8_t  data1;
@@ -1242,18 +1244,48 @@ typedef struct  {
   uint16_t prog_set_id;     /* On LG V1.1 discs this is program set ID */
   uint16_t first_prog_id;   /* ID of first program in this program set */
   char     data3[6];
-} ATTRIBUTE_PACKED psi_t;
-#define PSI_SIZE 142U
+} ATTRIBUTE_PACKED ud_pgci_t;
+#define UD_PGCI_SIZE 142U
+
+typedef struct  {
+  uint8_t    ep_ty; /* type */
+  uint8_t    ep_ptm[6]; /* entry point time pts */
+} ATTRIBUTE_PACKED m_c_epi_t;
+#define M_C_EPI_SIZE 7U
+
+typedef struct  {
+  uint8_t    type;
+  uint8_t    reserved;
+  union {
+    struct {
+      uint8_t group_id;
+      uint8_t start_image;
+    } still_id;
+    uint16_t m_vobi_srpn;
+  };
+  uint8_t    end_image; /* will be zero if type is movie cell */
+  uint8_t    c_epi_n; /* used to allocate m_c_epi */
+  uint8_t    c_v_s_ptm[6];
+  uint8_t    c_v_e_ptm[6];
+  m_c_epi_t* m_c_epi; /*  movie cell entry points. seekable chapters */
+} ATTRIBUTE_PACKED m_c_gi_t;
+#define M_C_GI_SIZE 18U
+
+#define MOVIE_CELL_TYPE 0
+#define STILL_CELL_TYPE 2
 
 /* this is like a playlist menu, it defines titles (groups of clips) */
 typedef struct  {
-  uint8_t  data1;
-  uint8_t  nr_of_psi;
-  uint16_t total_nr_of_programs;  /* Num programs on disc */
+  uint8_t    data1;
+  uint8_t    nr_of_pgci;
+  uint16_t   total_nr_of_programs;  /* Num programs on disc */
+  ud_pgci_t* ud_pgci_items;
+  uint32_t*  ci_offsets;
+  m_c_gi_t*  m_c_gi;
+} ATTRIBUTE_PACKED ud_pgcit_t; /* global info for Program Set*/
+#define UD_PGCIT_SIZE 4U
 
-  psi_t*   psi_items;
-} ATTRIBUTE_PACKED ps_gi_t; /* global info for Program Set*/
-#define PS_GI_SIZE 4U
+#define CI_OFFSET_SIZE 4U
 
 #if PRAGMA_PACK
 #pragma pack()
@@ -1324,9 +1356,13 @@ typedef struct {
     struct{
       /* VMGI_MAT for DVD-VR */
       rtav_vmgi_t            *rtav_vmgi;
-      pgit_t                 *pgit; /* vob formats */
-      pg_gi_t                *pg_gi; /* address map of recordings */
-      ps_gi_t                *ps_gi; /* titles, labels for recordings */
+
+      /* these two together make up the org_pgci, describe the VRO file's contents */
+      pgci_t                 *pgci;      /* Program cell information table */
+      pgc_gi_t               *pgc_gi;    /* Program cell general information table */
+
+      /* the user defined pgci */
+      ud_pgcit_t             *ud_pgcit;  /* titles, labels for recordings */
 
     };
 


=====================================
src/ifo_print.c
=====================================
@@ -1214,9 +1214,9 @@ static void ifoPrint_RTAV_VMGI(rtav_vmgi_t *vmgi) {
   printf("VMG End Address: %08x\n", vmgi->vmg_ea);
   printf("VMGI End Address: %08x\n", vmgi->vmgi_ea);
 
-  printf("PGIT Start Address: %08x\n", vmgi->pgit_sa);
+  printf("PGCI Start Address: %08x\n", vmgi->org_pgci_sa);
   printf("ORG_PGCI Start Address: %08x\n", vmgi->org_pgci_sa);
-  printf("DEF_PSI Start Address: %08x\n", vmgi->def_psi_sa);
+  printf("UD_PGCI Start Address: %08x\n", vmgi->ud_pgcit_sa);
 
   printf("Text Encoding: 0x%02x\n", vmgi->txt_encoding);
   printf("Disc Info 1: %.64s\n", vmgi->disc_info1);
@@ -1224,40 +1224,40 @@ static void ifoPrint_RTAV_VMGI(rtav_vmgi_t *vmgi) {
 
 }
 
-static void ifoPrint_PGIT(pgit_t *pgit) {
+static void ifoPrint_PGCI(pgci_t *pgci) {
   int i;
-  if (!pgit) {
-    printf("No PGIT present\n");
+  if (!pgci) {
+    printf("No PGCI present\n");
     return;
   }
 
-  printf("Program Information Table (PGIT)\n");
-  printf("Number of VOB Formats: %d\n", pgit->nr_of_vob_formats);
-  printf("PGIT End Address: %08x\n", pgit->pgit_ea);
+  printf("Program Information Table (pgci)\n");
+  printf("Number of VOB Formats: %d\n", pgci->nr_of_vob_formats);
+  printf("ORG_PGCI Length: %08x\n", pgci->len_org_pgci);
 
-  for(i = 0; i < pgit->nr_of_vob_formats; i++) {
+  for(i = 0; i < pgci->nr_of_vob_formats; i++) {
     printf("  Format %2i: Video Attr 0x%04x, Audio Streams: %d\n", 
            i + 1,
-           pgit->vob_formats[i].video_attr, 
-           pgit->vob_formats[i].nr_of_audio_streams);
+           pgci->vob_formats[i].video_attr,
+           pgci->vob_formats[i].nr_of_audio_streams);
   }
 }
 
-static void ifoPrint_PG_GI(pg_gi_t *pg_gi) {
+static void ifoPrint_PGC_GI(pgc_gi_t *pgc_gi) {
   int i;
-  if (!pg_gi) {
-    printf("No PG_GI present\n");
+  if (!pgc_gi) {
+    printf("No pgc_gi present\n");
     return;
   }
 
-  printf("Program General Information (PG_GI)\n");
-  printf("Number of Programs: %d\n", pg_gi->nr_of_programs);
+  printf("Program General Information (PGC_GI)\n");
+  printf("Number of Programs: %d\n", pgc_gi->nr_of_programs);
 
-  for(i = 0; i < pg_gi->nr_of_programs; i++) {
-    program_t *prog = &pg_gi->programs[i];
+  for(i = 0; i < pgc_gi->nr_of_programs; i++) {
+    pgi_t *prog = &pgc_gi->pgi[i];
 
     printf("\n  Program %3i:\n", i + 1);
-    printf("    Start Byte Offset: %08x\n", pg_gi->program_offsets[i]);
+    printf("    Start Byte Offset: %08x\n", pgc_gi->program_offsets[i]);
     printf("    VOB Attribute: 0x%04x\n", prog->header.vob_attr);
 
     printf("    Timestamp (PGTM): %02x %02x %02x %02x %02x\n",
@@ -1280,19 +1280,19 @@ static void ifoPrint_PG_GI(pg_gi_t *pg_gi) {
   }
 }
 
-static void ifoPrint_PS_GI(ps_gi_t *ps_gi) {
+static void ifoPrint_ud_pgcit(ud_pgcit_t *ud_pgcit) {
   int i;
-  if (!ps_gi) {
-    printf("No PS_GI present\n");
+  if (!ud_pgcit) {
+    printf("No UD_PGCIT present\n");
     return;
   }
 
-  printf("Program Set General Information (PS_GI)\n");
-  printf("Total Number of Programs on Disc: %d\n", ps_gi->total_nr_of_programs);
-  printf("Number of Program Sets (Playlists): %d\n", ps_gi->nr_of_psi);
+  printf("Program Set General Information (UD_PGCIT)\n");
+  printf("Total Number of Programs on Disc: %d\n", ud_pgcit->total_nr_of_programs);
+  printf("Number of Program Sets (Playlists): %d\n", ud_pgcit->nr_of_pgci);
 
-  for(i = 0; i < ps_gi->nr_of_psi; i++) {
-    psi_t *item = &ps_gi->psi_items[i];
+  for(i = 0; i < ud_pgcit->nr_of_pgci; i++) {
+    ud_pgci_t *item = &ud_pgcit->ud_pgci_items[i];
     printf("\n  Playlist %2i:\n", i + 1);
     printf("    Label: %.64s\n", item->label);
     printf("    Programs in Set: %d\n", item->nr_of_programs);
@@ -1475,22 +1475,22 @@ void ifo_print(dvd_reader_t *dvd, int title) {
         printf("No RTAV VMGI present\n");
       }
 
-      if(ifohandle->pgit) {
+      if(ifohandle->pgci) {
         printf("\nProgram Information Table (Tech Specs)\n");
         printf("--------------------------------------\n");
-        ifoPrint_PGIT(ifohandle->pgit);
+        ifoPrint_PGCI(ifohandle->pgci);
       }
 
-      if(ifohandle->pg_gi) {
+      if(ifohandle->pgc_gi) {
         printf("\nProgram General Information (Original Content)\n");
         printf("----------------------------------------------\n");
-        ifoPrint_PG_GI(ifohandle->pg_gi);
+        ifoPrint_PGC_GI(ifohandle->pgc_gi);
       }
 
-      if(ifohandle->ps_gi) {
+      if(ifohandle->ud_pgcit) {
         printf("\nProgram Set General Information (Playlists)\n");
         printf("-------------------------------------------\n");
-        ifoPrint_PS_GI(ifohandle->ps_gi);
+        ifoPrint_ud_pgcit(ifohandle->ud_pgcit);
       }
       break;
     case(IFO_UNKNOWN): 


=====================================
src/ifo_read.c
=====================================
@@ -201,9 +201,11 @@ CHECK_STRUCT_SIZE(atsi_title_record_t,    4, ATSI_TITLE_ROW_TABLE_SIZE);
 CHECK_STRUCT_SIZE(atsi_title_table_t,     2, ATSI_TITLE_TABLE_SIZE);
 CHECK_STRUCT_SIZE(downmix_coeff_t,        0, DOWNMIX_COEFF_SIZE);
 CHECK_STRUCT_SIZE(rtav_vmgi_t,            0, RTAV_VMGI_SIZE);
-CHECK_STRUCT_SIZE(pgit_t,                 1, PGIT_SIZE);
-CHECK_STRUCT_SIZE(pg_gi_t,                2, PG_GI_SIZE);
-CHECK_STRUCT_SIZE(ps_gi_t,                1, PS_GI_SIZE);
+CHECK_STRUCT_SIZE(pgci_t,                 1, PGCI_SIZE);
+CHECK_STRUCT_SIZE(pgc_gi_t,               2, PGC_GI_SIZE);
+CHECK_STRUCT_SIZE(ud_pgcit_t,             3, UD_PGCIT_SIZE);
+CHECK_STRUCT_SIZE(m_c_gi_t,               1, M_C_GI_SIZE);
+CHECK_STRUCT_SIZE(m_c_epi_t,              0, M_C_EPI_SIZE);
 
 static void read_video_attr(video_attr_t *va) {
   getbits_state_t state;
@@ -508,15 +510,13 @@ static ifo_handle_t *ifoOpenFileOrBackup(dvd_reader_t *ctx, int title,
   if(ifoRead_RTAV_VMGI(ifofile)){
     ifofile->ifo_format=IFO_VIDEO_RECORDING;
 
-    /* PS_GI and PGIT are required for the module */
-    if(!ifoRead_PS_GI(ifofile))
+    if(!ifoRead_UD_PGCIT(ifofile))
       goto ifoOpen_fail;
 
-    if(!ifoRead_PGIT(ifofile))
+    if(!ifoRead_PGCI(ifofile))
       goto ifoOpen_fail;
 
-    /* likely empty */
-    if(!ifoRead_PG_GI(ifofile))
+    if(!ifoRead_PGC_GI(ifofile))
       goto ifoOpen_fail;
 
   }
@@ -749,18 +749,31 @@ void ifoFree_TT(ifo_handle_t *ifofile){
   }
 }
 
-DVDREAD_API void ifoFree_PG_GI(ifo_handle_t *ifofile) {
-  if(!ifofile)
+DVDREAD_API void ifoFree_PGC_GI(ifo_handle_t *ifofile) {
+  if(!ifofile || !ifofile->pgc_gi)
     return;
 
-  for(int k = 0; k < ifofile->pg_gi->nr_of_programs; k++){
-    free(ifofile->pg_gi->programs[k].map.time_infos);
-    free(ifofile->pg_gi->programs[k].map.vobu_infos);
+  for(int k = 0; k < ifofile->pgc_gi->nr_of_programs; k++){
+    free(ifofile->pgc_gi->pgi[k].map.time_infos);
+    free(ifofile->pgc_gi->pgi[k].map.vobu_infos);
   }
-  free(ifofile->pg_gi->program_offsets);
-  free(ifofile->pg_gi->programs);
-  free(ifofile->pg_gi);
-  ifofile->pg_gi= NULL;
+  free(ifofile->pgc_gi->program_offsets);
+  free(ifofile->pgc_gi->pgi);
+  free(ifofile->pgc_gi);
+  ifofile->pgc_gi= NULL;
+}
+
+DVDREAD_API void ifoFree_UD_PGCIT(ifo_handle_t *ifofile) {
+  for ( int j = 0; j < ifofile->ud_pgcit->total_nr_of_programs ; j++ ) {
+    if(ifofile->ud_pgcit->m_c_gi[j].c_epi_n > 0)
+      free(ifofile->ud_pgcit->m_c_gi[j].m_c_epi);
+  }
+
+  free(ifofile->ud_pgcit->m_c_gi);
+  free(ifofile->ud_pgcit->ci_offsets);
+  free(ifofile->ud_pgcit->ud_pgci_items);
+  free(ifofile->ud_pgcit);
+  ifofile->ud_pgcit = NULL;
 }
 
 void ifoClose(ifo_handle_t *ifofile) {
@@ -816,15 +829,13 @@ void ifoClose(ifo_handle_t *ifofile) {
     case IFO_VIDEO_RECORDING:
       if(ifofile->rtav_vmgi)
         free(ifofile->rtav_vmgi);
-      if(ifofile->ps_gi) {
-        free(ifofile->ps_gi->psi_items);
-        free(ifofile->ps_gi);
-      }
-      if(ifofile->pg_gi)
-        ifoFree_PG_GI(ifofile);
-      if(ifofile->pgit){
-        free(ifofile->pgit->vob_formats);
-        free(ifofile->pgit);
+      if(ifofile->ud_pgcit)
+        ifoFree_UD_PGCIT(ifofile);
+      if(ifofile->pgc_gi)
+        ifoFree_PGC_GI(ifofile);
+      if(ifofile->pgci){
+        free(ifofile->pgci->vob_formats);
+        free(ifofile->pgci);
       }
       break;
     case IFO_UNKNOWN:
@@ -1345,16 +1356,17 @@ static int ifoRead_RTAV_VMGI(ifo_handle_t *ifofile) {
   }
 
   B2N_16(ifofile->rtav_vmgi->version);
+  B2N_16(ifofile->rtav_vmgi->still_tm);
   B2N_32(ifofile->rtav_vmgi->vmg_ea);
   B2N_32(ifofile->rtav_vmgi->vmgi_ea);
-  B2N_32(ifofile->rtav_vmgi->pgit_sa);
-  B2N_32(ifofile->rtav_vmgi->def_psi_sa);
   B2N_32(ifofile->rtav_vmgi->org_pgci_sa);
+  B2N_32(ifofile->rtav_vmgi->ud_pgcit_sa);
+  B2N_32(ifofile->rtav_vmgi->org_pgci_ea);
   B2N_32(ifofile->rtav_vmgi->info_308_sa);
   B2N_32(ifofile->rtav_vmgi->info_312_sa);
   B2N_32(ifofile->rtav_vmgi->info_316_sa);
-  B2N_32(ifofile->rtav_vmgi->txt_attr_sa);
-  B2N_32(ifofile->rtav_vmgi->info_356_sa);
+  B2N_32(ifofile->rtav_vmgi->txtdt_mg_sa);
+  B2N_32(ifofile->rtav_vmgi->mnfit_sa);
 
 
   CHECK_ZERO(ifofile->rtav_vmgi->zero_16);
@@ -1368,185 +1380,196 @@ static int ifoRead_RTAV_VMGI(ifo_handle_t *ifofile) {
 
 }
 
-int ifoRead_PGIT(ifo_handle_t *ifofile) {
+int ifoRead_PGCI(ifo_handle_t *ifofile) {
   struct ifo_handle_private_s *ifop = PRIV(ifofile);
-  pgit_t *pgit;
+  pgci_t *pgci;
 
-  pgit = malloc(sizeof(pgit_t));
+  pgci = malloc(sizeof(pgci_t));
 
-  if(!pgit)
+  if(!pgci)
     return 0;
 
-  ifofile->pgit= pgit;
+  ifofile->pgci= pgci;
 
-  if(!DVDFileSeek_(ifop->file, ifofile->rtav_vmgi->pgit_sa)) {
-    free(ifofile->pgit);
-    ifofile->pgit = NULL;
+  if(!DVDFileSeek_(ifop->file, ifofile->rtav_vmgi->org_pgci_sa)) {
+    free(ifofile->pgci);
+    ifofile->pgci = NULL;
     return 0;
   }
 
-  if(!DVDReadBytes(ifop->file, pgit, PGIT_SIZE)) {
-    free(ifofile->pgit);
-    ifofile->pgit = NULL;
+  if(!DVDReadBytes(ifop->file, pgci, PGCI_SIZE)) {
+    free(ifofile->pgci);
+    ifofile->pgci = NULL;
     return 0;
   }
 
-  pgit->vob_formats = calloc(ifofile->pgit->nr_of_vob_formats, VOB_FORMAT_SIZE);
+  pgci->vob_formats = calloc(ifofile->pgci->nr_of_vob_formats, VOB_FORMAT_SIZE);
 
-  if(!pgit->vob_formats) {
-    free(ifofile->pgit->vob_formats);
-    free(ifofile->pgit);
-    ifofile->pgit = NULL;
+  if(!pgci->vob_formats) {
+    free(ifofile->pgci->vob_formats);
+    free(ifofile->pgci);
+    ifofile->pgci = NULL;
     return 0;
   }
 
-  if(!DVDReadBytes(ifop->file, pgit->vob_formats, pgit->nr_of_vob_formats * VOB_FORMAT_SIZE)) {
-    free(ifofile->pgit->vob_formats);
-    free(ifofile->pgit);
-    ifofile->pgit = NULL;
+  if(!DVDReadBytes(ifop->file, pgci->vob_formats, pgci->nr_of_vob_formats * VOB_FORMAT_SIZE)) {
+    free(ifofile->pgci->vob_formats);
+    free(ifofile->pgci);
+    ifofile->pgci = NULL;
     return 0;
   }
 
-  for (int i = 0; i < pgit->nr_of_vob_formats ; i++)
-    B2N_16(pgit->vob_formats[i].video_attr);
+  for (int i = 0; i < pgci->nr_of_vob_formats ; i++)
+    B2N_16(pgci->vob_formats[i].video_attr);
 
-  B2N_32(pgit->pgit_ea);
-  CHECK_ZERO(pgit->zero1);
+  B2N_32(pgci->len_org_pgci);
+  CHECK_ZERO(pgci->zero1);
   return 1;
 
 }
 
-int ifoRead_PG_GI(ifo_handle_t *ifofile) {
+int ifoRead_PGC_GI(ifo_handle_t *ifofile) {
   struct ifo_handle_private_s *ifop = PRIV(ifofile);
-  pg_gi_t *pg_gi;
+  pgc_gi_t *pgc_gi;
 
-  pg_gi = malloc(sizeof(pg_gi_t));
+  pgc_gi = malloc(sizeof(pgc_gi_t));
 
-  if(!pg_gi)
+  if(!pgc_gi)
     return 0;
 
-  ifofile->pg_gi = pg_gi;
+  ifofile->pgc_gi = pgc_gi;
 
-  if(!DVDFileSeek_(ifop->file, ifofile->rtav_vmgi->org_pgci_sa)) {
-    free(ifofile->pg_gi);
-    ifofile->pg_gi = NULL;
+  /* the pgc_gi directly follows pgci */
+  uint32_t pgc_gi_sa = ifofile->rtav_vmgi->org_pgci_sa
+                     + PGCI_SIZE
+                     + ifofile->pgci->nr_of_vob_formats * VOB_FORMAT_SIZE;
+
+  if(!DVDFileSeek_(ifop->file, pgc_gi_sa )) {
+    free(ifofile->pgc_gi);
+    ifofile->pgc_gi = NULL;
     return 0;
   }
 
-  if(!DVDReadBytes(ifop->file, pg_gi, PG_GI_SIZE)) {
-    free(ifofile->pg_gi);
-    ifofile->pg_gi= NULL;
+  if(!DVDReadBytes(ifop->file, pgc_gi, PGC_GI_SIZE)) {
+    free(ifofile->pgc_gi);
+    ifofile->pgc_gi= NULL;
     return 0;
   }
 
-  B2N_16(pg_gi->nr_of_programs);
+  B2N_16(pgc_gi->nr_of_programs);
 
   /* there is a case where the original program info table is undefined or overwritten, regardless this should not be the default table used when we are navigating the disc */
-  if ( pg_gi->nr_of_programs == 0 ) {
-    free(ifofile->pg_gi);
-    ifofile->pg_gi= NULL;
+  if ( pgc_gi->nr_of_programs == 0 ) {
+    free(ifofile->pgc_gi);
+    ifofile->pgc_gi= NULL;
     return 1;
   }
 
-  pg_gi->program_offsets = calloc(pg_gi->nr_of_programs, sizeof(uint32_t));
+  pgc_gi->program_offsets = calloc(pgc_gi->nr_of_programs, sizeof(uint32_t));
 
-  if(!pg_gi->program_offsets) {
-    free(ifofile->pg_gi);
-    ifofile->pg_gi= NULL;
+  if(!pgc_gi->program_offsets) {
+    free(ifofile->pgc_gi);
+    ifofile->pgc_gi= NULL;
     return 0;
   }
 
-  if(!DVDReadBytes(ifop->file, pg_gi->program_offsets, pg_gi->nr_of_programs * sizeof(uint32_t))) {
-    free(ifofile->pg_gi->program_offsets);
-    free(ifofile->pg_gi);
-    ifofile->pg_gi= NULL;
+  if(!DVDReadBytes(ifop->file, pgc_gi->program_offsets, pgc_gi->nr_of_programs * sizeof(uint32_t))) {
+    free(ifofile->pgc_gi->program_offsets);
+    free(ifofile->pgc_gi);
+    ifofile->pgc_gi= NULL;
     return 0;
   }
 
-  pg_gi->programs= calloc(pg_gi->nr_of_programs, sizeof(program_t));
+  pgc_gi->pgi= calloc(pgc_gi->nr_of_programs, sizeof(pgi_t));
 
-  if(!pg_gi->programs) {
-    free(ifofile->pg_gi->program_offsets);
-    free(ifofile->pg_gi->programs);
-    free(ifofile->pg_gi);
-    ifofile->pg_gi= NULL;
+  if(!pgc_gi->pgi) {
+    free(ifofile->pgc_gi->program_offsets);
+    free(ifofile->pgc_gi);
+    ifofile->pgc_gi= NULL;
     return 0;
   }
 
   int i, j;
-  for(i = 0; i < pg_gi->nr_of_programs; i++) {
-    B2N_32(pg_gi->program_offsets[i]);
+  for(i = 0; i < pgc_gi->nr_of_programs; i++) {
+    B2N_32(pgc_gi->program_offsets[i]);
 
     if(!DVDFileSeek_(ifop->file, ifofile->rtav_vmgi->org_pgci_sa
-                     + pg_gi->program_offsets[i]))
+                     + pgc_gi->program_offsets[i]))
       goto fail3;
 
-    if(!DVDReadBytes(ifop->file, &pg_gi->programs[i].header, VVOB_SIZE)) {
+    if(!DVDReadBytes(ifop->file, &pgc_gi->pgi[i].header, VVOB_SIZE)) {
       goto fail3;
    }
 
-    B2N_16(pg_gi->programs[i].header.vob_attr);
-    B2N_16(pg_gi->programs[i].header.vob_v_e_ptm.ptm_extra);
-    B2N_16(pg_gi->programs[i].header.vob_v_s_ptm.ptm_extra);
-    B2N_32(pg_gi->programs[i].header.vob_v_e_ptm.ptm);
-    B2N_32(pg_gi->programs[i].header.vob_v_s_ptm.ptm);
+    B2N_16(pgc_gi->pgi[i].header.vob_attr);
+    B2N_16(pgc_gi->pgi[i].header.vob_v_e_ptm.ptm_extra);
+    B2N_16(pgc_gi->pgi[i].header.vob_v_s_ptm.ptm_extra);
+    B2N_32(pgc_gi->pgi[i].header.vob_v_e_ptm.ptm);
+    B2N_32(pgc_gi->pgi[i].header.vob_v_s_ptm.ptm);
 
 
 
     /* this entry is supposedly optional, and will not exist without this flag */
-    if(pg_gi->programs[i].header.vob_attr & 0x80) {
-      if(!DVDReadBytes(ifop->file, &pg_gi->programs[i].adj_info, ADJ_VOB_SIZE))
+    if(pgc_gi->pgi[i].header.vob_attr & 0x80) {
+      if(!DVDReadBytes(ifop->file, &pgc_gi->pgi[i].adj_info, ADJ_VOB_SIZE))
         goto fail3;
     }
 
+    /* since we're reading a struct that isn't packed , we have to
+     * skip the padding this way */
+    uint16_t pad2;
+    if(!DVDReadBytes(ifop->file, &pad2, sizeof(pad2)))
+      goto fail3;
+
     /* header of this table */
-    if(!DVDReadBytes(ifop->file, &pg_gi->programs[i].map, VOBU_MAP_SIZE))
+    if(!DVDReadBytes(ifop->file, &pgc_gi->pgi[i].map, VOBU_MAP_SIZE))
       goto fail3;
 
-    B2N_16(pg_gi->programs[i].map.nr_of_time_info);
-    B2N_16(pg_gi->programs[i].map.nr_of_vobu_info);
-    B2N_16(pg_gi->programs[i].map.time_offset);
-    B2N_32(pg_gi->programs[i].map.vob_offset);
+    B2N_16(pgc_gi->pgi[i].map.nr_of_time_info);
+    B2N_16(pgc_gi->pgi[i].map.nr_of_vobu_info);
+    B2N_16(pgc_gi->pgi[i].map.time_offset);
+    B2N_32(pgc_gi->pgi[i].map.vob_offset);
 
-    if(pg_gi->programs[i].map.nr_of_time_info > 0) {
-      pg_gi->programs[i].map.time_infos = calloc(pg_gi->programs[i].map.nr_of_time_info,
+    if(pgc_gi->pgi[i].map.nr_of_time_info > 0) {
+      pgc_gi->pgi[i].map.time_infos = calloc(pgc_gi->pgi[i].map.nr_of_time_info,
                                                  TIME_INFO_SIZE);
-      if(!pg_gi->programs[i].map.time_infos) {
-        free(pg_gi->programs[i].map.time_infos);
+      if(!pgc_gi->pgi[i].map.time_infos)
         goto fail3;
-      }
 
-      if(!DVDReadBytes(ifop->file, pg_gi->programs[i].map.time_infos,
-                       pg_gi->programs[i].map.nr_of_time_info * TIME_INFO_SIZE)) {
-        free(pg_gi->programs[i].map.time_infos);
-        free(pg_gi->programs[i].map.vobu_infos);
+      if(!DVDReadBytes(ifop->file, pgc_gi->pgi[i].map.time_infos,
+                       pgc_gi->pgi[i].map.nr_of_time_info * TIME_INFO_SIZE)) {
+        free(pgc_gi->pgi[i].map.time_infos);
         goto fail3;
       }
 
+      for(int j = 0; j < pgc_gi->pgi[i].map.nr_of_time_info; j++) {
+        B2N_16(pgc_gi->pgi[i].map.time_infos[j].vobu_entn);
+        B2N_32(pgc_gi->pgi[i].map.time_infos[j].vobu_adr);
+      }
+
     } else {
-      pg_gi->programs[i].map.time_infos = NULL;
+      pgc_gi->pgi[i].map.time_infos = NULL;
     }
 
-    if(pg_gi->programs[i].map.nr_of_vobu_info > 0) {
-      pg_gi->programs[i].map.vobu_infos = calloc(pg_gi->programs[i].map.nr_of_vobu_info,
+    if(pgc_gi->pgi[i].map.nr_of_vobu_info > 0) {
+      pgc_gi->pgi[i].map.vobu_infos = calloc(pgc_gi->pgi[i].map.nr_of_vobu_info,
                                                  VOBU_INFO_SIZE);
-      if(!pg_gi->programs[i].map.vobu_infos) {
-        free(pg_gi->programs[i].map.time_infos);
-        free(pg_gi->programs[i].map.vobu_infos);
+      if(!pgc_gi->pgi[i].map.vobu_infos) {
+        free(pgc_gi->pgi[i].map.time_infos);
         goto fail3;
       }
 
-      if(!DVDReadBytes(ifop->file, pg_gi->programs[i].map.vobu_infos,
-                     pg_gi->programs[i].map.nr_of_vobu_info * VOBU_INFO_SIZE)) {
-        free(pg_gi->programs[i].map.time_infos);
-        free(pg_gi->programs[i].map.vobu_infos);
+      if(!DVDReadBytes(ifop->file, pgc_gi->pgi[i].map.vobu_infos,
+                     pgc_gi->pgi[i].map.nr_of_vobu_info * VOBU_INFO_SIZE)) {
+        free(pgc_gi->pgi[i].map.time_infos);
+        free(pgc_gi->pgi[i].map.vobu_infos);
         goto fail3;
       }
-      for(j = 0; j<pg_gi->programs[i].map.nr_of_vobu_info; j++)
-        B2N_16(pg_gi->programs[i].map.vobu_infos[j].vobu_size);
+      for(j = 0; j<pgc_gi->pgi[i].map.nr_of_vobu_info; j++)
+        B2N_16(pgc_gi->pgi[i].map.vobu_infos[j].vobu_size);
 
     } else {
-      pg_gi->programs[i].map.vobu_infos = NULL;
+      pgc_gi->pgi[i].map.vobu_infos = NULL;
     }
   }
 
@@ -1554,64 +1577,154 @@ int ifoRead_PG_GI(ifo_handle_t *ifofile) {
 
 fail3:
   for(int k = 0; k < i; k++){
-    free(ifofile->pg_gi->programs[k].map.time_infos);
-    free(ifofile->pg_gi->programs[k].map.vobu_infos);
+    free(ifofile->pgc_gi->pgi[k].map.time_infos);
+    free(ifofile->pgc_gi->pgi[k].map.vobu_infos);
   }
-  free(ifofile->pg_gi->program_offsets);
-  free(ifofile->pg_gi->programs);
-  free(ifofile->pg_gi);
-  ifofile->pg_gi= NULL;
+  free(ifofile->pgc_gi->program_offsets);
+  free(ifofile->pgc_gi->pgi);
+  free(ifofile->pgc_gi);
+  ifofile->pgc_gi= NULL;
   return 0;
 }
 
-int ifoRead_PS_GI(ifo_handle_t *ifofile) {
+int ifoRead_UD_PGCIT(ifo_handle_t *ifofile) {
   struct ifo_handle_private_s *ifop = PRIV(ifofile);
-  ps_gi_t *ps_gi;
+  ud_pgcit_t *ud_pgcit;
+
+  ud_pgcit = malloc(sizeof(ud_pgcit_t));
+
+  if(!ud_pgcit)
+    return 0;
+
+  ifofile->ud_pgcit = ud_pgcit;
 
-  ps_gi = malloc(sizeof(ps_gi_t));
+  if(!DVDFileSeek_(ifop->file, ifofile->rtav_vmgi->ud_pgcit_sa)) {
+    free(ifofile->ud_pgcit);
+    ifofile->ud_pgcit = NULL;
+    return 0;
+  }
 
-  if(!ps_gi)
+  if(!DVDReadBytes(ifop->file, ud_pgcit, UD_PGCIT_SIZE)) {
+    free(ifofile->ud_pgcit);
+    ifofile->ud_pgcit = NULL;
     return 0;
+  }
+
+  B2N_16(ud_pgcit->total_nr_of_programs);
 
-  ifofile->ps_gi= ps_gi;
+  ud_pgcit->ud_pgci_items = calloc(ud_pgcit->nr_of_pgci, UD_PGCI_SIZE);
 
-  if(!DVDFileSeek_(ifop->file, ifofile->rtav_vmgi->def_psi_sa)) {
-    free(ifofile->ps_gi);
-    ifofile->ps_gi = NULL;
+  if(!ud_pgcit->ud_pgci_items) {
+    free(ifofile->ud_pgcit);
+    ifofile->ud_pgcit = NULL;
     return 0;
   }
 
-  if(!DVDReadBytes(ifop->file, ps_gi, PS_GI_SIZE)) {
-    free(ifofile->ps_gi);
-    ifofile->ps_gi = NULL;
+  if(!DVDReadBytes(ifop->file, ud_pgcit->ud_pgci_items, ud_pgcit->nr_of_pgci * UD_PGCI_SIZE)) {
+    free(ud_pgcit->ud_pgci_items);
+    free(ifofile->ud_pgcit);
+    ifofile->ud_pgcit = NULL;
     return 0;
   }
 
-  B2N_16(ps_gi->total_nr_of_programs);
+  for(int i = 0; i < ud_pgcit->nr_of_pgci; i++) {
+    B2N_16(ud_pgcit->ud_pgci_items[i].nr_of_programs);
+    B2N_16(ud_pgcit->ud_pgci_items[i].prog_set_id);
+    B2N_16(ud_pgcit->ud_pgci_items[i].first_prog_id);
+  }
+
+  ud_pgcit->ci_offsets = calloc(ud_pgcit->total_nr_of_programs, CI_OFFSET_SIZE);
 
-  ps_gi->psi_items = calloc(ps_gi->nr_of_psi, PSI_SIZE);
+  if(!ud_pgcit->ci_offsets) {
+    free(ud_pgcit->ud_pgci_items);
+    free(ifofile->ud_pgcit);
+    ifofile->ud_pgcit = NULL;
+    return 0;
+  }
 
-  if(!ps_gi->psi_items) {
-    free(ps_gi->psi_items);
-    free(ifofile->ps_gi);
-    ifofile->ps_gi = NULL;
+  if(!DVDReadBytes(ifop->file, ud_pgcit->ci_offsets,
+                   ud_pgcit->total_nr_of_programs * CI_OFFSET_SIZE)) {
+    free(ud_pgcit->ci_offsets);
+    free(ud_pgcit->ud_pgci_items);
+    free(ifofile->ud_pgcit);
+    ifofile->ud_pgcit = NULL;
     return 0;
   }
 
-  if(!DVDReadBytes(ifop->file, ps_gi->psi_items, ps_gi->nr_of_psi * PSI_SIZE)) {
-    free(ps_gi->psi_items);
-    free(ifofile->ps_gi);
-    ifofile->ps_gi = NULL;
+  ud_pgcit->m_c_gi = calloc(ud_pgcit->total_nr_of_programs, sizeof(m_c_gi_t) );
+  if(!ud_pgcit->m_c_gi) {
+    free(ud_pgcit->ci_offsets);
+    free(ud_pgcit->ud_pgci_items);
+    free(ifofile->ud_pgcit);
+    ifofile->ud_pgcit = NULL;
     return 0;
   }
 
-  for(int i = 0; i < ps_gi->nr_of_psi; i++) {
-    B2N_16(ps_gi->psi_items[i].nr_of_programs);
-    B2N_16(ps_gi->psi_items[i].prog_set_id);
-    B2N_16(ps_gi->psi_items[i].first_prog_id);
+  int i;
+  for ( i = 0; i < ud_pgcit->total_nr_of_programs; i++ ) {
+    B2N_32(ud_pgcit->ci_offsets[i]);
+
+    if(!DVDFileSeek_(ifop->file,
+                     ifofile->rtav_vmgi->ud_pgcit_sa + ud_pgcit->ci_offsets[i])) {
+      for (int j = 0; j < i; j++) {
+        if(ud_pgcit->m_c_gi[j].c_epi_n > 0)
+          free(ud_pgcit->m_c_gi[j].m_c_epi);
+      }
+      free(ud_pgcit->m_c_gi);
+      free(ifofile->ud_pgcit->ci_offsets);
+      free(ud_pgcit->ud_pgci_items);
+      free(ifofile->ud_pgcit);
+      ifofile->ud_pgcit = NULL;
+      return 0;
+    }
+
+    if(!DVDReadBytes(ifop->file, &ud_pgcit->m_c_gi[i], M_C_GI_SIZE)) {
+      for (int j = 0; j < i; j++) {
+        if(ud_pgcit->m_c_gi[j].c_epi_n > 0)
+          free(ud_pgcit->m_c_gi[j].m_c_epi);
+      }
+      free(ud_pgcit->m_c_gi);
+      free(ud_pgcit->ci_offsets);
+      free(ud_pgcit->ud_pgci_items);
+      free(ifofile->ud_pgcit);
+      ifofile->ud_pgcit = NULL;
+      return 0;
+    }
+
+    B2N_16(ud_pgcit->m_c_gi[i].m_vobi_srpn);
+
+    if(ud_pgcit->m_c_gi[i].c_epi_n > 0){
+      ud_pgcit->m_c_gi[i].m_c_epi = calloc(ud_pgcit->m_c_gi[i].c_epi_n, M_C_EPI_SIZE );
+
+      if(!ud_pgcit->m_c_gi[i].m_c_epi)
+        goto fail4;
+
+      if(!DVDReadBytes(ifop->file, ud_pgcit->m_c_gi[i].m_c_epi,
+                       ud_pgcit->m_c_gi[i].c_epi_n * M_C_EPI_SIZE)) {
+        free(ud_pgcit->m_c_gi[i].m_c_epi);
+        goto fail4;
+      }
+
+    }
+
   }
 
   return 1;
+
+fail4:
+
+  for ( int j = 0; j < i; j++ ) {
+    if(ud_pgcit->m_c_gi[j].c_epi_n > 0)
+      free(ud_pgcit->m_c_gi[j].m_c_epi);
+  }
+
+  free(ud_pgcit->m_c_gi);
+  free(ud_pgcit->ci_offsets);
+  free(ud_pgcit->ud_pgci_items);
+  free(ifofile->ud_pgcit);
+  ifofile->ud_pgcit = NULL;
+  return 0;
+
 }
 
 static int ifoRead_VTS(ifo_handle_t *ifofile) {



View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/e294cf7156ce8170ebb6786e21c4baf7aa5f48e4...3803c92fdc0bf5aaf9d0dd9644fd441b2f628c65

-- 
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/e294cf7156ce8170ebb6786e21c4baf7aa5f48e4...3803c92fdc0bf5aaf9d0dd9644fd441b2f628c65
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the libdvdnav-devel mailing list