From: Bastian B. <wa...@de...> - 2008-03-17 16:18:52
|
# HG changeset patch # User Bastian Blank <wa...@de...> # Date 1204498119 0 # Node ID 2d3f6ef238f266ffa76407d73ee29c30475ad96d # Parent 9b12a67af944397cdc849e355c3d55959d2affc5 libdvdread - Uses UDF provided length as authoritative libdvdread uses the file length provided by the UDF fs of the title set IFO files authoritative. I got a DVD which have parts of this file mapped outside of the provided file size and according to my memory only the offsets in the files matters in the standard. This patch adjusts the internal knowledge of the filesize accordingly and at least allows mplayer to play the dvd. (Imported from Debian libdvdread 0.9.7-8) diff -r 2d3f6ef238f266ffa76407d73ee29c30475ad96d -r 9b12a67af944397cdc849e355c3d55959d2affc5 src/input/libdvdnav/dvd_reader.c --- a/src/input/libdvdnav/dvd_reader.c Sun Mar 02 22:48:39 2008 +0000 +++ b/src/input/libdvdnav/dvd_reader.c Mon Mar 17 16:01:40 2008 +0000 @@ -1037,6 +1037,28 @@ int32_t DVDFileSeek( dvd_file_t *dvd_fil return offset; } +int32_t DVDFileSeekForce( dvd_file_t *dvd_file, int offset, int force_size ) +{ + /* Check arguments. */ + if( dvd_file == NULL || offset < 0 ) + return -1; + + if( dvd_file->dvd->isImageFile ) { + if( force_size < 0 ) + force_size = (offset - 1) / DVD_VIDEO_LB_LEN + 1; + if( dvd_file->filesize < force_size) { + dvd_file->filesize = force_size; + fprintf(stderr, "libdvdread: Ignored UDF provided size of file.\n"); + } + } + + if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) { + return -1; + } + dvd_file->seek_pos = (uint32_t) offset; + return offset; +} + ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size ) { unsigned char *secbuf_base, *secbuf; @@ -1077,7 +1099,7 @@ ssize_t DVDReadBytes( dvd_file_t *dvd_fi memcpy( data, &(secbuf[ seek_byte ]), byte_size ); free( secbuf_base ); - dvd_file->seek_pos += byte_size; + DVDFileSeekForce(dvd_file, dvd_file->seek_pos + byte_size, -1); return byte_size; } diff -r 2d3f6ef238f266ffa76407d73ee29c30475ad96d -r 9b12a67af944397cdc849e355c3d55959d2affc5 src/input/libdvdnav/dvd_reader.h --- a/src/input/libdvdnav/dvd_reader.h Sun Mar 02 22:48:39 2008 +0000 +++ b/src/input/libdvdnav/dvd_reader.h Mon Mar 17 16:01:40 2008 +0000 @@ -170,6 +170,8 @@ ssize_t DVDReadBlocks( dvd_file_t *, int * offset_set = DVDFileSeek(dvd_file, seek_offset); */ int32_t DVDFileSeek( dvd_file_t *, int32_t ); + +int32_t DVDFileSeekForce( dvd_file_t *, int, int ); /** * Reads the given number of bytes from the file. This call can only be used diff -r 2d3f6ef238f266ffa76407d73ee29c30475ad96d -r 9b12a67af944397cdc849e355c3d55959d2affc5 src/input/libdvdnav/ifo_read.c --- a/src/input/libdvdnav/ifo_read.c Sun Mar 02 22:48:39 2008 +0000 +++ b/src/input/libdvdnav/ifo_read.c Mon Mar 17 16:01:40 2008 +0000 @@ -91,6 +91,10 @@ static void ifoFree_PGCIT_internal(pgcit static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) { return (DVDFileSeek(dvd_file, (int)offset) == (int)offset); +} + +static inline int32_t DVDFileSeekForce_( dvd_file_t *dvd_file, uint32_t offset, int force_size ) { + return (DVDFileSeekForce(dvd_file, (int)offset, force_size) == (int)offset); } @@ -1507,7 +1511,7 @@ static int ifoRead_VOBU_ADMAP_internal(i unsigned int i; int info_length; - if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN)) + if(!DVDFileSeekForce_(ifofile->file, sector * DVD_BLOCK_LEN, sector)) return 0; if(!(DVDReadBytes(ifofile->file, vobu_admap, VOBU_ADMAP_SIZE))) |