[libdvdnav-devel] [PATCH] [RFC] Use libudfread
Petri Hintukainen
phintuka at gmail.com
Wed May 20 13:15:08 CEST 2015
---
Note that this patch does not compile because of missing ifdefs in libudfread:
UDFREAD_NO_DEFAULT_INPUT
- disable file I/O in libudfread (not used with libdvdread)
-> removes dependency on POSIX pread()
UDFREAD_NO_REENTRANT
- disable thread safety in libudfread (libdvdread is not thread safe)
-> removes dependency on pthread / atomic operations
Alternative would be adding (pointless) configure checks for pread() and pthread.
Another change is in caching: libudfread always caches directory trees,
but it does not cache file entries. Caching could be made optional if
disabling caching is useful feature in libdvdread ?
.gitmodules | 3 ++
Makefile.am | 10 ++++-
src/dvd_reader.c | 130 +++++++++++++++++++++++++++++++++++--------------------
3 files changed, 94 insertions(+), 49 deletions(-)
create mode 100644 .gitmodules
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..e2722d7
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "contrib/libudfread"]
+ path = contrib/libudfread
+ url = git://git.videolan.org/libudfread.git
diff --git a/Makefile.am b/Makefile.am
index 57ca371..d99693e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS = -Im4
-AM_CPPFLAGS = -I$(top_srcdir)/src $(CSS_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/contrib/libudfread/src $(CSS_CFLAGS)
dist_doc_DATA = AUTHORS ChangeLog COPYING NEWS README TODO
@@ -31,6 +31,14 @@ libdvdread_la_SOURCES = \
src/nav_print.c \
src/nav_read.c
+AM_CPPFLAGS += -DUDFREAD_NO_DEFAULT_INPUT -DUDFREAD_NO_REENTRANT
+libdvdread_la_SOURCES += \
+ contrib/libudfread/src/blockinput.h \
+ contrib/libudfread/src/ecma167.h \
+ contrib/libudfread/src/ecma167.c \
+ contrib/libudfread/src/udfread.h \
+ contrib/libudfread/src/udfread.c
+
libdvdread_la_LIBADD = $(CSS_LIBS)
libdvdread_la_LDFLAGS = -version-info $(DVDREAD_LTVERSION) \
diff --git a/src/dvd_reader.c b/src/dvd_reader.c
index 54a33b2..c323600 100644
--- a/src/dvd_reader.c
+++ b/src/dvd_reader.c
@@ -25,6 +25,7 @@
#include <sys/stat.h> /* stat */
#include <sys/time.h> /* For the timing of dvdcss_title crack. */
#include <fcntl.h> /* open */
+#include <stddef.h> /* offsetof */
#include <stdlib.h> /* free */
#include <stdio.h> /* fprintf */
#include <errno.h> /* errno, EIN* */
@@ -70,6 +71,9 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz )
# include <paths.h>
#endif
+#include "udfread.h"
+#include "blockinput.h"
+
#include "dvdread/dvd_udf.h"
#include "dvdread/dvd_reader.h"
#include "dvd_input.h"
@@ -77,11 +81,7 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz )
#include "md5.h"
#include "dvdread/ifo_read.h"
-#define DEFAULT_UDF_CACHE_LEVEL 1
-
struct dvd_reader_s {
- /* Basic information. */
- int isImageFile;
/* Hack for keeping track of the css status.
* 0: no css, 1: perhaps (need init of keys), 2: have done init */
@@ -94,9 +94,9 @@ struct dvd_reader_s {
/* Information required for a directory path drive. */
char *path_root;
- /* Filesystem cache */
- int udfcache_level; /* 0 - turned off, 1 - on */
- void *udfcache;
+ /* UDF filesystem access */
+ udfread *udf;
+ udfread_block_input udf_input;
};
#define TITLES_MAX 9
@@ -124,6 +124,7 @@ struct dvd_file_s {
unsigned char *cache;
};
+static
int InternalUDFReadBlocksRaw( const dvd_reader_t *device, uint32_t lb_number,
size_t block_count, unsigned char *data,
int encrypted );
@@ -135,31 +136,10 @@ int InternalUDFReadBlocksRaw( const dvd_reader_t *device, uint32_t lb_number,
*/
int DVDUDFCacheLevel(dvd_reader_t *device, int level)
{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
-
- if(level > 0) {
- level = 1;
- } else if(level < 0) {
- return dev->udfcache_level;
- }
-
- dev->udfcache_level = level;
-
- return level;
-}
-
-void *GetUDFCacheHandle(dvd_reader_t *device)
-{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
-
- return dev->udfcache;
-}
-
-void SetUDFCacheHandle(dvd_reader_t *device, void *cache)
-{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
-
- dev->udfcache = cache;
+ // not used with libudfread
+ (void)device;
+ (void)level;
+ return 1;
}
@@ -230,7 +210,56 @@ static int initAllCSSKeys( dvd_reader_t *dvd )
return 0;
}
+/* compability layer for old dvd_udf.c (and exposed dvd_udf.h API) */
+
+uint32_t UDFFindFile( dvd_reader_t *device, char *filename, uint32_t *size )
+{
+ uint32_t lba = 0;
+ UDFFILE *fp = udfread_file_open(device->udf, filename);
+ if (fp) {
+ *size = udfread_file_size(fp);
+ lba = udfread_file_lba(fp, 0);
+ udfread_file_close(fp);
+ }
+ return lba;
+}
+
+int UDFGetVolumeIdentifier(dvd_reader_t *device,
+ char *volid, unsigned int volid_size)
+{
+ const char *id;
+ size_t volid_len = 0;
+
+ id = udfread_get_volume_id (device->udf);
+ if (id) {
+ volid_len = strlen(id);
+
+ if (volid_size > volid_len)
+ volid_size = volid_len;
+ memcpy(volid, id, volid_size);
+ volid[volid_size] = 0;
+ }
+
+ return volid_len;
+}
+
+int UDFGetVolumeSetIdentifier(dvd_reader_t *device,
+ uint8_t *volsetid, unsigned int volsetid_size)
+{
+ return udfread_get_volume_set_id (device->udf, volsetid, volsetid_size);
+}
+
+/* */
+
+static int _bi_read(udfread_block_input *i, uint32_t lba, void *buf, uint32_t nblocks, int flags)
+{
+ dvd_reader_t *dvd = (void *)((intptr_t)i - offsetof(dvd_reader_t, udf_input));
+ if (dvdinput_seek(dvd->dev, lba) < 0) {
+ return -1;
+ }
+ return dvdinput_read(dvd->dev, buf, nblocks, flags);
+}
/**
* Open a DVD image or block device file or use stream_cb functions.
@@ -254,10 +283,16 @@ static dvd_reader_t *DVDOpenImageFile( const char *location,
dvdinput_close(dev);
return NULL;
}
- dvd->isImageFile = 1;
dvd->dev = dev;
- dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
+ dvd->udf = udfread_init();
+ //udfread_set_caching(dvd->udf, UDF_CACHE_FILE_ENTRY);
+ dvd->udf_input.read = _bi_read;
+ if (udfread_open_input(dvd->udf, &dvd->udf_input) < 0) {
+ fprintf(stderr, "failed opening UDF filesystem\n");
+ DVDClose( dvd );
+ return NULL;
+ }
if( have_css ) {
/* Only if DVDCSS_METHOD = title, a bit if it's disc or if
@@ -281,7 +316,6 @@ static dvd_reader_t *DVDOpenPath( const char *path_root )
free(dvd);
return NULL;
}
- dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
return dvd;
}
@@ -632,9 +666,9 @@ dvd_reader_t *DVDOpenStream( void *stream,
void DVDClose( dvd_reader_t *dvd )
{
if( dvd ) {
+ if( dvd->udf ) udfread_close(dvd->udf);
if( dvd->dev ) dvdinput_close( dvd->dev );
if( dvd->path_root ) free( dvd->path_root );
- if( dvd->udfcache ) FreeUDFCache( dvd->udfcache );
free( dvd );
}
}
@@ -931,7 +965,7 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
do_cache = 1;
break;
case DVD_READ_MENU_VOBS:
- if( dvd->isImageFile ) {
+ if( dvd->udf ) {
return DVDOpenVOBUDF( dvd, titlenum, 1 );
} else {
return DVDOpenVOBPath( dvd, titlenum, 1 );
@@ -939,7 +973,7 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
break;
case DVD_READ_TITLE_VOBS:
if( titlenum == 0 ) return NULL;
- if( dvd->isImageFile ) {
+ if( dvd->udf ) {
return DVDOpenVOBUDF( dvd, titlenum, 0 );
} else {
return DVDOpenVOBPath( dvd, titlenum, 0 );
@@ -950,7 +984,7 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
return NULL;
}
- if( dvd->isImageFile ) {
+ if( dvd->udf ) {
return DVDOpenFileUDF( dvd, filename, do_cache );
} else {
return DVDOpenFilePath( dvd, filename );
@@ -960,7 +994,7 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
void DVDCloseFile( dvd_file_t *dvd_file )
{
if( dvd_file && dvd_file->dvd ) {
- if( !dvd_file->dvd->isImageFile ) {
+ if( !dvd_file->dvd->udf ) {
int i;
for( i = 0; i < TITLES_MAX; ++i ) {
@@ -1105,7 +1139,7 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
break;
case DVD_READ_MENU_VOBS:
- if( dvd->isImageFile )
+ if( dvd->udf )
return DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf );
else
return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf );
@@ -1115,7 +1149,7 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
if( titlenum == 0 )
return -1;
- if( dvd->isImageFile )
+ if( dvd->udf )
return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf );
else
return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf );
@@ -1127,7 +1161,7 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
return -1;
}
- if( dvd->isImageFile ) {
+ if( dvd->udf ) {
if( UDFFindFile( dvd, filename, &size ) ) {
statbuf->size = size;
statbuf->nr_parts = 1;
@@ -1151,7 +1185,7 @@ int DVDFileStat( dvd_reader_t *dvd, int titlenum,
return -1;
}
-/* Internal, but used from dvd_udf.c */
+static
int InternalUDFReadBlocksRaw( const dvd_reader_t *device, uint32_t lb_number,
size_t block_count, unsigned char *data,
int encrypted )
@@ -1292,7 +1326,7 @@ ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
/* 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 ) {
+ if( dvd_file->dvd->udf ) {
dvdinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start );
}
/* Here each vobu has it's own dvdcss handle, so no need to update
@@ -1301,7 +1335,7 @@ ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
}*/
}
- if( dvd_file->dvd->isImageFile ) {
+ if( dvd_file->dvd->udf ) {
ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset,
block_count, data, DVDINPUT_READ_DECRYPT );
} else {
@@ -1331,7 +1365,7 @@ int DVDFileSeekForce(dvd_file_t *dvd_file, int offset, int force_size)
if( dvd_file == NULL || offset <= 0 )
return -1;
- if( dvd_file->dvd->isImageFile ) {
+ if( dvd_file->dvd->udf ) {
if( force_size < 0 )
force_size = (offset - 1) / DVD_VIDEO_LB_LEN + 1;
if( dvd_file->filesize < force_size ) {
@@ -1371,7 +1405,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_file->dvd->udf ) {
ret = DVDReadBlocksUDF( dvd_file, (uint32_t) seek_sector,
(size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
} else {
--
2.1.4
More information about the libdvdnav-devel
mailing list