[libdvdnav-devel] [Git][videolan/libdvdread][master] 5 commits: ifo_read: refactor and fix BUP fallback
Jean-Baptiste Kempf
gitlab at videolan.org
Sun Mar 1 12:23:58 CET 2020
Jean-Baptiste Kempf pushed to branch master at VideoLAN / libdvdread
Commits:
89a5fce5 by Francois Cartegnie at 2020-02-24T16:18:51+01:00
ifo_read: refactor and fix BUP fallback
- - - - -
8ca9828e by Francois Cartegnie at 2020-02-24T16:18:51+01:00
handle VTSI fallback
- - - - -
18b176cb by Francois Cartegnie at 2020-02-24T16:18:51+01:00
handle VMGI fallback
- - - - -
1a01c64c by Francois Cartegnie at 2020-02-24T16:18:51+01:00
Change dvd_reader_t for a real global context
dvd_reader_t is only accessible by dvd_reader.c
- - - - -
6c463b78 by Francois Cartegnie at 2020-02-24T16:18:51+01:00
flag broken IFO to load BUP instead
Fallback isn't done for VMGI. We need to store
earlier IFO fallback state.
Fixes playback with crafted/corrupted IFO
- - - - -
6 changed files:
- src/dvd_reader.c
- src/dvd_udf.c
- src/dvdread/dvd_reader.h
- src/dvdread/dvd_udf.h
- src/dvdread_internal.h
- src/ifo_read.c
Changes:
=====================================
src/dvd_reader.c
=====================================
@@ -79,7 +79,7 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz )
#define DEFAULT_UDF_CACHE_LEVEL 1
-struct dvd_reader_s {
+struct dvd_reader_device_s {
/* Basic information. */
int isImageFile;
@@ -103,7 +103,7 @@ struct dvd_reader_s {
struct dvd_file_s {
/* Basic information. */
- dvd_reader_t *dvd;
+ dvd_reader_t *ctx;
/* Hack for selecting the right css title. */
int css_title;
@@ -129,9 +129,9 @@ struct dvd_file_s {
* level = 0 (no caching)
* level = 1 (caching filesystem info)
*/
-int DVDUDFCacheLevel(dvd_reader_t *device, int level)
+int DVDUDFCacheLevel(dvd_reader_t *reader, int level)
{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
+ dvd_reader_device_t *dev = reader->rd;
if(level > 0) {
level = 1;
@@ -144,16 +144,16 @@ int DVDUDFCacheLevel(dvd_reader_t *device, int level)
return level;
}
-void *GetUDFCacheHandle(dvd_reader_t *device)
+void *GetUDFCacheHandle(dvd_reader_t *reader)
{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
+ dvd_reader_device_t *dev = reader->rd;
return dev->udfcache;
}
-void SetUDFCacheHandle(dvd_reader_t *device, void *cache)
+void SetUDFCacheHandle(dvd_reader_t *reader, void *cache)
{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
+ dvd_reader_device_t *dev = reader->rd;
dev->udfcache = cache;
}
@@ -161,8 +161,9 @@ void SetUDFCacheHandle(dvd_reader_t *device, void *cache)
/* Loop over all titles and call dvdcss_title to crack the keys. */
-static int initAllCSSKeys( dvd_reader_t *dvd )
+static int initAllCSSKeys( dvd_reader_t *ctx )
{
+ dvd_reader_device_t *dvd = ctx->rd;
struct timeval all_s, all_e;
struct timeval t_s, t_e;
char filename[ MAX_UDF_FILE_NAME_LEN ];
@@ -186,7 +187,7 @@ static int initAllCSSKeys( dvd_reader_t *dvd )
} else {
sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 0 );
}
- start = UDFFindFile( dvd, filename, &len );
+ start = UDFFindFile( ctx, filename, &len );
if( start != 0 && len != 0 ) {
/* Perform CSS key cracking for this title. */
fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
@@ -203,7 +204,7 @@ static int initAllCSSKeys( dvd_reader_t *dvd )
gettimeofday( &t_s, NULL );
sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 1 );
- start = UDFFindFile( dvd, filename, &len );
+ start = UDFFindFile( ctx, filename, &len );
if( start == 0 || len == 0 ) break;
/* Perform CSS key cracking for this title. */
@@ -231,12 +232,12 @@ static int initAllCSSKeys( dvd_reader_t *dvd )
/**
* Open a DVD image or block device file or use stream_cb functions.
*/
-static dvd_reader_t *DVDOpenImageFile( const char *location,
+static dvd_reader_device_t *DVDOpenImageFile( const char *location,
void *stream,
dvd_reader_stream_cb *stream_cb,
int have_css )
{
- dvd_reader_t *dvd;
+ dvd_reader_device_t *dvd;
dvd_input_t dev;
dev = dvdinput_open( location, stream, stream_cb );
@@ -245,7 +246,7 @@ static dvd_reader_t *DVDOpenImageFile( const char *location,
return NULL;
}
- dvd = calloc( 1, sizeof( dvd_reader_t ) );
+ dvd = calloc( 1, sizeof( dvd_reader_device_t ) );
if( !dvd ) {
dvdinput_close(dev);
return NULL;
@@ -266,11 +267,11 @@ static dvd_reader_t *DVDOpenImageFile( const char *location,
return dvd;
}
-static dvd_reader_t *DVDOpenPath( const char *path_root )
+static dvd_reader_device_t *DVDOpenPath( const char *path_root )
{
- dvd_reader_t *dvd;
+ dvd_reader_device_t *dvd;
- dvd = calloc( 1, sizeof( dvd_reader_t ) );
+ dvd = calloc( 1, sizeof( dvd_reader_device_t ) );
if( !dvd ) return NULL;
dvd->path_root = strdup( path_root );
if(!dvd->path_root) {
@@ -342,9 +343,11 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
{
struct stat fileinfo;
int ret, have_css, retval, cdir = -1;
- dvd_reader_t *ret_val = NULL;
char *dev_name = NULL;
char *path = NULL, *new_path = NULL, *path_copy = NULL;
+ dvd_reader_t *ctx = calloc(1, sizeof(*ctx));
+ if(!ctx)
+ return NULL;
#if defined(_WIN32) || defined(__OS2__)
int len;
@@ -354,7 +357,13 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
if( stream != NULL && stream_cb != NULL )
{
have_css = dvdinput_setup();
- return DVDOpenImageFile( NULL, stream, stream_cb, have_css );
+ ctx->rd = DVDOpenImageFile( NULL, stream, stream_cb, have_css );
+ if(!ctx->rd)
+ {
+ free(ctx);
+ return NULL;
+ }
+ return ctx;
}
if( ppath == NULL )
@@ -384,9 +393,14 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
/* maybe "host:port" url? try opening it with acCeSS library */
if( strchr(path,':') ) {
- ret_val = DVDOpenImageFile( path, NULL, NULL, have_css );
+ ctx->rd = DVDOpenImageFile( path, NULL, NULL, have_css );
free(path);
- return ret_val;
+ if(!ctx->rd)
+ {
+ free(ctx);
+ return NULL;
+ }
+ return ctx;
}
/* If we can't stat the file, give up */
@@ -403,7 +417,6 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
/**
* Block devices and regular files are assumed to be DVD-Video images.
*/
- dvd_reader_t *dvd = NULL;
#if defined(__sun)
dev_name = sun_block2char( path );
#elif defined(SYS_BSD)
@@ -413,12 +426,16 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
#endif
if(!dev_name)
goto DVDOpen_error;
- dvd = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
+ ctx->rd = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
free( dev_name );
free(path);
- return dvd;
+ if(!ctx->rd)
+ {
+ free(ctx);
+ return NULL;
+ }
+ return ctx;
} else if( S_ISDIR( fileinfo.st_mode ) ) {
- dvd_reader_t *auth_drive = 0;
#if defined(SYS_BSD)
struct fstab* fe;
#elif defined(__sun) || defined(__linux__)
@@ -505,7 +522,7 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
" mounted on %s for CSS authentication\n",
dev_name,
s[i].f_mntonname);
- auth_drive = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
+ ctx->rd = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
break;
}
}
@@ -518,7 +535,7 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
" mounted on %s for CSS authentication\n",
dev_name,
fe->fs_file );
- auth_drive = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
+ ctx->rd = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
}
#elif defined(__sun)
mntfile = fopen( MNTTAB, "r" );
@@ -534,7 +551,7 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
" mounted on %s for CSS authentication\n",
dev_name,
mp.mnt_mountp );
- auth_drive = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
+ ctx->rd = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
break;
}
}
@@ -558,7 +575,7 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
" mounted on %s for CSS authentication\n",
me->mnt_fsname,
me->mnt_dir );
- auth_drive = DVDOpenImageFile( me->mnt_fsname, NULL, NULL, have_css );
+ ctx->rd = DVDOpenImageFile( me->mnt_fsname, NULL, NULL, have_css );
dev_name = strdup(me->mnt_fsname);
break;
}
@@ -572,18 +589,18 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
( !path[2] ||
((path[2] == '\\' || path[2] == '/') && !path[3])))
#endif
- auth_drive = DVDOpenImageFile( path, NULL, NULL, have_css );
+ ctx->rd = DVDOpenImageFile( path, NULL, NULL, have_css );
#endif
#if !defined(_WIN32) && !defined(__OS2__)
if( !dev_name ) {
fprintf( stderr, "libdvdread: Couldn't find device name.\n" );
- } else if( !auth_drive ) {
+ } else if( !ctx->rd ) {
fprintf( stderr, "libdvdread: Device %s inaccessible, "
"CSS authentication not available.\n", dev_name );
}
#else
- if( !auth_drive ) {
+ if( !ctx->rd ) {
fprintf( stderr, "libdvdread: Device %s inaccessible, "
"CSS authentication not available.\n", path );
}
@@ -597,16 +614,22 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
/**
* If we've opened a drive, just use that.
*/
- if( auth_drive ) {
- free(path);
- return auth_drive;
+ if(ctx->rd)
+ {
+ free(path);
+ return ctx;
}
/**
* Otherwise, we now try to open the directory tree instead.
*/
- ret_val = DVDOpenPath( path );
- free( path );
- return ret_val;
+ ctx->rd = DVDOpenPath( path );
+ free( path );
+ if(!ctx->rd)
+ {
+ free(ctx);
+ return NULL;
+ }
+ return ctx;
}
DVDOpen_error:
@@ -634,9 +657,10 @@ dvd_reader_t *DVDOpenStream( void *stream,
void DVDClose( dvd_reader_t *dvd )
{
if( dvd ) {
- if( dvd->dev ) dvdinput_close( dvd->dev );
- if( dvd->path_root ) free( dvd->path_root );
- if( dvd->udfcache ) FreeUDFCache( dvd->udfcache );
+ if( dvd->rd->dev ) dvdinput_close( dvd->rd->dev );
+ if( dvd->rd->path_root ) free( dvd->rd->path_root );
+ if( dvd->rd->udfcache ) FreeUDFCache( dvd->rd->udfcache );
+ free( dvd->rd );
free( dvd );
}
}
@@ -644,13 +668,13 @@ void DVDClose( dvd_reader_t *dvd )
/**
* Open an unencrypted file on a DVD image file.
*/
-static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, const char *filename,
+static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *ctx, const char *filename,
int do_cache )
{
uint32_t start, len;
dvd_file_t *dvd_file;
- start = UDFFindFile( dvd, filename, &len );
+ start = UDFFindFile( ctx, filename, &len );
if( !start ) {
fprintf( stderr, "libdvdread:DVDOpenFileUDF:UDFFindFile %s failed\n", filename );
return NULL;
@@ -661,7 +685,7 @@ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, const char *filename,
fprintf( stderr, "libdvdread:DVDOpenFileUDF:malloc failed\n" );
return NULL;
}
- dvd_file->dvd = dvd;
+ dvd_file->ctx = ctx;
dvd_file->lb_start = start;
dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
@@ -674,7 +698,7 @@ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, const char *filename,
if( !dvd_file->cache )
return dvd_file;
- ret = InternalUDFReadBlocksRaw( dvd, dvd_file->lb_start,
+ ret = InternalUDFReadBlocksRaw( ctx, dvd_file->lb_start,
dvd_file->filesize, dvd_file->cache,
DVDINPUT_NOFLAGS );
if( ret != dvd_file->filesize ) {
@@ -725,16 +749,16 @@ static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename )
nodirfile = file;
}
- ret = findDirFile( dvd->path_root, nodirfile, filename );
+ ret = findDirFile( dvd->rd->path_root, nodirfile, filename );
if( ret < 0 ) {
char video_path[ PATH_MAX + 1 ];
/* Try also with adding the path, just in case. */
- sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root );
+ sprintf( video_path, "%s/VIDEO_TS/", dvd->rd->path_root );
ret = findDirFile( video_path, nodirfile, filename );
if( ret < 0 ) {
/* Try with the path, but in lower case. */
- sprintf( video_path, "%s/video_ts/", dvd->path_root );
+ sprintf( video_path, "%s/video_ts/", dvd->rd->path_root );
ret = findDirFile( video_path, nodirfile, filename );
if( ret < 0 ) {
return 0;
@@ -748,7 +772,7 @@ static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename )
/**
* Open an unencrypted file from a DVD directory tree.
*/
-static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, const char *filename )
+static dvd_file_t *DVDOpenFilePath( dvd_reader_t *ctx, const char *filename )
{
char full_path[ PATH_MAX + 1 ];
dvd_file_t *dvd_file;
@@ -756,7 +780,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, const char *filename )
dvd_input_t dev;
/* Get the full path of the file. */
- if( !findDVDFile( dvd, filename, full_path ) ) {
+ if( !findDVDFile( ctx, filename, full_path ) ) {
fprintf( stderr, "libdvdread:DVDOpenFilePath:findDVDFile %s failed\n", filename );
return NULL;
}
@@ -773,7 +797,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, const char *filename )
dvdinput_close(dev);
return NULL;
}
- dvd_file->dvd = dvd;
+ dvd_file->ctx = ctx;
if( stat( full_path, &fileinfo ) < 0 ) {
fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
@@ -788,7 +812,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, const char *filename )
return dvd_file;
}
-static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu )
+static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *ctx, int title, int menu )
{
char filename[ MAX_UDF_FILE_NAME_LEN ];
uint32_t start, len;
@@ -799,12 +823,12 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu )
} else {
sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
}
- start = UDFFindFile( dvd, filename, &len );
+ start = UDFFindFile( ctx, filename, &len );
if( start == 0 ) return NULL;
dvd_file = calloc( 1, sizeof( dvd_file_t ) );
if( !dvd_file ) return NULL;
- dvd_file->dvd = dvd;
+ dvd_file->ctx = ctx;
/*Hack*/ dvd_file->css_title = title << 1 | menu;
dvd_file->lb_start = start;
dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
@@ -815,14 +839,14 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu )
for( cur = 2; cur < 10; cur++ ) {
sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
- if( !UDFFindFile( dvd, filename, &len ) ) break;
+ if( !UDFFindFile( ctx, filename, &len ) ) break;
dvd_file->filesize += len / DVD_VIDEO_LB_LEN;
}
}
- if( dvd->css_state == 1 /* Need key init */ ) {
- initAllCSSKeys( dvd );
- dvd->css_state = 2;
+ if( ctx->rd->css_state == 1 /* Need key init */ ) {
+ initAllCSSKeys( ctx );
+ ctx->rd->css_state = 2;
}
/*
if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) {
@@ -834,7 +858,7 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu )
return dvd_file;
}
-static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
+static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *ctx, int title, int menu )
{
char filename[ MAX_UDF_FILE_NAME_LEN ];
char full_path[ PATH_MAX + 1 ];
@@ -843,7 +867,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
dvd_file = calloc( 1, sizeof( dvd_file_t ) );
if( !dvd_file ) return NULL;
- dvd_file->dvd = dvd;
+ dvd_file->ctx = ctx;
/*Hack*/ dvd_file->css_title = title << 1 | menu;
if( menu ) {
@@ -854,7 +878,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
} else {
sprintf( filename, "VTS_%02i_0.VOB", title );
}
- if( !findDVDFile( dvd, filename, full_path ) ) {
+ if( !findDVDFile( ctx, filename, full_path ) ) {
free( dvd_file );
return NULL;
}
@@ -882,7 +906,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
for( i = 0; i < TITLES_MAX; ++i ) {
sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 );
- if( !findDVDFile( dvd, filename, full_path ) ) {
+ if( !findDVDFile( ctx, filename, full_path ) ) {
break;
}
@@ -905,9 +929,10 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
return dvd_file;
}
-dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
+dvd_file_t *DVDOpenFile( dvd_reader_t *ctx, int titlenum,
dvd_read_domain_t domain )
{
+ dvd_reader_device_t *dvd = ctx->rd;
char filename[ MAX_UDF_FILE_NAME_LEN ];
int do_cache = 0;
@@ -934,17 +959,17 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
break;
case DVD_READ_MENU_VOBS:
if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 1 );
+ return DVDOpenVOBUDF( ctx, titlenum, 1 );
} else {
- return DVDOpenVOBPath( dvd, titlenum, 1 );
+ return DVDOpenVOBPath( ctx, titlenum, 1 );
}
break;
case DVD_READ_TITLE_VOBS:
if( titlenum == 0 ) return NULL;
if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 0 );
+ return DVDOpenVOBUDF( ctx, titlenum, 0 );
} else {
- return DVDOpenVOBPath( dvd, titlenum, 0 );
+ return DVDOpenVOBPath( ctx, titlenum, 0 );
}
break;
default:
@@ -953,16 +978,17 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
}
if( dvd->isImageFile ) {
- return DVDOpenFileUDF( dvd, filename, do_cache );
+ return DVDOpenFileUDF( ctx, filename, do_cache );
} else {
- return DVDOpenFilePath( dvd, filename );
+ return DVDOpenFilePath( ctx, filename );
}
}
void DVDCloseFile( dvd_file_t *dvd_file )
{
- if( dvd_file && dvd_file->dvd ) {
- if( !dvd_file->dvd->isImageFile ) {
+ dvd_reader_device_t *dvd = dvd_file->ctx->rd;
+ if( dvd_file && dvd ) {
+ if( !dvd->isImageFile ) {
int i;
for( i = 0; i < TITLES_MAX; ++i ) {
@@ -1078,9 +1104,10 @@ static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title,
}
-int DVDFileStat( dvd_reader_t *dvd, int titlenum,
+int DVDFileStat( dvd_reader_t *reader, int titlenum,
dvd_read_domain_t domain, dvd_stat_t *statbuf )
{
+ dvd_reader_device_t *dvd = reader->rd;
char filename[ MAX_UDF_FILE_NAME_LEN ];
struct stat fileinfo;
uint32_t size;
@@ -1108,9 +1135,9 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
break;
case DVD_READ_MENU_VOBS:
if( dvd->isImageFile )
- return DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf );
+ return DVDFileStatVOBUDF( reader, titlenum, 1, statbuf );
else
- return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf );
+ return DVDFileStatVOBPath( reader, titlenum, 1, statbuf );
break;
case DVD_READ_TITLE_VOBS:
@@ -1118,9 +1145,9 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
return -1;
if( dvd->isImageFile )
- return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf );
+ return DVDFileStatVOBUDF( reader, titlenum, 0, statbuf );
else
- return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf );
+ return DVDFileStatVOBPath( reader, titlenum, 0, statbuf );
break;
default:
@@ -1130,7 +1157,7 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
}
if( dvd->isImageFile ) {
- if( UDFFindFile( dvd, filename, &size ) ) {
+ if( UDFFindFile( reader, filename, &size ) ) {
statbuf->size = size;
statbuf->nr_parts = 1;
statbuf->parts_size[ 0 ] = size;
@@ -1139,7 +1166,7 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
} else {
char full_path[ PATH_MAX + 1 ];
- if( findDVDFile( dvd, filename, full_path ) ) {
+ if( findDVDFile( reader, filename, full_path ) ) {
if( stat( full_path, &fileinfo ) < 0 )
fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
else {
@@ -1154,24 +1181,24 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
}
/* Internal, but used from dvd_udf.c */
-int InternalUDFReadBlocksRaw( const dvd_reader_t *device, uint32_t lb_number,
+int InternalUDFReadBlocksRaw( const dvd_reader_t *ctx, uint32_t lb_number,
size_t block_count, unsigned char *data,
int encrypted )
{
int ret;
- if( !device->dev ) {
+ if( !ctx->rd->dev ) {
fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
return -1;
}
- ret = dvdinput_seek( device->dev, (int) lb_number );
+ ret = dvdinput_seek( ctx->rd->dev, (int) lb_number );
if( ret != (int) lb_number ) {
fprintf( stderr, "libdvdread: Can't seek to block %u\n", lb_number );
return ret;
}
- ret = dvdinput_read( device->dev, (char *) data,
+ ret = dvdinput_read( ctx->rd->dev, (char *) data,
(int) block_count, encrypted );
return ret;
}
@@ -1202,7 +1229,7 @@ static int DVDReadBlocksUDF( const dvd_file_t *dvd_file, uint32_t offset,
return block_count;
} else {
/* use dvdinput access */
- return InternalUDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset,
+ return InternalUDFReadBlocksRaw( dvd_file->ctx, dvd_file->lb_start + offset,
block_count, data, encrypted );
}
}
@@ -1285,6 +1312,8 @@ static int DVDReadBlocksPath( const dvd_file_t *dvd_file, unsigned int offset,
ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
size_t block_count, unsigned char *data )
{
+ dvd_reader_t *ctx = dvd_file->ctx;
+ dvd_reader_device_t *dvd = ctx->rd;
int ret;
/* Check arguments. */
@@ -1292,10 +1321,10 @@ ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
return -1;
/* Hack, and it will still fail for multiple opens in a threaded app ! */
- if( dvd_file->dvd->css_title != dvd_file->css_title ) {
- dvd_file->dvd->css_title = dvd_file->css_title;
- if( dvd_file->dvd->isImageFile ) {
- dvdinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start );
+ if( dvd->css_title != dvd_file->css_title ) {
+ dvd->css_title = dvd_file->css_title;
+ if( dvd->isImageFile ) {
+ dvdinput_title( dvd->dev, (int)dvd_file->lb_start );
}
/* Here each vobu has it's own dvdcss handle, so no need to update
else {
@@ -1303,7 +1332,7 @@ ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
}*/
}
- if( dvd_file->dvd->isImageFile ) {
+ if( dvd->isImageFile ) {
ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset,
block_count, data, DVDINPUT_READ_DECRYPT );
} else {
@@ -1329,11 +1358,13 @@ int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset )
int DVDFileSeekForce(dvd_file_t *dvd_file, int offset, int force_size)
{
+ dvd_reader_t *ctx = dvd_file->ctx;
+ dvd_reader_device_t *dvd = ctx->rd;
/* Check arguments. */
if( dvd_file == NULL || offset <= 0 )
return -1;
- if( dvd_file->dvd->isImageFile ) {
+ if( dvd->isImageFile ) {
if( force_size < 0 )
force_size = (offset - 1) / DVD_VIDEO_LB_LEN + 1;
if( dvd_file->filesize < force_size ) {
@@ -1353,6 +1384,8 @@ int DVDFileSeekForce(dvd_file_t *dvd_file, int offset, int force_size)
ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
{
+ dvd_reader_t *ctx = dvd_file->ctx;
+ dvd_reader_device_t *dvd = ctx->rd;
unsigned char *secbuf_base, *secbuf;
unsigned int numsec, seek_sector, seek_byte;
int ret;
@@ -1375,7 +1408,7 @@ ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
}
secbuf = (unsigned char *)(((uintptr_t)secbuf_base & ~((uintptr_t)2047)) + 2048);
- if( dvd_file->dvd->isImageFile ) {
+ if( dvd->isImageFile ) {
ret = DVDReadBlocksUDF( dvd_file, (uint32_t) seek_sector,
(size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
} else {
@@ -1473,10 +1506,11 @@ int DVDDiscID( dvd_reader_t *dvd, unsigned char *discid )
}
-int DVDISOVolumeInfo( dvd_reader_t *dvd,
+int DVDISOVolumeInfo( dvd_reader_t *ctx,
char *volid, unsigned int volid_size,
unsigned char *volsetid, unsigned int volsetid_size )
{
+ dvd_reader_device_t *dvd = ctx->rd;
unsigned char *buffer, *buffer_base;
int ret;
@@ -1499,7 +1533,7 @@ int DVDISOVolumeInfo( dvd_reader_t *dvd,
buffer = (unsigned char *)(((uintptr_t)buffer_base & ~((uintptr_t)2047)) + 2048);
- ret = InternalUDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );
+ ret = InternalUDFReadBlocksRaw( ctx, 16, 1, buffer, 0 );
if( ret != 1 ) {
fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
"read ISO9660 Primary Volume Descriptor!\n" );
@@ -1534,28 +1568,28 @@ int DVDISOVolumeInfo( dvd_reader_t *dvd,
}
-int DVDUDFVolumeInfo( dvd_reader_t *dvd,
+int DVDUDFVolumeInfo( dvd_reader_t *ctx,
char *volid, unsigned int volid_size,
unsigned char *volsetid, unsigned int volsetid_size )
{
int ret;
/* Check arguments. */
- if( dvd == NULL )
+ if( ctx == NULL || ctx->rd == NULL )
return -1;
- if( dvd->dev == NULL ) {
+ if( ctx->rd->dev == NULL ) {
/* No block access, so no UDF VolumeSet Identifier */
return -1;
}
if( (volid != NULL) && (volid_size > 0) ) {
- ret = UDFGetVolumeIdentifier(dvd, volid, volid_size);
+ ret = UDFGetVolumeIdentifier(ctx, volid, volid_size);
if(!ret) {
return -1;
}
}
if( (volsetid != NULL) && (volsetid_size > 0) ) {
- ret = UDFGetVolumeSetIdentifier(dvd, volsetid, volsetid_size);
+ ret = UDFGetVolumeSetIdentifier(ctx, volsetid, volsetid_size);
if(!ret) {
return -1;
}
=====================================
src/dvd_udf.c
=====================================
@@ -44,7 +44,7 @@
#include "dvdread/dvd_udf.h"
/* It's required to either fail or deliver all the blocks asked for. */
-static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
+static int DVDReadLBUDF( dvd_reader_t *ctx, uint32_t lb_number,
size_t block_count, unsigned char *data,
int encrypted )
{
@@ -53,7 +53,7 @@ static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
while(count > 0) {
int ret;
- ret = InternalUDFReadBlocksRaw(device, lb_number, count, data + DVD_VIDEO_LB_LEN * (block_count - count), encrypted);
+ ret = InternalUDFReadBlocksRaw(ctx, lb_number, count, data + DVD_VIDEO_LB_LEN * (block_count - count), encrypted);
if(ret <= 0) {
/* One of the reads failed or nothing more to read, too bad.
@@ -156,16 +156,16 @@ void FreeUDFCache(void *cache)
}
-static int GetUDFCache(dvd_reader_t *device, UDFCacheType type,
+static int GetUDFCache(dvd_reader_t *ctx, UDFCacheType type,
uint32_t nr, void *data)
{
int n;
struct udf_cache *c;
- if(DVDUDFCacheLevel(device, -1) <= 0)
+ if(DVDUDFCacheLevel(ctx, -1) <= 0)
return 0;
- c = (struct udf_cache *)GetUDFCacheHandle(device);
+ c = (struct udf_cache *)GetUDFCacheHandle(ctx);
if(c == NULL)
return 0;
@@ -218,24 +218,24 @@ static int GetUDFCache(dvd_reader_t *device, UDFCacheType type,
return 0;
}
-static int SetUDFCache(dvd_reader_t *device, UDFCacheType type,
+static int SetUDFCache(dvd_reader_t *ctx, UDFCacheType type,
uint32_t nr, void *data)
{
int n;
struct udf_cache *c;
void *tmp;
- if(DVDUDFCacheLevel(device, -1) <= 0)
+ if(DVDUDFCacheLevel(ctx, -1) <= 0)
return 0;
- c = (struct udf_cache *)GetUDFCacheHandle(device);
+ c = (struct udf_cache *)GetUDFCacheHandle(ctx);
if(c == NULL) {
c = calloc(1, sizeof(struct udf_cache));
/* fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache)); */
if(c == NULL)
return 0;
- SetUDFCacheHandle(device, c);
+ SetUDFCacheHandle(ctx, c);
}
@@ -511,7 +511,7 @@ static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics,
* File: Location of file the ICB is pointing to
* return 1 on success, 0 on error;
*/
-static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType,
+static int UDFMapICB( dvd_reader_t *ctx, struct AD ICB, uint8_t *FileType,
struct Partition *partition, struct AD *File )
{
uint8_t LogBlock_base[DVD_VIDEO_LB_LEN + 2048];
@@ -523,14 +523,14 @@ static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType,
lbnum = partition->Start + ICB.Location;
tmpmap.lbn = lbnum;
- if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) {
+ if(GetUDFCache(ctx, MapCache, lbnum, &tmpmap)) {
*FileType = tmpmap.filetype;
memcpy(File, &tmpmap.file, sizeof(tmpmap.file));
return 1;
}
do {
- ret = DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 );
+ ret = DVDReadLBUDF( ctx, lbnum++, 1, LogBlock, 0 );
if( ret < 0 ) {
return ret;
}
@@ -545,7 +545,7 @@ static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType,
UDFFileEntry( LogBlock, FileType, partition, File );
memcpy(&tmpmap.file, File, sizeof(tmpmap.file));
tmpmap.filetype = *FileType;
- SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap);
+ SetUDFCache(ctx, MapCache, tmpmap.lbn, &tmpmap);
return 1;
};
} while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 )
@@ -560,7 +560,7 @@ static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType,
* FileICB: Location of ICB of the found file
* return 1 on success, 0 on error;
*/
-static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
+static int UDFScanDir( dvd_reader_t *ctx, struct AD Dir, char *FileName,
struct Partition *partition, struct AD *FileICB,
int cache_file_info)
{
@@ -579,18 +579,18 @@ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
/* Scan dir for ICB of file */
lbnum = partition->Start + Dir.Location;
- if(DVDUDFCacheLevel(device, -1) > 0) {
+ if(DVDUDFCacheLevel(ctx, -1) > 0) {
int found = 0;
int in_cache = 0;
/* caching */
- if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) {
+ if(!GetUDFCache(ctx, LBUDFCache, lbnum, &cached_dir)) {
dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN;
if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL)
return 0;
cached_dir = (uint8_t *)(((uintptr_t)cached_dir_base & ~((uintptr_t)2047)) + 2048);
- ret = DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0);
+ ret = DVDReadLBUDF( ctx, lbnum, dir_lba, cached_dir, 0);
if( ret <= 0 ) {
free(cached_dir_base);
cached_dir_base = NULL;
@@ -607,7 +607,7 @@ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
uint8_t *data[2];
data[0] = cached_dir_base;
data[1] = cached_dir;
- SetUDFCache(device, LBUDFCache, lbnum, data);
+ SetUDFCache(ctx, LBUDFCache, lbnum, data);
}
} else
in_cache = 1;
@@ -633,7 +633,7 @@ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
memcpy(FileICB, &tmpICB, sizeof(tmpICB));
found = 1;
}
- if(!UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile))
+ if(!UDFMapICB(ctx, tmpICB, &tmpFiletype, partition, &tmpFile))
return 0;
} else {
@@ -653,7 +653,7 @@ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
return 0;
}
- if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 )
+ if( DVDReadLBUDF( ctx, lbnum, 2, directory, 0 ) <= 0 )
return 0;
p = 0;
@@ -662,7 +662,7 @@ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
++lbnum;
p -= DVD_VIDEO_LB_LEN;
Dir.Length -= DVD_VIDEO_LB_LEN;
- if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {
+ if( DVDReadLBUDF( ctx, lbnum, 2, directory, 0 ) <= 0 ) {
return 0;
}
}
@@ -681,7 +681,7 @@ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
}
-static int UDFGetAVDP( dvd_reader_t *device,
+static int UDFGetAVDP( dvd_reader_t *ctx,
struct avdp_t *avdp)
{
uint8_t Anchor_base[ DVD_VIDEO_LB_LEN + 2048 ];
@@ -693,7 +693,7 @@ static int UDFGetAVDP( dvd_reader_t *device,
struct avdp_t;
int ret;
- if(GetUDFCache(device, AVDPCache, 0, avdp))
+ if(GetUDFCache(ctx, AVDPCache, 0, avdp))
return 1;
/* Find Anchor */
@@ -702,7 +702,7 @@ static int UDFGetAVDP( dvd_reader_t *device,
terminate = 0;
for(;;) {
- ret = DVDReadLBUDF( device, lbnum, 1, Anchor, 0 );
+ ret = DVDReadLBUDF( ctx, lbnum, 1, Anchor, 0 );
if( ret < 0 ) {
return ret;
}
@@ -745,7 +745,7 @@ static int UDFGetAVDP( dvd_reader_t *device,
avdp->rvds.location = MVDS_location;
avdp->rvds.length = MVDS_length;
- SetUDFCache(device, AVDPCache, 0, avdp);
+ SetUDFCache(ctx, AVDPCache, 0, avdp);
return 1;
}
@@ -755,7 +755,7 @@ static int UDFGetAVDP( dvd_reader_t *device,
* partnum: Number of the partition, starting at 0.
* part: structure to fill with the partition information
*/
-static int UDFFindPartition( dvd_reader_t *device, int partnum,
+static int UDFFindPartition( dvd_reader_t *ctx, int partnum,
struct Partition *part )
{
uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ];
@@ -765,7 +765,7 @@ static int UDFFindPartition( dvd_reader_t *device, int partnum,
int i, volvalid, ret;
struct avdp_t avdp;
- if(!UDFGetAVDP(device, &avdp))
+ if(!UDFGetAVDP(ctx, &avdp))
return 0;
/* Main volume descriptor */
@@ -781,7 +781,7 @@ static int UDFFindPartition( dvd_reader_t *device, int partnum,
lbnum = MVDS_location;
do {
- ret = DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 );
+ ret = DVDReadLBUDF( ctx, lbnum++, 1, LogBlock, 0 );
if( ret < 0 ) {
return ret;
}
@@ -820,7 +820,7 @@ static int UDFFindPartition( dvd_reader_t *device, int partnum,
return part->valid;
}
-uint32_t UDFFindFile( dvd_reader_t *device, const char *filename,
+uint32_t UDFFindFile( dvd_reader_t *ctx, const char *filename,
uint32_t *filesize )
{
uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ];
@@ -838,16 +838,16 @@ uint32_t UDFFindFile( dvd_reader_t *device, const char *filename,
strncat(tokenline, filename, MAX_UDF_FILE_NAME_LEN - 1);
memset(&ICB, 0, sizeof(ICB));
- if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&
- GetUDFCache(device, RootICBCache, 0, &RootICB))) {
+ if(!(GetUDFCache(ctx, PartitionCache, 0, &partition) &&
+ GetUDFCache(ctx, RootICBCache, 0, &RootICB))) {
/* Find partition, 0 is the standard location for DVD Video.*/
- if( !UDFFindPartition( device, 0, &partition ) ) return 0;
- SetUDFCache(device, PartitionCache, 0, &partition);
+ if( !UDFFindPartition( ctx, 0, &partition ) ) return 0;
+ SetUDFCache(ctx, PartitionCache, 0, &partition);
/* Find root dir ICB */
lbnum = partition.Start;
do {
- ret = DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 );
+ ret = DVDReadLBUDF( ctx, lbnum++, 1, LogBlock, 0 );
if( ret < 0 ) {
return ret;
}
@@ -869,11 +869,11 @@ uint32_t UDFFindFile( dvd_reader_t *device, const char *filename,
return 0;
if( RootICB.Partition != 0 )
return 0;
- SetUDFCache(device, RootICBCache, 0, &RootICB);
+ SetUDFCache(ctx, RootICBCache, 0, &RootICB);
}
/* Find root dir */
- if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) )
+ if( !UDFMapICB( ctx, RootICB, &filetype, &partition, &File ) )
return 0;
if( filetype != 4 )
return 0; /* Root dir should be dir */
@@ -883,10 +883,10 @@ uint32_t UDFFindFile( dvd_reader_t *device, const char *filename,
char *token = strtok(tokenline, "/");
while( token != NULL ) {
- if( !UDFScanDir( device, File, token, &partition, &ICB,
+ if( !UDFScanDir( ctx, File, token, &partition, &ICB,
cache_file_info))
return 0;
- if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) )
+ if( !UDFMapICB( ctx, ICB, &filetype, &partition, &File ) )
return 0;
if(!strcmp(token, "VIDEO_TS"))
cache_file_info = 1;
@@ -913,7 +913,7 @@ uint32_t UDFFindFile( dvd_reader_t *device, const char *filename,
* id, tagid of descriptor
* bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN).
*/
-static int UDFGetDescriptor( dvd_reader_t *device, int id,
+static int UDFGetDescriptor( dvd_reader_t *ctx, int id,
uint8_t *descriptor, int bufsize)
{
uint32_t lbnum, MVDS_location, MVDS_length;
@@ -925,7 +925,7 @@ static int UDFGetDescriptor( dvd_reader_t *device, int id,
if(bufsize < DVD_VIDEO_LB_LEN)
return 0;
- if(!UDFGetAVDP(device, &avdp))
+ if(!UDFGetAVDP(ctx, &avdp))
return 0;
/* Main volume descriptor */
@@ -937,7 +937,7 @@ static int UDFGetDescriptor( dvd_reader_t *device, int id,
/* Find Descriptor */
lbnum = MVDS_location;
do {
- ret = DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 );
+ ret = DVDReadLBUDF( ctx, lbnum++, 1, descriptor, 0 );
if( ret < 0 ) {
return ret;
}
@@ -965,19 +965,19 @@ static int UDFGetDescriptor( dvd_reader_t *device, int id,
}
-static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd)
+static int UDFGetPVD(dvd_reader_t *ctx, struct pvd_t *pvd)
{
uint8_t pvd_buf_base[DVD_VIDEO_LB_LEN + 2048];
uint8_t *pvd_buf = (uint8_t *)(((uintptr_t)pvd_buf_base & ~((uintptr_t)2047)) + 2048);
- if(GetUDFCache(device, PVDCache, 0, pvd))
+ if(GetUDFCache(ctx, PVDCache, 0, pvd))
return 1;
- if(!UDFGetDescriptor( device, 1, pvd_buf, DVD_VIDEO_LB_LEN))
+ if(!UDFGetDescriptor( ctx, 1, pvd_buf, DVD_VIDEO_LB_LEN))
return 0;
memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);
memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128);
- SetUDFCache(device, PVDCache, 0, pvd);
+ SetUDFCache(ctx, PVDCache, 0, pvd);
return 1;
}
@@ -987,14 +987,14 @@ static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd)
* volid_size, size of the buffer volid points to
* returns the size of buffer needed for all data
*/
-int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid,
+int UDFGetVolumeIdentifier(dvd_reader_t *ctx, char *volid,
unsigned int volid_size)
{
struct pvd_t pvd;
unsigned int volid_len;
/* get primary volume descriptor */
- if(!UDFGetPVD(device, &pvd))
+ if(!UDFGetPVD(ctx, &pvd))
return 0;
volid_len = pvd.VolumeIdentifier[31];
@@ -1017,13 +1017,13 @@ int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid,
* returns the size of the available volsetid information (128)
* or 0 on error
*/
-int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid,
+int UDFGetVolumeSetIdentifier(dvd_reader_t *ctx, uint8_t *volsetid,
unsigned int volsetid_size)
{
struct pvd_t pvd;
/* get primary volume descriptor */
- if(!UDFGetPVD(device, &pvd))
+ if(!UDFGetPVD(ctx, &pvd))
return 0;
=====================================
src/dvdread/dvd_reader.h
=====================================
@@ -63,6 +63,7 @@ extern "C" {
* Opaque type that is used as a handle for one instance of an opened DVD.
*/
typedef struct dvd_reader_s dvd_reader_t;
+typedef struct dvd_reader_device_s dvd_reader_device_t;
/**
* Opaque type for a file read handle, much like a normal fd or FILE *.
=====================================
src/dvdread/dvd_udf.h
=====================================
@@ -46,11 +46,11 @@ extern "C" {
* '/VIDEO_TS/VTS_01_1.IFO'. On success, filesize will be set to the size of
* the file in bytes.
*/
-uint32_t UDFFindFile( dvd_reader_t *device, const char *filename, uint32_t *size );
+uint32_t UDFFindFile( dvd_reader_t *, const char *filename, uint32_t *size );
-int UDFGetVolumeIdentifier(dvd_reader_t *device,
+int UDFGetVolumeIdentifier(dvd_reader_t *,
char *volid, unsigned int volid_size);
-int UDFGetVolumeSetIdentifier(dvd_reader_t *device,
+int UDFGetVolumeSetIdentifier(dvd_reader_t *,
uint8_t *volsetid, unsigned int volsetid_size);
#ifdef __cplusplus
=====================================
src/dvdread_internal.h
=====================================
@@ -35,6 +35,14 @@
__FILE__, __LINE__, # arg ); \
}
+struct dvd_reader_s
+{
+ dvd_reader_device_t *rd;
+ /* Set 100 flags for BUP fallback, most signifiant left
+ [0] for upper remaining VTS, [1] for the first Main + 63 VTS */
+ uint64_t ifoBUPflags[2];
+};
+
enum TagIdentifier {
/* ECMA 167 3/7.2.1 */
PrimaryVolumeDescriptor = 1,
@@ -60,11 +68,11 @@ enum TagIdentifier {
ExtendedFileEntry = 266,
};
-int InternalUDFReadBlocksRaw(const dvd_reader_t *device, uint32_t lb_number,
+int InternalUDFReadBlocksRaw(const dvd_reader_t *, uint32_t lb_number,
size_t block_count, unsigned char *data, int encrypted);
-void *GetUDFCacheHandle(dvd_reader_t *device);
-void SetUDFCacheHandle(dvd_reader_t *device, void *cache);
+void *GetUDFCacheHandle(dvd_reader_t *);
+void SetUDFCacheHandle(dvd_reader_t *, void *cache);
void FreeUDFCache(void *cache);
#endif /* LIBDVDREAD_DVDREAD_INTERNAL_H */
=====================================
src/ifo_read.c
=====================================
@@ -288,25 +288,28 @@ static void free_ptl_mait(ptl_mait_t* ptl_mait, int num_entries) {
free(ptl_mait);
}
-ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
+static ifo_handle_t *ifoOpenFileOrBackup(dvd_reader_t *ctx, int title,
+ int backup) {
ifo_handle_t *ifofile;
- int bup_file_opened = 0;
+ dvd_read_domain_t domain = backup ? DVD_READ_INFO_BACKUP_FILE
+ : DVD_READ_INFO_FILE;
char ifo_filename[13];
ifofile = calloc(1, sizeof(ifo_handle_t));
if(!ifofile)
return NULL;
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
- if(!ifofile->file) { /* Failed to open IFO, try to open BUP */
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
- bup_file_opened = 1;
+ ifofile->file = DVDOpenFile(ctx, title, domain);
+ if(!ifofile->file)
+ {
+ free(ifofile);
+ return NULL;
}
if (title)
- snprintf(ifo_filename, 13, "VTS_%02d_0.%s", title, bup_file_opened ? "BUP" : "IFO");
+ snprintf(ifo_filename, 13, "VTS_%02d_0.%s", title, backup ? "BUP" : "IFO");
else
- snprintf(ifo_filename, 13, "VIDEO_TS.%s", bup_file_opened ? "BUP" : "IFO");
+ snprintf(ifo_filename, 13, "VIDEO_TS.%s", backup ? "BUP" : "IFO");
if(!ifofile->file) {
fprintf(stderr, "libdvdread: Can't open file %s.\n", ifo_filename);
@@ -314,68 +317,6 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
return NULL;
}
- /* First check if this is a VMGI file. */
- if(ifoRead_VMG(ifofile)) {
-
- /* These are both mandatory. */
- if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile))
- goto ifoOpen_try_bup;
-
- ifoRead_PGCI_UT(ifofile);
- ifoRead_PTL_MAIT(ifofile);
-
- /* This is also mandatory. */
- if(!ifoRead_VTS_ATRT(ifofile))
- goto ifoOpen_try_bup;
-
- ifoRead_TXTDT_MGI(ifofile);
- ifoRead_C_ADT(ifofile);
- ifoRead_VOBU_ADMAP(ifofile);
-
- return ifofile;
- }
-
- if(ifoRead_VTS(ifofile)) {
-
- if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile))
- goto ifoOpen_try_bup;
-
- ifoRead_PGCI_UT(ifofile);
- ifoRead_VTS_TMAPT(ifofile);
- ifoRead_C_ADT(ifofile);
- ifoRead_VOBU_ADMAP(ifofile);
-
- if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile))
- goto ifoOpen_try_bup;
-
- return ifofile;
- }
-
-ifoOpen_try_bup:
- if (bup_file_opened)
- goto ifoOpen_fail;
-
- /* Try BUP instead */
- ifoClose(ifofile);
-
- ifofile = calloc(1, sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
-
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
-
- if (title)
- snprintf(ifo_filename, 13, "VTS_%02d_0.BUP", title);
- else
- strncpy(ifo_filename, "VIDEO_TS.BUP", 13);
-
- if (!ifofile->file) {
- fprintf(stderr, "libdvdread: Can't open file %s.\n", ifo_filename);
- free(ifofile);
- return NULL;
- }
- bup_file_opened = 1;
-
/* First check if this is a VMGI file. */
if(ifoRead_VMG(ifofile)) {
@@ -419,60 +360,101 @@ ifoOpen_fail:
return NULL;
}
+static void ifoSetBupFlag(dvd_reader_t *ctx, int title)
+{
+ if(title > 63)
+ ctx->ifoBUPflags[0] |= 1 << (title - 64);
+ else
+ ctx->ifoBUPflags[1] |= 1 << title;
+}
-ifo_handle_t *ifoOpenVMGI(dvd_reader_t *dvd) {
- ifo_handle_t *ifofile;
+static int ifoGetBupFlag(const dvd_reader_t *ctx, int title)
+{
+ int bupflag;
+ if(title > 63)
+ bupflag = !! (ctx->ifoBUPflags[0] & (1 << (title - 64)));
+ else
+ bupflag = !! (ctx->ifoBUPflags[1] & (1 << title));
+ return bupflag;
+}
- ifofile = calloc(1, sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
+ifo_handle_t *ifoOpen(dvd_reader_t *ctx, int title) {
+ ifo_handle_t *ifofile;
+ int bupflag = ifoGetBupFlag(ctx, title);
- ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_FILE);
- if(!ifofile->file) /* Should really catch any error and try to fallback */
- ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_BACKUP_FILE);
- if(!ifofile->file) {
- fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n");
- free(ifofile);
- return NULL;
+ ifofile = ifoOpenFileOrBackup(ctx, title, bupflag);
+ if(!ifofile) /* Try backup */
+ {
+ ifofile = ifoOpenFileOrBackup(ctx, title, 1);
+ if(ifofile && !bupflag)
+ ifoSetBupFlag(ctx, title);
}
+ return ifofile;
+}
- if(ifoRead_VMG(ifofile))
- return ifofile;
+ifo_handle_t *ifoOpenVMGI(dvd_reader_t *ctx) {
+ ifo_handle_t *ifofile;
- fprintf(stderr, "libdvdread,ifoOpenVMGI(): Invalid main menu IFO (VIDEO_TS.IFO).\n");
- ifoClose(ifofile);
+ for(int backup = ifoGetBupFlag(ctx, 0); backup <= 1; backup++)
+ {
+ ifofile = calloc(1, sizeof(ifo_handle_t));
+ if(!ifofile)
+ return NULL;
+
+ const dvd_read_domain_t domain = backup ? DVD_READ_INFO_BACKUP_FILE
+ : DVD_READ_INFO_FILE;
+ const char *ext = backup ? "BUP" : "IFO";
+
+ ifofile->file = DVDOpenFile(ctx, 0, domain);
+ if(!ifofile->file) { /* Should really catch any error */
+ fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.%s.\n", ext);
+ free(ifofile);
+ return NULL;
+ }
+
+ if(ifoRead_VMG(ifofile))
+ return ifofile;
+
+ fprintf(stderr, "libdvdread,ifoOpenVMGI(): Invalid main menu IFO (VIDEO_TS.%s).\n", ext);
+ ifoClose(ifofile);
+ }
return NULL;
}
-ifo_handle_t *ifoOpenVTSI(dvd_reader_t *dvd, int title) {
+ifo_handle_t *ifoOpenVTSI(dvd_reader_t *ctx, int title) {
ifo_handle_t *ifofile;
- ifofile = calloc(1, sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
-
if(title <= 0 || title > 99) {
fprintf(stderr, "libdvdread: ifoOpenVTSI invalid title (%d).\n", title);
- free(ifofile);
return NULL;
}
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
- if(!ifofile->file) /* Should really catch any error and try to fallback */
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
- if(!ifofile->file) {
- fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title);
- free(ifofile);
- return NULL;
- }
+ for(int backup = ifoGetBupFlag(ctx, title); backup <= 1; backup++)
+ {
+ ifofile = calloc(1, sizeof(ifo_handle_t));
+ if(!ifofile)
+ return NULL;
+
+ const dvd_read_domain_t domain = backup ? DVD_READ_INFO_BACKUP_FILE
+ : DVD_READ_INFO_FILE;
+ const char *ext = backup ? "BUP" : "IFO";
+ ifofile->file = DVDOpenFile(ctx, title, domain);
+ /* Should really catch any error */
+ if(!ifofile->file) {
+ fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n", title, ext);
+ free(ifofile);
+ continue;
+ }
- if(ifoRead_VTS(ifofile) && ifofile->vtsi_mat)
- return ifofile;
+ if(ifoRead_VTS(ifofile) && ifofile->vtsi_mat)
+ return ifofile;
+
+ fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.%s).\n",
+ title, title, ext);
+ ifoClose(ifofile);
+ }
- fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.IFO).\n",
- title, title);
- ifoClose(ifofile);
return NULL;
}
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/64e41a83448560374655eab9ab377dcce66e5a64...6c463b78201e2af6a5191c1d4c2272ef5711c45b
--
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/64e41a83448560374655eab9ab377dcce66e5a64...6c463b78201e2af6a5191c1d4c2272ef5711c45b
You're receiving this email because of your account on code.videolan.org.
More information about the libdvdnav-devel
mailing list