[libdvdnav-devel] [Git][videolan/libdvdread][master] 5 commits: DVD-Audio: safety guard for menus

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Tue Aug 12 14:40:14 UTC 2025



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


Commits:
44f2a1dc by Saifelden Mohamed Ismail at 2025-08-12T17:23:01+03:00
DVD-Audio: safety guard for menus

- - - - -
2f6f672f by Saifelden Mohamed Ismail at 2025-08-12T17:38:49+03:00
DVD-Audio: debug log for MKB

- - - - -
a2d5d91f by Saifelden Mohamed Ismail at 2025-08-12T17:38:53+03:00
DVD-Audio: document PTS type

- - - - -
2dbf6c4c by Saifelden Mohamed Ismail at 2025-08-12T17:39:21+03:00
formatting: adjusted for dvd_reader.c

- - - - -
3d973d0b by Saifelden Mohamed Ismail at 2025-08-12T17:39:24+03:00
DVD-Audio add SAMG option to DVDFileStat

- - - - -


2 changed files:

- src/dvd_reader.c
- src/dvdread/ifo_types.h


Changes:

=====================================
src/dvd_reader.c
=====================================
@@ -452,15 +452,18 @@ static uint8_t *cppm_get_mkb_or_backup( dvd_reader_t *ctx, int backup );
 /* this should only be called if libdvdcss is available and if the disc type is DVD-Audio */
 static int cpxm_init_condition( dvd_reader_t* ctx, dvd_type_t type, int have_css )
 {
-    if ( type == DVD_A && have_css ) {
-        uint8_t *p_mkb = NULL;
-        p_mkb = cppm_get_mkb_or_backup( ctx, 0 );
-        if ( !p_mkb )
-            p_mkb = cppm_get_mkb_or_backup( ctx, 1 );
-        return dvdinput_init( ctx->rd->dev, p_mkb );
-    }
-    else
-        return 0;
+  if ( type == DVD_A && have_css ) 
+  {
+    uint8_t *p_mkb = NULL;
+    p_mkb = cppm_get_mkb_or_backup( ctx, 0 );
+    if ( !p_mkb )
+      p_mkb = cppm_get_mkb_or_backup( ctx, 1 );
+    if ( !p_mkb )
+      Log2(ctx, "There is no MKB on this DVD-Audio disc, so there likely no encryption");
+    return dvdinput_init( ctx->rd->dev, p_mkb );
+  }
+  else
+    return 0;
 }
 
 static dvd_reader_t *DVDOpenCommon( void *priv,
@@ -750,7 +753,7 @@ static dvd_reader_t *DVDOpenCommon( void *priv,
 
 DVDOpen_error:
   /* If it's none of the above, screw it. */
-  Log0(ctx, "Could not open %s", path );
+  Log0( ctx, "Could not open %s", path );
   free( path );
   free( path_copy );
   if ( cdir >= 0 )
@@ -816,13 +819,13 @@ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *ctx, const char *filename,
 
   start = UDFFindFile( ctx, filename, &len );
   if( !start ) {
-    Log0(ctx, "DVDOpenFileUDF:UDFFindFile %s failed", filename );
+    Log0( ctx, "DVDOpenFileUDF:UDFFindFile %s failed", filename );
     return NULL;
   }
 
   dvd_file = calloc( 1, sizeof( dvd_file_t ) );
   if( !dvd_file ) {
-    Log0(ctx, "DVDOpenFileUDF:malloc failed" );
+    Log0( ctx, "DVDOpenFileUDF:malloc failed" );
     return NULL;
   }
   dvd_file->ctx = ctx;
@@ -954,44 +957,53 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *ctx, const char *filename )
 
 static uint8_t *cppm_get_mkb_or_backup( dvd_reader_t *ctx, int backup )
 {
-    uint8_t* p_mkb;
-    dvd_file_t* mkb_file;
-    char filename[ MAX_UDF_FILE_NAME_LEN ];
-
-    dvd_reader_device_t *dvd = ctx->rd;
-    switch(backup){
-      case 0:
-        strcpy( filename,  "/AUDIO_TS/DVDAUDIO.MKB");
-        break;
-      case 1:
-        strcpy( filename,  "/AUDIO_TS/DVDAUDIO.BUP");
-        break;
-    }
- 
-    if( dvd->isImageFile ) {
-       mkb_file= DVDOpenFileUDF( ctx, filename, 0 );
-    } else {
-       mkb_file= DVDOpenFilePath( ctx, filename );
-    }
+  uint8_t* p_mkb;
+  dvd_file_t* mkb_file;
+  char filename[ MAX_UDF_FILE_NAME_LEN ];
 
-    if ( !mkb_file )
-        return NULL;
+  dvd_reader_device_t *dvd = ctx->rd;
+  switch( backup )
+  {
+    case 0:
+      strcpy( filename,  "/AUDIO_TS/DVDAUDIO.MKB" );
+      break;
+    case 1:
+      strcpy( filename,  "/AUDIO_TS/DVDAUDIO.BUP" );
+      break;
+  }
 
-    p_mkb=malloc( mkb_file->filesize * DVD_VIDEO_LB_LEN );
-    if ( !p_mkb )
-        return NULL;
+  uint32_t len; 
 
-    if ( !DVDReadBytes( mkb_file, p_mkb, mkb_file->filesize * DVD_VIDEO_LB_LEN ) ) {
-        free( p_mkb );
-        return NULL;
-    }
+  /* exits early if there is no MKB file */
+  if( dvd->isImageFile ) 
+  {
+    if( !UDFFindFile( ctx, filename, &len ) ) return NULL;
+    mkb_file= DVDOpenFileUDF( ctx, filename, 0 );
+  } else
+  {
+    if( !findDVDFile( ctx, filename, filename ) ) return NULL;
+    mkb_file= DVDOpenFilePath( ctx, filename );
+  }
+
+  if ( !mkb_file )
+    return NULL;
+
+  p_mkb = malloc( mkb_file->filesize * DVD_VIDEO_LB_LEN );
+  if ( !p_mkb )
+    return NULL;
 
-    /* checking header */
-    if( ( !memcmp( p_mkb, "DVDAUDIO.MKB", 12 ) && !backup )
+  if ( !DVDReadBytes( mkb_file, p_mkb, mkb_file->filesize * DVD_VIDEO_LB_LEN ) ) 
+  {
+    free( p_mkb );
+    return NULL;
+  }
+
+  /* checking header */
+  if( ( !memcmp( p_mkb, "DVDAUDIO.MKB", 12 ) && !backup )
         || ( !memcmp( p_mkb, "DVDAUDIO.BUP", 12 ) && backup ) )
-        return NULL;
- 
-    return p_mkb;
+    return NULL;
+
+  return p_mkb;
 }
 
 static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *ctx, int title, int menu )
@@ -1001,10 +1013,10 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *ctx, int title, int menu )
   dvd_file_t *dvd_file;
 
   if( title == 0 ) {
-    sprintf(filename, "/%s_TS/%s_TS.VOB", DVD_TYPE_STRING( ctx->dvd_type ), DVD_TYPE_STRING( ctx->dvd_type ) );
+    sprintf( filename, "/%s_TS/%s_TS.VOB", DVD_TYPE_STRING( ctx->dvd_type ), DVD_TYPE_STRING( ctx->dvd_type ) );
   } else {
     sprintf( filename, "/%s_TS/%cTS_%02d_%d.%cOB", DVD_TYPE_STRING( ctx->dvd_type ), STREAM_TYPE_STRING( ctx->dvd_type ),
-            title, menu ? 0 : 1, STREAM_TYPE_STRING( ctx->dvd_type ));
+            title, menu ? 0 : 1, STREAM_TYPE_STRING( ctx->dvd_type ) );
   }
   start = UDFFindFile( ctx, filename, &len );
   if( start == 0 ) return NULL;
@@ -1066,9 +1078,9 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *ctx, int title, int menu )
     if( title == 0 ) {
       /* there can not be an AUDIO_TS.AOB, there is however sometimes an AUDIO_TS.VOB menu */
       sprintf(filename, "%s_TS.VOB", DVD_TYPE_STRING( ctx->dvd_type ) );
-    } else {
-      sprintf( filename, "%cTS_%02i_0.%cOB",  STREAM_TYPE_STRING( ctx->dvd_type ) , title, 
-              STREAM_TYPE_STRING( ctx->dvd_type ) );
+    } else if ( ctx->dvd_type == DVD_V ) {
+      /* there are no ATS_%02i_0.AOB's */
+      sprintf( filename, "VTS_%02i_0.VOB", title );
     }
     if( !findDVDFile( ctx, filename, full_path ) ) {
       free( dvd_file );
@@ -1155,9 +1167,12 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *ctx, int titlenum,
     break;
   case DVD_READ_MENU_VOBS:
     if( dvd->isImageFile ) {
-      return DVDOpenVOBUDF( ctx, titlenum, 1 );
+      /* there is only one DVD-Audio menu vob, this call should be restricted */
+      if ( ctx->dvd_type == DVD_A && titlenum != 0 ) 
+        Log2( ctx, "Defaulting to the only menu on DVD-Audio discs" );
+      return DVDOpenVOBUDF( ctx, ( ctx->dvd_type == DVD_V ? titlenum : 0 ), 1 );
     } else {
-      return DVDOpenVOBPath( ctx, titlenum, 1 );
+      return DVDOpenVOBPath( ctx, ( ctx->dvd_type == DVD_V ? titlenum : 0 ), 1 );
     }
     break;
   case DVD_READ_TITLE_VOBS:
@@ -1170,10 +1185,10 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *ctx, int titlenum,
     break;
   case DVD_READ_SAMG_INFO:
     /* no other way to reach SAMG menu*/
-    strcpy( filename,  "/AUDIO_TS/AUDIO_PP.IFO");
+    strcpy( filename, "/AUDIO_TS/AUDIO_PP.IFO" );
     break;
   default:
-    Log1(ctx, "Invalid domain for file open." );
+    Log1( ctx, "Invalid domain for file open." );
     return NULL;
   }
 
@@ -1215,11 +1230,11 @@ static int DVDFileStatVOBUDF( dvd_reader_t *dvd, int title,
   int n;
 
   if( title == 0 )
-    sprintf(filename, "/%s_TS/%s_TS.VOB", DVD_TYPE_STRING( dvd->dvd_type ),
+    sprintf( filename, "/%s_TS/%s_TS.VOB", DVD_TYPE_STRING( dvd->dvd_type ),
             DVD_TYPE_STRING( dvd->dvd_type ) );
   else
     sprintf( filename, "/%s_TS/%cTS_%02d_%d.%cOB", DVD_TYPE_STRING( dvd->dvd_type ), 
-            STREAM_TYPE_STRING( dvd->dvd_type ),  title, menu ? 0 : 1, STREAM_TYPE_STRING( dvd->dvd_type ) );
+            STREAM_TYPE_STRING( dvd->dvd_type ), title, menu ? 0 : 1, STREAM_TYPE_STRING( dvd->dvd_type ) );
 
   if( !UDFFindFile( dvd, filename, &size ) )
     return -1;
@@ -1264,7 +1279,7 @@ static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title,
   int n;
 
   if( title == 0 )
-    sprintf(filename, "%s_TS.VOB", DVD_TYPE_STRING( dvd->dvd_type ));
+    sprintf( filename, "%s_TS.VOB", DVD_TYPE_STRING( dvd->dvd_type ) );
   else
     sprintf( filename, "%cTS_%02d_%d.%cOB", STREAM_TYPE_STRING( dvd->dvd_type ), title, menu ? 0 : 1, 
             STREAM_TYPE_STRING( dvd->dvd_type ) );
@@ -1273,7 +1288,7 @@ static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title,
     return -1;
 
   if( dvdstat( full_path, &fileinfo ) < 0 ) {
-    Log1(dvd, "Can't stat() %s.", filename );
+    Log1( dvd, "Can't stat() %s.", filename );
     return -1;
   }
 
@@ -1290,7 +1305,7 @@ static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title,
         break;
 
       if( dvdstat( full_path, &fileinfo ) < 0 ) {
-        Log1(dvd, "Can't stat() %s.", filename );
+        Log1( dvd, "Can't stat() %s.", filename );
         break;
       }
 
@@ -1327,14 +1342,14 @@ int DVDFileStat( dvd_reader_t *reader, int titlenum,
 
   case DVD_READ_INFO_FILE:
     if( titlenum == 0 )
-      sprintf(filename, "/%s_TS/%s_TS.IFO", DVD_TYPE_STRING( reader->dvd_type ), DVD_TYPE_STRING( reader->dvd_type ));
+      sprintf( filename, "/%s_TS/%s_TS.IFO", DVD_TYPE_STRING( reader->dvd_type ), DVD_TYPE_STRING( reader->dvd_type ) );
     else
       sprintf( filename, "/%s_TS/%cTS_%02i_0.IFO", DVD_TYPE_STRING( reader->dvd_type ), STREAM_TYPE_STRING( reader->dvd_type ) ,titlenum );
 
     break;
   case DVD_READ_INFO_BACKUP_FILE:
     if( titlenum == 0 )
-      sprintf(filename, "/%s_TS/%s_TS.BUP", DVD_TYPE_STRING( reader->dvd_type ), DVD_TYPE_STRING( reader->dvd_type ) );
+      sprintf( filename, "/%s_TS/%s_TS.BUP", DVD_TYPE_STRING( reader->dvd_type ), DVD_TYPE_STRING( reader->dvd_type ) );
     else
       sprintf( filename, "/%s_TS/%cTS_%02i_0.BUP", DVD_TYPE_STRING( reader->dvd_type ), STREAM_TYPE_STRING( reader->dvd_type ), titlenum );
 
@@ -1355,6 +1370,9 @@ int DVDFileStat( dvd_reader_t *reader, int titlenum,
     else
       return DVDFileStatVOBPath( reader, titlenum, 0, statbuf );
 
+    break;
+  case DVD_READ_SAMG_INFO:
+    strcpy( filename, "/AUDIO_TS/AUDIO_PP.IFO" );
     break;
   default:
     Log1(reader, "Invalid domain for file stat." );
@@ -1374,7 +1392,7 @@ int DVDFileStat( dvd_reader_t *reader, int titlenum,
 
     if( findDVDFile( reader, filename, full_path ) ) {
       if( dvdstat( full_path, &fileinfo ) < 0 )
-        Log1(reader, "Can't stat() %s.", filename );
+        Log1( reader, "Can't stat() %s.", filename );
       else {
         statbuf->size = fileinfo.st_size;
         statbuf->nr_parts = 1;
@@ -1394,13 +1412,13 @@ int InternalUDFReadBlocksRaw( const dvd_reader_t *ctx, uint32_t lb_number,
   int ret;
 
   if( !ctx->rd->dev ) {
-    Log0(ctx, "Fatal error in block read." );
+    Log0( ctx, "Fatal error in block read." );
     return -1;
   }
 
   ret = dvdinput_seek( ctx->rd->dev, (int) lb_number );
   if( ret != (int) lb_number ) {
-    Log1(ctx, "Can't seek to block %u", lb_number );
+    Log1( ctx, "Can't seek to block %u", lb_number );
     return ret;
   }
 
@@ -1463,7 +1481,7 @@ static int DVDReadBlocksPath( const dvd_file_t *dvd_file, unsigned int offset,
       if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) {
         off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset );
         if( off < 0 || off != (int)offset ) {
-          Log1(ctx, "Can't seek to block %u", offset );
+          Log1( ctx, "Can't seek to block %u", offset );
           return off < 0 ? off : 0;
         }
         ret = dvdinput_read( dvd_file->title_devs[ i ], data,
@@ -1477,7 +1495,7 @@ static int DVDReadBlocksPath( const dvd_file_t *dvd_file, unsigned int offset,
         /* Read part 1 */
         off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset );
         if( off < 0 || off != (int)offset ) {
-          Log1(ctx, "Can't seek to block %u", offset );
+          Log1( ctx, "Can't seek to block %u", offset );
           return off < 0 ? off : 0;
         }
         ret = dvdinput_read( dvd_file->title_devs[ i ], data,
@@ -1493,7 +1511,7 @@ static int DVDReadBlocksPath( const dvd_file_t *dvd_file, unsigned int offset,
         /* Read part 2 */
         off = dvdinput_seek( dvd_file->title_devs[ i + 1 ], 0 );
         if( off < 0 || off != 0 ) {
-          Log1(ctx, "Can't seek to block %d", 0 );
+          Log1( ctx, "Can't seek to block %d", 0 );
           return off < 0 ? off : 0;
         }
         ret2 = dvdinput_read( dvd_file->title_devs[ i + 1 ],
@@ -1606,7 +1624,7 @@ ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
 
   secbuf_base = malloc( numsec * DVD_VIDEO_LB_LEN + 2048 );
   if( !secbuf_base ) {
-    Log0(ctx, "Can't allocate memory for file read" );
+    Log0( ctx, "Can't allocate memory for file read" );
     return 0;
   }
   secbuf = (unsigned char *)(((uintptr_t)secbuf_base & ~((uintptr_t)2047)) + 2048);


=====================================
src/dvdread/ifo_types.h
=====================================
@@ -465,7 +465,7 @@ typedef struct {
   uint16_t zero_1;
   uint8_t  group_num;
   uint8_t  chapter_num; /* chapter number within group*/
-  uint32_t timestamp_pts;
+  uint32_t timestamp_pts; /* this is MPEG time, Not DVD time */
   uint32_t chapter_len;
   uint32_t zero_2;
   uint8_t  record_code;
@@ -542,7 +542,8 @@ typedef struct {
   uint8_t  nr_chapters_in_title;
   uint8_t  nr_visible_chapters_in_vts_title; /* this will be zeros in an audio record */
   uint8_t  zero_1;
-  uint32_t len_audio_zone_pts;
+  uint32_t len_audio_zone_pts; /* this is MPEG time, Not DVD time */
+
   uint8_t  group_property; /* in a video track, this is video titleset number, in audio its rank of group */
   uint8_t  title_property; /* in video track this is title number , in audio track this is rank of title*/
   uint32_t ts_pointer_relative_sector; /* for ats or vts*/
@@ -851,8 +852,10 @@ typedef struct {
   uint16_t unknown_2; /* will be 0x0000*/
   uint8_t  track_number_in_title;
   uint8_t  unknown_3; /* will be 0x00*/
-  uint32_t first_pts_of_track;
-  uint32_t length_pts_of_track;
+  uint32_t first_pts_of_track; /* this is MPEG time, Not DVD time */
+
+  uint32_t length_pts_of_track; /* this is MPEG time, Not DVD time */
+
   uint8_t  zero[6];
 } ATTRIBUTE_PACKED atsi_track_timestamp_t;
 #define ATSI_TRACK_TIMESTAMP_SIZE 20U
@@ -869,7 +872,8 @@ typedef struct {
   uint16_t unknown_1; /* will be 0x0000*/
   uint8_t  nr_tracks; /* unsure if this holds up for other files*/
   uint8_t  nr_pointer_records; /* unsure if this holds up for other files*/
-  uint32_t length_pts;
+  uint32_t length_pts; /* this is MPEG time, Not DVD time */
+
   uint16_t unknown_3; /* will be 0x0000*/
   uint16_t unknown_4; /* will be 0x0010*/
   uint16_t start_sector_pointers_table; /* pointer to start of sector pointers table, relative to start of title record*/



View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/b0a00e6ca57bd2a69484b665772cc6d5c7e7d2c4...3d973d0be47a009a1468b3b9340c1c290bf5ee4a

-- 
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/b0a00e6ca57bd2a69484b665772cc6d5c7e7d2c4...3d973d0be47a009a1468b3b9340c1c290bf5ee4a
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