[libdvdnav-devel] [Git][videolan/libdvdread][master] 6 commits: Fix AMGI_MAT start address fields

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Jul 26 14:34:07 UTC 2026



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


Commits:
b9d167b2 by Kacper Michajłow at 2026-07-24T17:12:11+02:00
Fix AMGI_MAT start address fields

Bytes 192-207 of the AMGI_MAT were misread as several unrelated 16-bit
fields. They hold the start sectors of the AMGM_VOBS, the ATT_SRPT, the
AOTT_SRPT and the AMGM_PGCI_UT. Read the title search pointer tables at
their recorded location instead of assuming sectors 1 and 2, and
validate the address against the AMGI size.

- - - - -
b90c575d by Kacper Michajłow at 2026-07-24T17:12:11+02:00
Fix ASVS information layout

The management table of AUDIO_SV.IFO was partly misread. Bytes 16-23
are the 32-bit start sector of the ASVOBS (always 2, right after the two
information sectors) and the end sector of the last still, not 16-bit
attribute and end fields. Bytes 24-31 hold four 2-byte still picture
attributes whose low byte describes the sub-picture setup, followed by
the 16 palette entries; the attributes were absorbed into a shifted
palette array. Each ASVU_GI entry is the number of stills, the
attribute slot the unit uses, the first still number and a 32-bit start
sector relative to the ASVOBS.

Each search pointer is the still's start sector offset from its unit
start in the low 14 bits. The top two bits are copy control, not
address: every CPPM disc, and only those, sets the top bit on all
pointers, one also the second bit. Layouts verified against ~20 discs by
matching the computed sectors to the still VOBs' navigation packs; US
6,564,006 and JP 2002-288942 document the tables.

Also accept the specification version zero that a few discs write, and
bound the pointer count by the two sector table size.

- - - - -
63a32c98 by Kacper Michajłow at 2026-07-24T17:12:11+02:00
Identify the AMGI_MAT provider ID

Bytes 64-95 of the AMGI_MAT are the provider unique ID, the same field
the VMGI_MAT has at 192-223 (PVR_ID, US 2001/0008578 FIG. 18).

- - - - -
2f70afb7 by Kacper Michajłow at 2026-07-24T17:12:11+02:00
Fix the ASV display list fields

US 6,788,880 FIG. 98 to 101 give the display list record: byte 1 is
reserved and byte 2 is the number of the initially selected button
(FOSL_BTNN), the reverse of what the guessed names said, and the last
two bytes each split into a transition effect mode and period nibble.

- - - - -
3417c8f6 by Kacper Michajłow at 2026-07-24T17:12:11+02:00
Fix the backup handling of the audio IFO open helpers

The ifoOpenASVS loop over AUDIO_SV.IFO and AUDIO_SV.BUP returned on the
first open failure, so the backup was never tried when the IFO is
missing.  ifoOpenSAMG had the same early return, inside a loop that
could never vary what it opens: the simple audio play pointer has no
backup file, so drop the loop.

- - - - -
cf03e866 by Kacper Michajłow at 2026-07-24T17:12:11+02:00
Fix the SAMG specification version field

Byte 14 of AUDIO_PP.IFO is not the upper half of a 16-bit version; it
varies between discs (0, 1 and 2 seen) independently of the 0x12 in byte
15. Split the field and sanity check the version, accepting the zero a
few discs write.

- - - - -


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
=====================================
@@ -215,12 +215,13 @@ DVDREAD_API int ifoRead_TXTDT_MGI(ifo_handle_t *);
 DVDREAD_API int ifoRead_TT(ifo_handle_t *);
 
 /**
- * okay = ifoRead_TIF(ifofile);
+ * okay = ifoRead_TIF(ifofile, table_nr);
  *
- * Reads either table in AUDIO_TS.IFO based on the sector offset given,
- * either 1,2. The first table being one with video titles, the second one
- * without. This structure. This structure is mandatory, and must be included
- * in the AMGI file.
+ * Reads one of the two title search pointer tables of AUDIO_TS.IFO.
+ * Table 1 is the ATT_SRPT, which on a hybrid disc also lists the titles in
+ * the video zone. Table 2 is the AOTT_SRPT, which lists audio zone titles only.
+ * Without video titles both tables list the same titles. Both tables are
+ * mandatory in the AMGI file.
  */
 DVDREAD_API int ifoRead_TIF(ifo_handle_t *, int);
 


=====================================
src/dvdread/ifo_types.h
=====================================
@@ -538,23 +538,24 @@ typedef struct {
   uint32_t timestamp_pts; /* this is MPEG time, Not DVD time */
   uint32_t chapter_len;
   uint32_t zero_2;
-  uint8_t  record_code;
+  uint8_t  record_code; /* the top bit is set on the first chapter of a group */
   uint8_t  bit_depth;
   uint8_t  sampling_rate;
   uint8_t  nr_channels; 
   /* some DVD's made with authoring software keep downmix coefficients here */
   /* since I do not have samples of commercial discs that do this, I will not include it */
   uint8_t  zero_3[20];
-  uint32_t start_sector_1; /*aob start sector*/
-  uint32_t start_sector_2; /*aob start sector is repeated again */
-  uint32_t end_sector;
+  uint32_t start_sector_1; /* first sector of the chapter, an absolute sector of the volume */
+  uint32_t start_sector_2; /* the same sector repeated again */
+  uint32_t end_sector;     /* last sector of the chapter, absolute */
 } ATTRIBUTE_PACKED samg_chapter_t;
 #define SAMG_CHAPTER_SIZE 52U
 
 typedef struct {
   char           samg_identifier[12];
   uint16_t       nr_chapters;
-  uint16_t       specification_version;
+  uint8_t        unknown_1;             /* 0, 1 or 2 seen, not the volume number */
+  uint8_t        specification_version; /* 0x12, a few discs write zero */
   samg_chapter_t *samg_chapters;
 } ATTRIBUTE_PACKED samg_mat_t;
 #define SAMG_MAT_SIZE 16U
@@ -585,28 +586,27 @@ typedef struct {
   uint8_t  zero_4[8];
   uint8_t  vmg_nr_of_title_sets;  /* Number of video titlesets in audio zone. */
   uint8_t  amg_nr_of_title_sets;  /* Number of audio titlesets in audio zone. */
-  uint8_t  unknown_2[32]; /* may be set to zeros */
+  char     provider_identifier[32];
   uint8_t  unknown_3[8]; /* may be set to zeros */
   uint8_t  zero_5[24];  
   uint32_t amg_end_byte_address;
   uint8_t  unknown_4[4]; /* may be set to zeros */
-  uint8_t  zero_6[56];  
-  uint16_t menu_prescence_1; /* may be set to zero, or some other value, optional field*/
-  uint8_t  unknown_5[4];  
-  uint16_t unknown_6; /* should be 0x01 */
-  uint8_t  zero_7[2];  
-  uint16_t amg_nr_of_zones; /* may be set to 0x02*/
-  uint8_t  zero_8[2];  
-  uint16_t menu_prescence_2; /* may be set to 0x03*/
-  uint8_t  zero_9[48];  
-  uint8_t  last_sector_audio_sys_space;  
-  uint8_t  zero_10[79];  
+  uint8_t  zero_6[56];
+  uint32_t amgm_vobs_sa;    /* start sector of the menu AMGM_VOBS; zero without a menu */
+  uint32_t att_srpt_sa;     /* start sector of the audio title SRPT */
+  uint32_t aott_srpt_sa;    /* start sector of the audio only title SRPT */
+  uint32_t amgm_pgci_ut_sa; /* start sector of the menu PGCI unit table */
+  uint8_t  zero_9[48];
+  uint8_t  last_sector_audio_sys_space;
+  uint8_t  zero_10[79];
   uint8_t  menu_prescence_3; /* will be set to 0x01*/
     /* XXX lots of padding after this to complete the sector*/
 } ATTRIBUTE_PACKED amgi_mat_t;
 #define AMGI_MAT_SIZE 337U
 
-/* Sector 2 may have video tracks, sector 3 will not. If there are no video tracks the tables will be the same*/
+/* The ATT_SRPT (at att_srpt_sa) may have video tracks, the AOTT_SRPT (at
+ * aott_srpt_sa) will not. If there are no video tracks the tables will be
+ * the same */
 
 /*this struct repeats for every audio or video track*/
 typedef struct {
@@ -953,7 +953,7 @@ typedef struct {
 typedef struct {
   uint8_t  asvu_n;      /* 1-based ASVU number holding this program's stills, several programs may share one */
   struct ATTRIBUTE_PACKED {
-    uint8_t order   : 2; /* only 0 (sequential) seen */
+    uint8_t order   : 2; /* 0 sequential, 1 random, 3 shuffle; only 0 seen */
     uint8_t timing  : 2; /* 0 timed slideshow, 1 user browsable */
     uint8_t zero    : 4;
   } dmod;
@@ -966,16 +966,19 @@ typedef struct {
  * One still picture. These records follow the entry table and run up to the
  * largest end_value in that table. asv_number starts again at 1 for each still
  * video unit. display_timing holds the picture's MPEG time in slideshow mode
- * and is 0 in browsable mode.
+ * and is 0 in browsable mode. In random and shuffle order asv_number is
+ * reserved, and in browsable mode track_nr is.
  */
 typedef struct {
-  uint8_t  asv_number;                  /* the still's number within its unit, restarting at 1 each unit */
-  uint8_t  fosl_btnn;                   /* probably the initial button number, only 0x00 seen */
-  uint8_t  unknown_a;                   /* 0 in slideshow mode, a small often sequential value in browsable mode, maybe a menu page marker */
-  uint8_t  track_nr;                    /* on a shared slideshow, which track the still belongs to, unused when each track has its own stills */
-  uint32_t display_timing;              /* when the still is shown, an MPEG PTS, 0 in browsable mode */
-  uint8_t  start_transition_mode;       /* probably a transition effect, only 0x00 seen */
-  uint8_t  termination_transition_mode; /* probably a transition effect, only 0x00 seen */
+  uint8_t  asv_number;     /* the still's number within its unit, restarting at 1 each unit */
+  uint8_t  reserved;       /* always 0x00 */
+  uint8_t  fosl_btnn;      /* number of the button selected first on a menu still */
+  uint8_t  track_nr;       /* on a shared slideshow, which track the still belongs to, unused when each track has its own stills */
+  uint32_t display_timing; /* when the still is shown, an MPEG PTS, 0 in browsable mode */
+  struct ATTRIBUTE_PACKED {
+    uint8_t period : 4;    /* transition length */
+    uint8_t mode   : 4;    /* transition effect */
+  } start_effect, end_effect;
 } ATTRIBUTE_PACKED asv_dlist_t;
 #define ASV_DLIST_SIZE 10U
 
@@ -1012,49 +1015,58 @@ typedef struct {
  * ASVS
  *
  * Structures relating to the Audio Still Video Set (ASVS).
- */
-
-/**
- * An ASVU groups the still pictures (P_VOBs) that are loaded before the
- * matching audio program plays. Each P_VOB is one still I-picture.
  *
- * ASV_SRPT addressing: each pointer is an offset from the parent ASVU
- * ref_start_sector, so the still sits at ref_start_sector + (value & 0x7fff).
- * The high bit (0x8000) does not select an addressing mode. Some discs set it
- * on every pointer and some leave it clear, and either way the offset is
- * counted from ref_start_sector.
+ * An ASVU groups the still pictures (ASVs) that are loaded before the
+ * matching audio program plays. Each ASV is one still I-picture with
+ * optional sub-picture streams.
  */
 
 /* general information for one Audio Still Video Unit */
 typedef struct {
-  uint8_t  p_vob_ns;           /* number of still pictures in this unit */
-  uint8_t  unknown_1;
-  uint16_t start_p_vob_number; /* number of this unit's first still picture, 1-based */
-  uint16_t zero_1;
-  uint16_t ref_start_sector;   /* base sector the unit's relative pointers count from */
+  uint8_t  asv_ns;         /* number of still pictures in this unit */
+  uint8_t  asvu_atrn;      /* which asvu_atr slot describes this unit's stills */
+  uint16_t first_abs_asvn; /* number of this unit's first still picture, 1-based */
+  uint32_t asvu_sa;        /* start sector of the unit, counted from the first
+                              sector of the ASVOBS (AUDIO_SV.VOB) */
 } ATTRIBUTE_PACKED asvu_gi_t;
 #define ASVU_GI_SIZE 8U
 #define ASVU_GI_MAX_SIZE 99U
 
-/* search pointer to one still picture, see the addressing note above */
-typedef uint16_t asv_srpt_t;
+/**
+ * Search pointer to one still picture. The still starts at sector
+ * asvu_sa + offset of its unit. The top two bits are not part of the
+ * address.
+ */
+typedef struct {
+  uint16_t offset : 14;
+  uint16_t cci    : 2;
+} ATTRIBUTE_PACKED asv_srpt_t;
 #define ASV_SRPT_SIZE 2U
 
+/* the ASV_SRPT must fit in the two sector ASVS information */
+#define ASV_MAX_NR ((2 * 2048 - ASVS_MAT_SIZE) / ASV_SRPT_SIZE)
+
 /**
  * Audio Still Video Set Management Table. Exclusive to DVD-Audio discs
  */
 typedef struct {
   char          asvs_identifier[12];   /* DVDAUDIOASVS */
   uint16_t      asvs_nr_of_asvus;      /* number of still video units in asvu_gi */
-  uint16_t      specification_version; /* always 0x0012 */
-  uint16_t      zero_1;
-  uint16_t      asvu_atr;              /* unit attributes, only 0x0002 seen */
-  uint16_t      zero_2;
-  uint16_t      p_vobs_ea;             /* end of the still picture area, in sectors */
-  uint32_t      p_vobs_sp_plt[16];     /* sub-picture palette, 16 colours, default 0x00108080 */
-  uint8_t       unknown_2[8];          /* trailing 8 bytes, usually more palette words */
+  uint16_t      specification_version; /* 0x0012, a few discs write zero */
+  uint32_t      asvobs_sa;             /* start sector of the still picture area,
+                                          counted from the ASVS start; always 2,
+                                          right after this two sector table */
+  uint32_t      asv_ea;                /* last sector of the last still picture,
+                                          counted from the first ASVOBS sector */
+  uint16_t      asvu_atr[4];           /* still picture attributes, selected per
+                                          unit by asvu_atrn; the low byte holds
+                                          the sub-picture setup: 0x00 no streams,
+                                          0x03 one stream, 0x05 two streams */
+  uint32_t      sp_plt[16];            /* sub-picture palette, 16 colours,
+                                          0x00YYCrCb, default 0x00108080 */
   asvu_gi_t     asvu_gi[ASVU_GI_MAX_SIZE]; /* size determined by asvs_nr_of_asvus */
-  asv_srpt_t   *asv_srpt;              /* length is the sum of p_vob_ns over asvu_gi */
+  asv_srpt_t   *asv_srpt;              /* one per still picture, the sum of
+                                          asv_ns over asvu_gi */
 } ATTRIBUTE_PACKED asvs_mat_t;
 #define ASVS_MAT_SIZE 888U
 


=====================================
src/ifo_print.c
=====================================
@@ -512,8 +512,12 @@ void ifoPrint_AMGI_MAT(amgi_mat_t *amgi_mat) {
   printf("Audio_SV ifo relative pointer: %08x\n", amgi_mat->audio_sv_ifo_relative_p);
   printf("VMG Number of title sets: %i\n", amgi_mat->vmg_nr_of_title_sets);
   printf("AMG Number of title sets: %i\n", amgi_mat->amg_nr_of_title_sets);
+  printf("Provider ID: %.32s\n", amgi_mat->provider_identifier);
   printf("End byte address: %08x\n", amgi_mat->amg_end_byte_address);
-  printf("AMG Number of zones: %i\n", amgi_mat->amg_nr_of_zones);
+  printf("Start sector of AMGM_VOBS: %08x\n", amgi_mat->amgm_vobs_sa);
+  printf("Start sector of ATT_SRPT: %08x\n", amgi_mat->att_srpt_sa);
+  printf("Start sector of AOTT_SRPT: %08x\n", amgi_mat->aott_srpt_sa);
+  printf("Start sector of AMGM_PGCI_UT: %08x\n", amgi_mat->amgm_pgci_ut_sa);
   printf("Last sector of audio system space: %02x\n", amgi_mat->last_sector_audio_sys_space);
 
 }


=====================================
src/ifo_read.c
=====================================
@@ -200,6 +200,9 @@ CHECK_STRUCT_SIZE(atsi_track_pointer_t,   0, ATSI_TRACK_POINTER_SIZE);
 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(asvu_gi_t,              0, ASVU_GI_SIZE);
+CHECK_STRUCT_SIZE(asv_srpt_t,             0, ASV_SRPT_SIZE);
+CHECK_STRUCT_SIZE(asvs_mat_t,             1, ASVS_MAT_SIZE);
 CHECK_STRUCT_SIZE(rtav_vmgi_t,            0, RTAV_VMGI_SIZE);
 CHECK_STRUCT_SIZE(pgci_t,                 1, PGCI_SIZE);
 CHECK_STRUCT_SIZE(pgc_gi_t,               2, PGC_GI_SIZE);
@@ -680,10 +683,10 @@ ifo_handle_t *ifoOpenASVS(dvd_reader_t *ctx) {
 
     ifop->ctx = ctx;
     ifop->file = DVDOpenFile(ctx, 0, domain);
-    if(!ifop->file) { /* Should really catch any error */
+    if(!ifop->file) {
       Log1(ctx, "Can't open file AUDIO_SV.%s.", ext);
       free(ifop);
-      return NULL;
+      continue;
     }
 
 
@@ -709,31 +712,26 @@ ifo_handle_t * ifoOpenSAMG(dvd_reader_t *ctx) {
     return NULL;
   }
 
-  struct ifo_handle_private_s *ifop;
-
-  for(int backup = ifoGetBupFlag(ctx, 0); backup <= 1; backup++)
-  {
-    ifop = calloc(1, sizeof(*ifop));
-    if(!ifop)
-      return NULL;
-
-    ifop->ctx = ctx;
-    ifop->file = DVDOpenFile(ctx, 0, DVD_READ_SAMG_INFO);
-    if(!ifop->file) { /* Should really catch any error */
-      Log1(ctx, "Can't open file AUDIO_PP.IFO.");
-      free(ifop);
-      return NULL;
-    }
-
+  /* the simple audio play pointer has no backup file */
+  struct ifo_handle_private_s *ifop = calloc(1, sizeof(*ifop));
+  if(!ifop)
+    return NULL;
 
-    if (ifoRead_SAMG(&ifop->handle)) {
-      ifop->handle.ifo_format = IFO_AUDIO;
-      return &ifop->handle;
-    }
+  ifop->ctx = ctx;
+  ifop->file = DVDOpenFile(ctx, 0, DVD_READ_SAMG_INFO);
+  if(!ifop->file) {
+    Log1(ctx, "Can't open file AUDIO_PP.IFO.");
+    free(ifop);
+    return NULL;
+  }
 
-    Log1(ctx, "ifoOpenSAMG(): Invalid SAMG IFO (AUDIO_PP.IFO).");
-    ifoClose(&ifop->handle);
+  if (ifoRead_SAMG(&ifop->handle)) {
+    ifop->handle.ifo_format = IFO_AUDIO;
+    return &ifop->handle;
   }
+
+  Log1(ctx, "ifoOpenSAMG(): Invalid SAMG IFO (AUDIO_PP.IFO).");
+  ifoClose(&ifop->handle);
   return NULL;
 }
 
@@ -981,7 +979,8 @@ static int ifoRead_SAMG(ifo_handle_t *ifofile) {
   }
  
   B2N_16(samg_mat->nr_chapters);
-  B2N_16(samg_mat->specification_version);
+  CHECK_VALUE(samg_mat->specification_version == 0x12
+              || samg_mat->specification_version == 0);
 
   samg_mat->samg_chapters = calloc(samg_mat->nr_chapters, sizeof(samg_chapter_t));
   if(!samg_mat->samg_chapters) {
@@ -1045,7 +1044,12 @@ static int ifoRead_ASVS(ifo_handle_t *ifofile){
 
   B2N_16(asvs_mat->asvs_nr_of_asvus);
   B2N_16(asvs_mat->specification_version);
-  B2N_16(asvs_mat->p_vobs_ea);
+  B2N_32(asvs_mat->asvobs_sa);
+  B2N_32(asvs_mat->asv_ea);
+  for (int i = 0; i < 4; i++)
+    B2N_16(asvs_mat->asvu_atr[i]);
+  for (int i = 0; i < 16; i++)
+    B2N_32(asvs_mat->sp_plt[i]);
 
   /* a broken disc could ask for more groups than fit */
   if(asvs_mat->asvs_nr_of_asvus > ASVU_GI_MAX_SIZE) {
@@ -1056,12 +1060,16 @@ static int ifoRead_ASVS(ifo_handle_t *ifofile){
 
   int total_nr_frames = 0;
   for (int i = 0; i < asvs_mat->asvs_nr_of_asvus; i++ ) {
-    B2N_16(asvs_mat->asvu_gi[i].start_p_vob_number);
-    B2N_16(asvs_mat->asvu_gi[i].ref_start_sector);
-    CHECK_ZERO(asvs_mat->asvu_gi[i].zero_1);
-    total_nr_frames+=asvs_mat->asvu_gi[i].p_vob_ns;
+    B2N_16(asvs_mat->asvu_gi[i].first_abs_asvn);
+    B2N_32(asvs_mat->asvu_gi[i].asvu_sa);
+    total_nr_frames+=asvs_mat->asvu_gi[i].asv_ns;
   }
 
+  if(total_nr_frames > (int)ASV_MAX_NR) {
+    free(ifofile->asvs_mat);
+    ifofile->asvs_mat = NULL;
+    return 0;
+  }
 
   asvs_mat->asv_srpt = calloc(total_nr_frames, ASV_SRPT_SIZE);
   if(!asvs_mat->asv_srpt) {
@@ -1078,13 +1086,14 @@ static int ifoRead_ASVS(ifo_handle_t *ifofile){
     return 0;
   }
 
+  uint16_t *asv_srpt_raw = (uint16_t *)asvs_mat->asv_srpt;
   for(int i = 0; i < total_nr_frames; i++)
-    B2N_16(asvs_mat->asv_srpt[i]);
-
+    B2N_16(asv_srpt_raw[i]);
 
-  CHECK_VALUE(asvs_mat->specification_version == 0x0012);
-  CHECK_ZERO(asvs_mat->zero_1);
-  CHECK_ZERO(asvs_mat->zero_2);
+  /* a few discs write zero here */
+  CHECK_VALUE(asvs_mat->specification_version == 0x0012
+              || asvs_mat->specification_version == 0);
+  CHECK_VALUE(asvs_mat->asvobs_sa == 2);
   return 1;
 
 }
@@ -1282,9 +1291,17 @@ int ifoRead_TT(ifo_handle_t *ifofile) {
       return 0;
 }
 
-int ifoRead_TIF(ifo_handle_t *ifofile, int sector_offset) {
+int ifoRead_TIF(ifo_handle_t *ifofile, int table_nr) {
   /* check early if sector_offset corresponds to one of the tables */
-  if (sector_offset != 2 && sector_offset != 1)
+  if (table_nr != 2 && table_nr != 1)
+    return 0;
+
+  if (!ifofile->amgi_mat)
+    return 0;
+
+  uint32_t sector = table_nr == 1 ? ifofile->amgi_mat->att_srpt_sa
+                                  : ifofile->amgi_mat->aott_srpt_sa;
+  if (sector == 0 || sector > ifofile->amgi_mat->amgi_last_sector)
     return 0;
 
   struct ifo_handle_private_s *ifop = PRIV(ifofile);
@@ -1294,7 +1311,7 @@ int ifoRead_TIF(ifo_handle_t *ifofile, int sector_offset) {
   if(!tracks_info_table)
     return 0;
 
-  if(!DVDFileSeek_(ifop->file,DVD_BLOCK_LEN * sector_offset)) {
+  if(!DVDFileSeek_(ifop->file, DVD_BLOCK_LEN * sector)) {
     free(tracks_info_table);
     return 0;
   }
@@ -1322,7 +1339,7 @@ int ifoRead_TIF(ifo_handle_t *ifofile, int sector_offset) {
 
   /* the second table is an audio_ts only table, the first is audio_ts, video_ts, strangly the nr_titles in second table doesnt match up with the true nr_titles for this table. Need to subtract video titles*/
   for(int i=0; i<tracks_info_table->nr_of_titles; i++) {
-    if(tracks_info_table->tracks_info[i].type_and_rank==0 && sector_offset == 2) {
+    if(tracks_info_table->tracks_info[i].type_and_rank==0 && table_nr == 2) {
       track_info_t *resized = realloc(tracks_info_table->tracks_info, i * sizeof(track_info_t));
       if(resized || i == 0)
         tracks_info_table->tracks_info = resized;
@@ -1338,12 +1355,12 @@ int ifoRead_TIF(ifo_handle_t *ifofile, int sector_offset) {
   /* sector table two's size and end byte are always the same as sector one's table
    * even though it will be equal to or smaller, since it only lists audio titles 
    * sector two's table has been resized in the ifo to match it's true size */
-  if(sector_offset == 1)
-    CHECK_VALUE( (TRACKS_INFO_TABLE_SIZE + 
+  if(table_nr == 1)
+    CHECK_VALUE( (TRACKS_INFO_TABLE_SIZE +
                   tracks_info_table->nr_of_titles * TRACK_INFO_SIZE -
                   1) == tracks_info_table->last_byte_in_table );
 
-  switch(sector_offset) {
+  switch(table_nr) {
     case 1:
       ifofile->info_table_first_sector = tracks_info_table;
       break;
@@ -1392,15 +1409,16 @@ static int ifoRead_AMG(ifo_handle_t *ifofile) {
   B2N_16(amgi_mat->amg_nr_of_volumes);
   B2N_16(amgi_mat->specification_version);
   B2N_16(amgi_mat->amg_this_volume_nr);
-  B2N_16(amgi_mat->amg_nr_of_zones);
+  B2N_32(amgi_mat->amgm_vobs_sa);
+  B2N_32(amgi_mat->att_srpt_sa);
+  B2N_32(amgi_mat->aott_srpt_sa);
+  B2N_32(amgi_mat->amgm_pgci_ut_sa);
   CHECK_ZERO(amgi_mat->zero_1);
   CHECK_ZERO(amgi_mat->zero_2);
   CHECK_ZERO(amgi_mat->zero_3);
   CHECK_ZERO(amgi_mat->zero_4);
   CHECK_ZERO(amgi_mat->zero_5);
   CHECK_ZERO(amgi_mat->zero_6);
-  CHECK_ZERO(amgi_mat->zero_7);
-  CHECK_ZERO(amgi_mat->zero_8);
   CHECK_ZERO(amgi_mat->zero_9);
   CHECK_ZERO(amgi_mat->zero_10);
   CHECK_VALUE(amgi_mat->specification_version == 0x0012);



View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/8e43bfea6cc731f48902ce55e41c540b497b6a84...cf03e8662f3848bb7992788cee7f14bcbdb2b779

-- 
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/8e43bfea6cc731f48902ce55e41c540b497b6a84...cf03e8662f3848bb7992788cee7f14bcbdb2b779
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the libdvdnav-devel mailing list