From gitlab at videolan.org Tue Feb 17 22:58:23 2026 From: gitlab at videolan.org (Jean-Baptiste Kempf (@jbk)) Date: Tue, 17 Feb 2026 23:58:23 +0100 Subject: [libdvdnav-devel] [Git][videolan/libdvdread][master] 8 commits: Refactor: Rename variables to match DVD-VR patent Message-ID: <6994f28f82f4d_caee915d1ab90163685f@gitlab.mail> 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; jprograms[i].map.nr_of_vobu_info; j++) - B2N_16(pg_gi->programs[i].map.vobu_infos[j].vobu_size); + for(j = 0; jpgi[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