From c5531425eace87a11c4804daf27c988228223d41 Mon Sep 17 00:00:00 2001 From: diego Date: Thu, 16 Aug 2007 06:57:43 +0000 Subject: Sync libdvdread with version 0.9.6. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@24075 b3059339-0415-0410-9bf9-f77b7e298cf2 --- dvdread/dvd_reader.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++--- dvdread/dvd_reader.h | 48 ++++++++++-- dvdread/dvd_udf.h | 2 + dvdread/ifo_types.h | 2 +- 4 files changed, 253 insertions(+), 17 deletions(-) (limited to 'dvdread') diff --git a/dvdread/dvd_reader.c b/dvdread/dvd_reader.c index 4ba75e9a4e..a96a0903d8 100644 --- a/dvdread/dvd_reader.c +++ b/dvdread/dvd_reader.c @@ -413,17 +413,21 @@ static char *sun_block2char( const char *path ) #if defined(SYS_BSD) /* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recomended to _not_ use r + update: FreeBSD and DragonFly no longer uses the prefix so don't add it. + OpenBSD /dev/rcd0c, it needs to be the raw device NetBSD /dev/rcd0[d|c|..] d for x86, c (for non x86), perhaps others Darwin /dev/rdisk0, it needs to be the raw device - BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do) */ + BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do) + + returns a string allocated with strdup which should be free()'d when + no longer used. +*/ static char *bsd_block2char( const char *path ) -#if defined(__FreeBSD__) { - return (char *) strdup( path ); -} +#if defined(__FreeBSD__) || defined(__DragonFly__) + return (char *) strdup( path ); #else -{ char *new_path; /* If it doesn't start with "/dev/" or does start with "/dev/r" exit */ @@ -436,8 +440,8 @@ static char *bsd_block2char( const char *path ) strcat( new_path, path + strlen( "/dev/" ) ); return new_path; +#endif /* __FreeBSD__ || __DragonFly__ */ } -#endif /* __FreeBSD__ */ #endif @@ -486,18 +490,21 @@ dvd_reader_t *DVDOpen( const char *path ) if( S_ISBLK( fileinfo.st_mode ) || S_ISCHR( fileinfo.st_mode ) || S_ISREG( fileinfo.st_mode ) ) { - /** * Block devices and regular files are assumed to be DVD-Video images. */ + dvd_reader_t *dvd = NULL; #if defined(__sun) - return DVDOpenImageFile( sun_block2char( path ), have_css ); + dev_name = sun_block2char( path ); #elif defined(SYS_BSD) - return DVDOpenImageFile( bsd_block2char( path ), have_css ); + dev_name = bsd_block2char( path ); #else - return DVDOpenImageFile( path, have_css ); + dev_name = strdup( path ); #endif - + dvd = DVDOpenImageFile( dev_name, have_css ); + free( dev_name ); + + return dvd; } else if( S_ISDIR( fileinfo.st_mode ) ) { dvd_reader_t *auth_drive = 0; char *path_copy; @@ -1020,6 +1027,195 @@ void DVDCloseFile( dvd_file_t *dvd_file ) } } +static int DVDFileStatVOBUDF(dvd_reader_t *dvd, int title, + int menu, dvd_stat_t *statbuf) +{ + char filename[ MAX_UDF_FILE_NAME_LEN ]; + uint32_t size; + off_t tot_size; + off_t parts_size[9]; + int nr_parts = 0; + int n; + + if( title == 0 ) { + sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" ); + } else { + sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); + } + if(!UDFFindFile( dvd, filename, &size )) { + return -1; + } + tot_size = size; + nr_parts = 1; + parts_size[0] = size; + + if( !menu ) { + int cur; + + for( cur = 2; cur < 10; cur++ ) { + sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur ); + if( !UDFFindFile( dvd, filename, &size ) ) { + break; + } + parts_size[nr_parts] = size; + tot_size += size; + nr_parts++; + } + } + + statbuf->size = tot_size; + statbuf->nr_parts = nr_parts; + for(n = 0; n < nr_parts; n++) { + statbuf->parts_size[n] = parts_size[n]; + } + return 0; +} + + +static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title, + int menu, dvd_stat_t *statbuf ) +{ + char filename[ MAX_UDF_FILE_NAME_LEN ]; + char full_path[ PATH_MAX + 1 ]; + struct stat fileinfo; + off_t tot_size; + off_t parts_size[9]; + int nr_parts = 0; + int n; + + + + if( title == 0 ) { + sprintf( filename, "VIDEO_TS.VOB" ); + } else { + sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); + } + if( !findDVDFile( dvd, filename, full_path ) ) { + return -1; + } + + if( stat( full_path, &fileinfo ) < 0 ) { + if(dvd->verbose >= 1) { + fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); + } + return -1; + } + + + tot_size = fileinfo.st_size; + nr_parts = 1; + parts_size[0] = fileinfo.st_size; + + if( !menu ) { + int cur; + + for( cur = 2; cur < 10; cur++ ) { + + sprintf( filename, "VTS_%02d_%d.VOB", title, cur ); + if( !findDVDFile( dvd, filename, full_path ) ) { + break; + } + + if( stat( full_path, &fileinfo ) < 0 ) { + if(dvd->verbose >= 1) { + fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); + } + break; + } + + parts_size[nr_parts] = fileinfo.st_size; + tot_size += parts_size[nr_parts]; + nr_parts++; + } + } + + statbuf->size = tot_size; + statbuf->nr_parts = nr_parts; + for(n = 0; n < nr_parts; n++) { + statbuf->parts_size[n] = parts_size[n]; + } + return 0; +} + + +int DVDFileStat(dvd_reader_t *dvd, int titlenum, + dvd_read_domain_t domain, dvd_stat_t *statbuf) +{ + char filename[ MAX_UDF_FILE_NAME_LEN ]; + char full_path[ PATH_MAX + 1 ]; + struct stat fileinfo; + uint32_t size; + + /* Check arguments. */ + if( dvd == NULL || titlenum < 0 ) { + errno = EINVAL; + return -1; + } + + switch( domain ) { + case DVD_READ_INFO_FILE: + if( titlenum == 0 ) { + sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" ); + } else { + sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum ); + } + break; + case DVD_READ_INFO_BACKUP_FILE: + if( titlenum == 0 ) { + sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" ); + } else { + sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum ); + } + break; + case DVD_READ_MENU_VOBS: + if( dvd->isImageFile ) { + return DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf ); + } else { + return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf ); + } + break; + case DVD_READ_TITLE_VOBS: + if( titlenum == 0 ) { + return -1; + } + if( dvd->isImageFile ) { + return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf ); + } else { + return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf ); + } + break; + default: + if(dvd->verbose >= 1) { + fprintf( stderr, "libdvdread: Invalid domain for file stat.\n" ); + } + errno = EINVAL; + return -1; + } + + if( dvd->isImageFile ) { + if( UDFFindFile( dvd, filename, &size ) ) { + statbuf->size = size; + statbuf->nr_parts = 1; + statbuf->parts_size[0] = size; + return 0; + } + } else { + if( findDVDFile( dvd, filename, full_path ) ) { + if( stat( full_path, &fileinfo ) < 0 ) { + if(dvd->verbose >= 1) { + fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); + } + } else { + statbuf->size = fileinfo.st_size; + statbuf->nr_parts = 1; + statbuf->parts_size[0] = statbuf->size; + return 0; + } + } + } + return -1; +} + /** * Internal, but used from dvd_udf.c * diff --git a/dvdread/dvd_reader.h b/dvdread/dvd_reader.h index 84b8bb0aee..fbd3b3217b 100644 --- a/dvdread/dvd_reader.h +++ b/dvdread/dvd_reader.h @@ -34,12 +34,8 @@ /** * The current version. (0.9.4 => 904, 1.2.3 => 10203) */ -#define DVDREAD_VERSION 905 +#define DVDREAD_VERSION 906 -/** - * Returns the compiled version. (DVDREAD_VERSION as an int) - */ -int DVDVersion(void); /** * The length of one Logical Block of a DVD. @@ -65,6 +61,12 @@ typedef struct dvd_reader_s dvd_reader_t; */ typedef struct dvd_file_s dvd_file_t; +/** + * Returns the compiled version. (DVDREAD_VERSION as an int) + */ +int DVDVersion(void); + + /** * Opens a block device of a DVD-ROM file, or an image file, or a directory * name for a mounted DVD or HD copy of a DVD. @@ -145,6 +147,42 @@ typedef enum { single file. */ } dvd_read_domain_t; +/** + * + */ +typedef struct { + off_t size; /**< Total size of file in bytes */ + int nr_parts; /**< Number of file parts */ + off_t parts_size[9]; /**< Size of each part in bytes */ +} dvd_stat_t; + +/** + * Stats a file on the DVD given the title number and domain. + * The information about the file is stored in a dvd_stat_t + * which contains information about the size of the file and + * the number of parts in case of a multipart file and the respective + * sizes of the parts. + * A multipart file is for instance VTS_02_1.VOB, VTS_02_2.VOB, VTS_02_3.VOB + * The size of VTS_02_1.VOB will be stored in stat->parts_size[0], + * VTS_02_2.VOB in stat->parts_size[1], ... + * The total size (sum of all parts) is stored in stat->size and + * stat->nr_parts will hold the number of parts. + * Only DVD_READ_TITLE_VOBS (VTS_??_[1-9].VOB) can be multipart files. + * + * This function is only of use if you want to get the size of each file + * in the filesystem. These sizes are not needed to use any other + * functions in libdvdread. + * + * @param dvd A dvd read handle. + * @param titlenum Which Video Title Set should be used, VIDEO_TS is 0. + * @param domain Which domain. + * @param stat Pointer to where the result is stored. + * @return If successful 0, otherwise -1. + * + * int DVDFileStat(dvd, titlenum, domain, stat); + */ +int DVDFileStat(dvd_reader_t *, int, dvd_read_domain_t, dvd_stat_t *); + /** * Opens a file on the DVD given the title number and domain. * diff --git a/dvdread/dvd_udf.h b/dvdread/dvd_udf.h index cbf4775070..5005ed6398 100644 --- a/dvdread/dvd_udf.h +++ b/dvdread/dvd_udf.h @@ -50,6 +50,8 @@ extern "C" { * absolute pathname on the UDF filesystem, starting with '/'. For example, * '/VIDEO_TS/VTS_01_1.IFO'. On success, filesize will be set to the size of * the file in bytes. + * This implementation relies on that the file size is less than 2^32 + * A DVD file can at most be 2^30 (-2048 ?). */ uint32_t UDFFindFile( dvd_reader_t *device, char *filename, uint32_t *size ); diff --git a/dvdread/ifo_types.h b/dvdread/ifo_types.h index d7c8c4bf4c..798cc04d6d 100644 --- a/dvdread/ifo_types.h +++ b/dvdread/ifo_types.h @@ -175,7 +175,7 @@ typedef struct { unsigned int unknown5 : 4; #endif } ATTRIBUTE_PACKED surround; - } app_info; + } ATTRIBUTE_PACKED app_info; } ATTRIBUTE_PACKED audio_attr_t; -- cgit v1.2.3