[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