Commit 6dfeb9b5 authored by Thomas Guillem's avatar Thomas Guillem Committed by Jean-Baptiste Kempf

add DVDOpenStream

open a DVD Device using external read/seek callbacks (see libdvdcss).
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent f5ea9142
......@@ -30,7 +30,7 @@
/* The function pointers that is the exported interface of this file. */
dvd_input_t (*dvdinput_open) (const char *);
dvd_input_t (*dvdinput_open) (const char *, void *, dvd_reader_stream_cb *);
int (*dvdinput_close) (dvd_input_t);
int (*dvdinput_seek) (dvd_input_t, int);
int (*dvdinput_title) (dvd_input_t, int);
......@@ -40,6 +40,8 @@ char * (*dvdinput_error) (dvd_input_t);
#ifdef HAVE_DVDCSS_DVDCSS_H
/* linking to libdvdcss */
# include <dvdcss/dvdcss.h>
# define DVDcss_open_stream(a, b) \
dvdcss_open_stream((void*)(a), (dvdcss_stream_cb*)(b))
# define DVDcss_open(a) dvdcss_open((char*)(a))
# define DVDcss_close dvdcss_close
# define DVDcss_seek dvdcss_seek
......@@ -58,6 +60,8 @@ char * (*dvdinput_error) (dvd_input_t);
#endif
typedef struct dvdcss_s *dvdcss_t;
typedef struct dvdcss_stream_cb dvdcss_stream_cb;
static dvdcss_t (*DVDcss_open_stream) (void *, dvdcss_stream_cb *);
static dvdcss_t (*DVDcss_open) (const char *);
static int (*DVDcss_close) (dvdcss_t);
static int (*DVDcss_seek) (dvdcss_t, int, int);
......@@ -77,9 +81,10 @@ struct dvd_input_s {
/**
* initialize and open a DVD device or file.
* initialize and open a DVD (device or file or stream_cb)
*/
static dvd_input_t css_open(const char *target)
static dvd_input_t css_open(const char *target,
void *stream, dvd_reader_stream_cb *stream_cb)
{
dvd_input_t dev;
......@@ -91,7 +96,10 @@ static dvd_input_t css_open(const char *target)
}
/* Really open it with libdvdcss */
dev->dvdcss = DVDcss_open(target);
if(target)
dev->dvdcss = DVDcss_open(target);
else if(stream && stream_cb)
dev->dvdcss = DVDcss_open_stream(stream, (dvdcss_stream_cb *)stream_cb);
if(dev->dvdcss == 0) {
fprintf(stderr, "libdvdread: Could not open %s with libdvdcss.\n", target);
free(dev);
......@@ -154,10 +162,13 @@ static int css_close(dvd_input_t dev)
/**
* initialize and open a DVD device or file.
*/
static dvd_input_t file_open(const char *target)
static dvd_input_t file_open(const char *target,
void *stream, dvd_reader_stream_cb *stream_cb)
{
dvd_input_t dev;
if(target == NULL)
return NULL;
/* Allocate the library structure */
dev = malloc(sizeof(*dev));
if(dev == NULL) {
......@@ -299,6 +310,8 @@ int dvdinput_setup(void)
#else
#define U_S
#endif
DVDcss_open_stream = (dvdcss_t (*)(void *, dvdcss_stream_cb *))
dlsym(dvdcss_library, U_S "dvdcss_open_stream");
DVDcss_open = (dvdcss_t (*)(const char*))
dlsym(dvdcss_library, U_S "dvdcss_open");
DVDcss_close = (int (*)(dvdcss_t))
......@@ -317,7 +330,7 @@ int dvdinput_setup(void)
"http://www.videolan.org/\n" );
dlclose(dvdcss_library);
dvdcss_library = NULL;
} else if(!DVDcss_open || !DVDcss_close || !DVDcss_seek
} else if(!DVDcss_open_stream ||!DVDcss_open || !DVDcss_close || !DVDcss_seek
|| !DVDcss_read || !DVDcss_error) {
fprintf(stderr, "libdvdread: Missing symbols in %s, "
"this shouldn't happen !\n", CSS_LIB);
......
......@@ -55,7 +55,8 @@ typedef struct dvd_input_s *dvd_input_t;
* Function pointers that will be filled in by the input implementation.
* These functions provide the main API.
*/
extern dvd_input_t (*dvdinput_open) (const char *);
extern dvd_input_t (*dvdinput_open) (const char *,
void *, dvd_reader_stream_cb *);
extern int (*dvdinput_close) (dvd_input_t);
extern int (*dvdinput_seek) (dvd_input_t, int);
extern int (*dvdinput_title) (dvd_input_t, int);
......
......@@ -229,14 +229,17 @@ static int initAllCSSKeys( dvd_reader_t *dvd )
/**
* Open a DVD image or block device file.
* Open a DVD image or block device file or use stream_cb functions.
*/
static dvd_reader_t *DVDOpenImageFile( const char *location, int have_css )
static dvd_reader_t *DVDOpenImageFile( const char *location,
void *stream,
dvd_reader_stream_cb *stream_cb,
int have_css )
{
dvd_reader_t *dvd;
dvd_input_t dev;
dev = dvdinput_open( location );
dev = dvdinput_open( location, stream, stream_cb );
if( !dev ) {
fprintf( stderr, "libdvdread: Can't open %s for reading\n", location );
return NULL;
......@@ -343,8 +346,9 @@ static char *bsd_block2char( const char *path )
}
#endif
dvd_reader_t *DVDOpen( const char *ppath )
static dvd_reader_t *DVDOpenCommon( const char *ppath,
void *stream,
dvd_reader_stream_cb *stream_cb )
{
struct stat fileinfo;
int ret, have_css, retval, cdir = -1;
......@@ -356,6 +360,13 @@ dvd_reader_t *DVDOpen( const char *ppath )
int len;
#endif
/* Try to open DVD using stream_cb functions */
if( stream != NULL && stream_cb != NULL )
{
have_css = dvdinput_setup();
return DVDOpenImageFile( NULL, stream, stream_cb, have_css );
}
if( ppath == NULL )
goto DVDOpen_error;
......@@ -383,7 +394,7 @@ dvd_reader_t *DVDOpen( const char *ppath )
/* maybe "host:port" url? try opening it with acCeSS library */
if( strchr(path,':') ) {
ret_val = DVDOpenImageFile( path, have_css );
ret_val = DVDOpenImageFile( path, NULL, NULL, have_css );
free(path);
return ret_val;
}
......@@ -412,7 +423,7 @@ dvd_reader_t *DVDOpen( const char *ppath )
#endif
if(!dev_name)
goto DVDOpen_error;
dvd = DVDOpenImageFile( dev_name, have_css );
dvd = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
free( dev_name );
free(path);
return dvd;
......@@ -503,7 +514,7 @@ dvd_reader_t *DVDOpen( const char *ppath )
" mounted on %s for CSS authentication\n",
dev_name,
s[i].f_mntonname);
auth_drive = DVDOpenImageFile( dev_name, have_css );
auth_drive = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
break;
}
}
......@@ -516,7 +527,7 @@ dvd_reader_t *DVDOpen( const char *ppath )
" mounted on %s for CSS authentication\n",
dev_name,
fe->fs_file );
auth_drive = DVDOpenImageFile( dev_name, have_css );
auth_drive = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
}
#elif defined(__sun)
mntfile = fopen( MNTTAB, "r" );
......@@ -532,7 +543,7 @@ dvd_reader_t *DVDOpen( const char *ppath )
" mounted on %s for CSS authentication\n",
dev_name,
mp.mnt_mountp );
auth_drive = DVDOpenImageFile( dev_name, have_css );
auth_drive = DVDOpenImageFile( dev_name, NULL, NULL, have_css );
break;
}
}
......@@ -550,7 +561,7 @@ dvd_reader_t *DVDOpen( const char *ppath )
" mounted on %s for CSS authentication\n",
me->mnt_fsname,
me->mnt_dir );
auth_drive = DVDOpenImageFile( me->mnt_fsname, have_css );
auth_drive = DVDOpenImageFile( me->mnt_fsname, NULL, NULL, have_css );
dev_name = strdup(me->mnt_fsname);
break;
}
......@@ -564,7 +575,7 @@ dvd_reader_t *DVDOpen( const char *ppath )
( !path[2] ||
((path[2] == '\\' || path[2] == '/') && !path[3])))
#endif
auth_drive = DVDOpenImageFile( path, have_css );
auth_drive = DVDOpenImageFile( path, NULL, NULL, have_css );
#endif
#if !defined(_WIN32) && !defined(__OS2__)
......@@ -612,6 +623,17 @@ DVDOpen_error:
return NULL;
}
dvd_reader_t *DVDOpen( const char *ppath )
{
return DVDOpenCommon( ppath, NULL, NULL );
}
dvd_reader_t *DVDOpenStream( void *stream,
dvd_reader_stream_cb *stream_cb )
{
return DVDOpenCommon( NULL, stream, stream_cb );
}
void DVDClose( dvd_reader_t *dvd )
{
if( dvd ) {
......@@ -726,7 +748,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
return NULL;
}
dev = dvdinput_open( full_path );
dev = dvdinput_open( full_path, NULL, NULL );
if( !dev ) {
fprintf( stderr, "libdvdread:DVDOpenFilePath:dvdinput_open %s failed\n", full_path );
return NULL;
......@@ -837,7 +859,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
return NULL;
}
dev = dvdinput_open( full_path );
dev = dvdinput_open( full_path, NULL, NULL );
if( dev == NULL ) {
free( dvd_file );
return NULL;
......@@ -870,7 +892,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
}
dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
dvd_file->title_devs[ i ] = dvdinput_open( full_path );
dvd_file->title_devs[ i ] = dvdinput_open( full_path, NULL, NULL );
dvdinput_title( dvd_file->title_devs[ i ], 0 );
dvd_file->filesize += dvd_file->title_sizes[ i ];
}
......
......@@ -69,6 +69,14 @@ typedef struct dvd_reader_s dvd_reader_t;
*/
typedef struct dvd_file_s dvd_file_t;
struct dvd_reader_stream_cb
{
int ( *pf_seek ) ( void *p_stream, uint64_t i_pos);
int ( *pf_read ) ( void *p_stream, void* buffer, int i_read);
int ( *pf_readv ) ( void *p_stream, void *p_iovec, int i_blocks);
};
typedef struct dvd_reader_stream_cb dvd_reader_stream_cb;
/**
* Public type that is used to provide statistics on a handle.
*/
......@@ -81,6 +89,8 @@ typedef struct {
/**
* 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.
* The second form of Open function (DVDOpenStream) can be used to
* provide custom stream_cb functions to access the DVD (see libdvdcss).
*
* If the given file is a block device, or is the mountpoint for a block
* device, then that device is used for CSS authentication using libdvdcss.
......@@ -96,11 +106,15 @@ typedef struct {
* path/vts_01_1.vob
*
* @param path Specifies the the device, file or directory to be used.
* @param stream is a private handle used by stream_cb
* @param stream_cb is a struct containing seek and read functions
* @return If successful a a read handle is returned. Otherwise 0 is returned.
*
* dvd = DVDOpen(path);
* dvd = DVDOpenStream(stream, &stream_cb);
*/
dvd_reader_t *DVDOpen( const char * );
dvd_reader_t *DVDOpenStream( void *, dvd_reader_stream_cb * );
/**
* Closes and cleans up the DVD reader object.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment