Commit 72f00b22 authored by Stéphane Borel's avatar Stéphane Borel

-Patch of libdvdread to do readv on regular files (dvd copied on hard drive).
Not completed, and little tested yet ; when it is completed, this patch should
be submitted to libdvdread developers.

-Patch of libdvdcss to decrypt vobs when they are not on a block device.
parent 791fb4e0
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libdvdcss.c: DVD reading library. * libdvdcss.c: DVD reading library.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: libdvdcss.c,v 1.27 2002/01/14 22:06:57 stef Exp $ * $Id: libdvdcss.c,v 1.28 2002/01/15 05:22:21 stef Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -79,7 +79,8 @@ static int _dvdcss_raw_open ( dvdcss_handle, char *psz_target ); ...@@ -79,7 +79,8 @@ static int _dvdcss_raw_open ( dvdcss_handle, char *psz_target );
*****************************************************************************/ *****************************************************************************/
extern dvdcss_handle dvdcss_open ( char *psz_target ) extern dvdcss_handle dvdcss_open ( char *psz_target )
{ {
int i_ret; struct stat fileinfo;
int i_ret;
char *psz_method = getenv( "DVDCSS_METHOD" ); char *psz_method = getenv( "DVDCSS_METHOD" );
char *psz_verbose = getenv( "DVDCSS_VERBOSE" ); char *psz_verbose = getenv( "DVDCSS_VERBOSE" );
...@@ -157,18 +158,35 @@ extern dvdcss_handle dvdcss_open ( char *psz_target ) ...@@ -157,18 +158,35 @@ extern dvdcss_handle dvdcss_open ( char *psz_target )
return NULL; return NULL;
} }
i_ret = CSSTest( dvdcss ); if( stat( psz_target, &fileinfo ) < 0 )
if( i_ret < 0 )
{ {
_dvdcss_error( dvdcss, "CSS test failed" ); _dvdcss_error( dvdcss, "dvdcss: can't stat target" );
/* Disable the CSS ioctls and hope that it works? */ }
dvdcss->b_ioctls = 0;
dvdcss->b_encrypted = 1; if( S_ISBLK( fileinfo.st_mode ) ||
S_ISCHR( fileinfo.st_mode ) )
{
i_ret = CSSTest( dvdcss );
if( i_ret < 0 )
{
_dvdcss_error( dvdcss, "CSS test failed" );
/* Disable the CSS ioctls and hope that it works? */
dvdcss->b_ioctls = 0;
dvdcss->b_encrypted = 1;
}
else
{
dvdcss->b_ioctls = 1;
dvdcss->b_encrypted = i_ret;
}
} }
else else
{ {
dvdcss->b_ioctls = 1; _dvdcss_debug( dvdcss, "dvdcss: file mode, using title method" );
dvdcss->b_encrypted = i_ret; dvdcss->i_method = DVDCSS_METHOD_TITLE;
dvdcss->b_ioctls = 0;
dvdcss->b_encrypted = 1;
memset( &dvdcss->css.disc, 0, sizeof(dvdcss->css.disc) );
} }
/* If disc is CSS protected and the ioctls work, authenticate the drive */ /* If disc is CSS protected and the ioctls work, authenticate the drive */
...@@ -182,10 +200,10 @@ extern dvdcss_handle dvdcss_open ( char *psz_target ) ...@@ -182,10 +200,10 @@ extern dvdcss_handle dvdcss_open ( char *psz_target )
free( dvdcss ); free( dvdcss );
return NULL; return NULL;
} }
memset( dvdcss->css.p_unenc_key, 0, KEY_SIZE );
} }
memset( dvdcss->css.p_unenc_key, 0, KEY_SIZE );
#ifndef WIN32 #ifndef WIN32
if( psz_raw_device != NULL ) if( psz_raw_device != NULL )
{ {
...@@ -211,7 +229,8 @@ extern int dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks, int i_flags ) ...@@ -211,7 +229,8 @@ extern int dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks, int i_flags )
{ {
/* title cracking method is too slow to be used at each seek */ /* title cracking method is too slow to be used at each seek */
if( ( ( i_flags & DVDCSS_SEEK_MPEG ) if( ( ( i_flags & DVDCSS_SEEK_MPEG )
&& ( dvdcss->i_method != DVDCSS_METHOD_TITLE ) ) ) && ( dvdcss->i_method != DVDCSS_METHOD_TITLE ) )
&& dvdcss->b_encrypted )
{ {
int i_ret; int i_ret;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* (hard-linked) and adds a readv call function to tha API. * (hard-linked) and adds a readv call function to tha API.
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>. * Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>.
* $Id: dvdread.c,v 1.2 2001/11/26 22:28:05 fgp Exp $ * $Id: dvdread.c,v 1.3 2002/01/15 05:22:21 stef Exp $
* *
* Author: Billy Biggs <vektor@dumbterm.net> * Author: Billy Biggs <vektor@dumbterm.net>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -33,18 +33,13 @@ ...@@ -33,18 +33,13 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h> #include <limits.h>
#include <dlfcn.h>
#include <dirent.h> #include <dirent.h>
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__)
#define SYS_BSD 1 #define SYS_BSD 1
#endif #endif
#ifdef SYS_DARWIN
#define off64_t off_t
#define stat64 stat
#define lseek64 lseek
#endif
#if defined(__sun) #if defined(__sun)
#include <sys/mnttab.h> #include <sys/mnttab.h>
#elif defined(SYS_BSD) #elif defined(SYS_BSD)
...@@ -86,6 +81,7 @@ struct dvd_file_s { ...@@ -86,6 +81,7 @@ struct dvd_file_s {
uint32_t seek_pos; uint32_t seek_pos;
/* Information required for a directory path drive. */ /* Information required for a directory path drive. */
dvdcss_handle title_devs[9];
size_t title_sizes[ 9 ]; size_t title_sizes[ 9 ];
int title_fds[ 9 ]; int title_fds[ 9 ];
...@@ -124,6 +120,7 @@ static dvd_reader_t *DVDOpenPath( const char *path_root ) ...@@ -124,6 +120,7 @@ static dvd_reader_t *DVDOpenPath( const char *path_root )
{ {
dvd_reader_t *dvd; dvd_reader_t *dvd;
fprintf(stderr, "libdvdread: opening %s as folder\n", path_root );
dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) ); dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
if( !dvd ) return 0; if( !dvd ) return 0;
dvd->isImageFile = 0; dvd->isImageFile = 0;
...@@ -353,11 +350,13 @@ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename ) ...@@ -353,11 +350,13 @@ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
start = UDFFindFile( dvd, filename, &len ); start = UDFFindFile( dvd, filename, &len );
if( !start ) return 0; if( !start ) return 0;
fprintf( stderr, "libdvdread: opening %s as image\n", filename );
dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
if( !dvd_file ) return 0; if( !dvd_file ) return 0;
dvd_file->dvd = dvd; dvd_file->dvd = dvd;
dvd_file->lb_start = start; dvd_file->lb_start = start;
dvd_file->seek_pos = 0; dvd_file->seek_pos = 0;
memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) ); memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
dvd_file->filesize = len / DVD_VIDEO_LB_LEN; dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
...@@ -434,6 +433,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename ) ...@@ -434,6 +433,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
/* Get the full path of the file. */ /* Get the full path of the file. */
if( !findDVDFile( dvd, filename, full_path ) ) return 0; if( !findDVDFile( dvd, filename, full_path ) ) return 0;
fprintf( stderr, "libdvdread: opening %s as file\n", full_path );
fd = open( full_path, O_RDONLY ); fd = open( full_path, O_RDONLY );
if( fd < 0 ) return 0; if( fd < 0 ) return 0;
...@@ -443,6 +443,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename ) ...@@ -443,6 +443,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
dvd_file->lb_start = 0; dvd_file->lb_start = 0;
dvd_file->seek_pos = 0; dvd_file->seek_pos = 0;
memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) ); memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
dvd_file->filesize = 0; dvd_file->filesize = 0;
...@@ -465,6 +466,7 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, ...@@ -465,6 +466,7 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd,
uint32_t start, len; uint32_t start, len;
dvd_file_t *dvd_file; dvd_file_t *dvd_file;
fprintf( stderr, "libdvdread: opening VOB as image\n" );
if( title == 0 ) { if( title == 0 ) {
sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" ); sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
} else { } else {
...@@ -510,12 +512,14 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, ...@@ -510,12 +512,14 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
dvd_file_t *dvd_file; dvd_file_t *dvd_file;
int i; int i;
fprintf( stderr, "libdvdread: opening VOB as file\n" );
dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
if( !dvd_file ) return 0; if( !dvd_file ) return 0;
dvd_file->dvd = dvd; dvd_file->dvd = dvd;
dvd_file->lb_start = 0; dvd_file->lb_start = 0;
dvd_file->seek_pos = 0; dvd_file->seek_pos = 0;
memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) ); memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
dvd_file->filesize = 0; dvd_file->filesize = 0;
...@@ -545,6 +549,8 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, ...@@ -545,6 +549,8 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
} }
dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
dvd_file->title_fds[ 0 ] = fd; dvd_file->title_fds[ 0 ] = fd;
dvd_file->title_devs[ 0 ] = dvdcss_open( full_path );
dvdcss_title( dvd_file->title_devs[0], 0 );
dvd_file->filesize = dvd_file->title_sizes[ 0 ]; dvd_file->filesize = dvd_file->title_sizes[ 0 ];
} else { } else {
...@@ -562,6 +568,8 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, ...@@ -562,6 +568,8 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
dvd_file->title_fds[ i ] = open( full_path, O_RDONLY ); dvd_file->title_fds[ i ] = open( full_path, O_RDONLY );
dvd_file->title_devs[ i ] = dvdcss_open( full_path );
dvdcss_title( dvd_file->title_devs[i], 0 );
dvd_file->filesize += dvd_file->title_sizes[ i ]; dvd_file->filesize += dvd_file->title_sizes[ i ];
} }
if( !(dvd_file->title_sizes[ 0 ]) ) { if( !(dvd_file->title_sizes[ 0 ]) ) {
...@@ -628,7 +636,10 @@ void DVDCloseFile( dvd_file_t *dvd_file ) ...@@ -628,7 +636,10 @@ void DVDCloseFile( dvd_file_t *dvd_file )
if( !dvd_file->dvd->isImageFile ) { if( !dvd_file->dvd->isImageFile ) {
for( i = 0; i < 9; ++i ) { for( i = 0; i < 9; ++i ) {
if( dvd_file->title_fds[ i ] >= 0 ) if( dvd_file->title_fds[ i ] >= 0 )
{
close( dvd_file->title_fds[ i ] ); close( dvd_file->title_fds[ i ] );
dvdcss_close( dvd_file->title_devs[i] );
}
} }
} }
...@@ -844,26 +855,103 @@ static int64_t DVDReadVBlocksUDF( dvd_file_t *dvd_file, uint32_t offset, ...@@ -844,26 +855,103 @@ static int64_t DVDReadVBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
block_count, vector, DVDCSS_READ_DECRYPT ); block_count, vector, DVDCSS_READ_DECRYPT );
} }
static int64_t DVDReadVBlocksPath( dvd_file_t *dvd_file, size_t offset,
size_t block_count, struct iovec *vector )
{
int i;
int ret, ret2;
int off;
ret = 0;
ret2 = 0;
for( i = 0 ; i < 9 ; ++i )
{
if( !dvd_file->title_sizes[ i ] )
{
return 0;
}
if( offset < dvd_file->title_sizes[ i ] )
{
if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] )
{
off = dvdcss_seek( dvd_file->title_devs[ i ],
(int)offset, 0 );
if( off != (int)offset )
{
fprintf( stderr, "libdvdread: Can't seek to block %d\n",
offset );
return 0;
}
ret = dvdcss_readv( dvd_file->title_devs[ i ], vector,
(int)block_count, DVDCSS_READ_DECRYPT );
break;
}
else
{
int part1_size = dvd_file->title_sizes[ i ] - offset;
/* FIXME: Really needs to be a while loop.
(This is only true if you try and read >1GB at a time) */
/* Read part 1 */
off = dvdcss_seek( dvd_file->title_devs[ i ], offset, 0 );
if( off != offset )
{
fprintf( stderr, "libdvdread: Can't seek to block %d\n",
offset );
return 0;
}
ret = dvdcss_readv( dvd_file->title_devs[ i ], vector,
part1_size, DVDCSS_READ_DECRYPT );
if( ret < 0 ) return ret;
/* FIXME: This is wrong if i is the last file in the set.
also error from this read will not show in ret. */
/* Read part 2 */
dvdcss_seek( dvd_file->title_devs[ i + 1 ], 0, 0 );
ret2 = dvdcss_readv( dvd_file->title_devs[ i + 1 ],
vector + part1_size, (int)(block_count - part1_size),
DVDCSS_READ_DECRYPT );
if( ret2 < 0 ) return ret2;
break;
}
}
else
{
offset -= dvd_file->title_sizes[ i ];
}
}
return ( ret + ret2 ) * (int64_t) DVD_VIDEO_LB_LEN;
}
ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset, ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset,
size_t block_count, struct iovec * vector ) size_t block_count, struct iovec * vector )
{ {
int64_t ret; int64_t ret;
if( dvd_file->dvd->isImageFile ) { if( dvd_file->dvd->isImageFile )
ret = DVDReadVBlocksUDF( dvd_file, (uint32_t)offset, {
block_count, vector ); ret = DVDReadVBlocksUDF( dvd_file, (uint32_t)offset,
} else { block_count, vector );
ret = 0;//= DVDReadVBlocksPath( dvd_file, (size_t) offset,
// block_count, vector );
} }
if( ret <= 0 ) { else
{
ret = DVDReadVBlocksPath( dvd_file, (size_t) offset,
block_count, vector );
}
if( ret <= 0 )
{
return (ssize_t) ret; return (ssize_t) ret;
} }
{ {
ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN ); ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN );
if( sret == 0 ) { if( sret == 0 )
fprintf(stderr, "libdvdread: DVDReadVBlocks got %d bytes\n", (int)ret ); {
fprintf(stderr, "libdvdread: DVDReadVBlocks got %d bytes\n", (int)ret );
} }
return sret; return sret;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* (hard-linked) and adds a readv call function to tha API. * (hard-linked) and adds a readv call function to tha API.
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>. * Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>.
* $Id: dvdread.c,v 1.1 2001/11/25 05:04:38 stef Exp $ * $Id: dvdread.c,v 1.2 2002/01/15 05:22:21 stef Exp $
* *
* Author: Billy Biggs <vektor@dumbterm.net> * Author: Billy Biggs <vektor@dumbterm.net>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -81,6 +81,7 @@ struct dvd_file_s { ...@@ -81,6 +81,7 @@ struct dvd_file_s {
uint32_t seek_pos; uint32_t seek_pos;
/* Information required for a directory path drive. */ /* Information required for a directory path drive. */
dvdcss_handle title_devs[9];
size_t title_sizes[ 9 ]; size_t title_sizes[ 9 ];
int title_fds[ 9 ]; int title_fds[ 9 ];
...@@ -119,6 +120,7 @@ static dvd_reader_t *DVDOpenPath( const char *path_root ) ...@@ -119,6 +120,7 @@ static dvd_reader_t *DVDOpenPath( const char *path_root )
{ {
dvd_reader_t *dvd; dvd_reader_t *dvd;
fprintf(stderr, "libdvdread: opening %s as folder\n", path_root );
dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) ); dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
if( !dvd ) return 0; if( !dvd ) return 0;
dvd->isImageFile = 0; dvd->isImageFile = 0;
...@@ -348,11 +350,13 @@ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename ) ...@@ -348,11 +350,13 @@ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
start = UDFFindFile( dvd, filename, &len ); start = UDFFindFile( dvd, filename, &len );
if( !start ) return 0; if( !start ) return 0;
fprintf( stderr, "libdvdread: opening %s as image\n", filename );
dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
if( !dvd_file ) return 0; if( !dvd_file ) return 0;
dvd_file->dvd = dvd; dvd_file->dvd = dvd;
dvd_file->lb_start = start; dvd_file->lb_start = start;
dvd_file->seek_pos = 0; dvd_file->seek_pos = 0;
memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) ); memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
dvd_file->filesize = len / DVD_VIDEO_LB_LEN; dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
...@@ -429,6 +433,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename ) ...@@ -429,6 +433,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
/* Get the full path of the file. */ /* Get the full path of the file. */
if( !findDVDFile( dvd, filename, full_path ) ) return 0; if( !findDVDFile( dvd, filename, full_path ) ) return 0;
fprintf( stderr, "libdvdread: opening %s as file\n", full_path );
fd = open( full_path, O_RDONLY ); fd = open( full_path, O_RDONLY );
if( fd < 0 ) return 0; if( fd < 0 ) return 0;
...@@ -438,6 +443,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename ) ...@@ -438,6 +443,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
dvd_file->lb_start = 0; dvd_file->lb_start = 0;
dvd_file->seek_pos = 0; dvd_file->seek_pos = 0;
memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) ); memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
dvd_file->filesize = 0; dvd_file->filesize = 0;
...@@ -460,6 +466,7 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, ...@@ -460,6 +466,7 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd,
uint32_t start, len; uint32_t start, len;
dvd_file_t *dvd_file; dvd_file_t *dvd_file;
fprintf( stderr, "libdvdread: opening VOB as image\n" );
if( title == 0 ) { if( title == 0 ) {
sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" ); sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
} else { } else {
...@@ -505,12 +512,14 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, ...@@ -505,12 +512,14 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
dvd_file_t *dvd_file; dvd_file_t *dvd_file;
int i; int i;
fprintf( stderr, "libdvdread: opening VOB as file\n" );
dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
if( !dvd_file ) return 0; if( !dvd_file ) return 0;
dvd_file->dvd = dvd; dvd_file->dvd = dvd;
dvd_file->lb_start = 0; dvd_file->lb_start = 0;
dvd_file->seek_pos = 0; dvd_file->seek_pos = 0;
memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) ); memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
dvd_file->filesize = 0; dvd_file->filesize = 0;
...@@ -540,6 +549,8 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, ...@@ -540,6 +549,8 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
} }
dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
dvd_file->title_fds[ 0 ] = fd; dvd_file->title_fds[ 0 ] = fd;
dvd_file->title_devs[ 0 ] = dvdcss_open( full_path );
dvdcss_title( dvd_file->title_devs[0], 0 );
dvd_file->filesize = dvd_file->title_sizes[ 0 ]; dvd_file->filesize = dvd_file->title_sizes[ 0 ];
} else { } else {
...@@ -557,6 +568,8 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, ...@@ -557,6 +568,8 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
dvd_file->title_fds[ i ] = open( full_path, O_RDONLY ); dvd_file->title_fds[ i ] = open( full_path, O_RDONLY );
dvd_file->title_devs[ i ] = dvdcss_open( full_path );
dvdcss_title( dvd_file->title_devs[i], 0 );
dvd_file->filesize += dvd_file->title_sizes[ i ]; dvd_file->filesize += dvd_file->title_sizes[ i ];
} }
if( !(dvd_file->title_sizes[ 0 ]) ) { if( !(dvd_file->title_sizes[ 0 ]) ) {
...@@ -623,7 +636,10 @@ void DVDCloseFile( dvd_file_t *dvd_file ) ...@@ -623,7 +636,10 @@ void DVDCloseFile( dvd_file_t *dvd_file )
if( !dvd_file->dvd->isImageFile ) { if( !dvd_file->dvd->isImageFile ) {
for( i = 0; i < 9; ++i ) { for( i = 0; i < 9; ++i ) {
if( dvd_file->title_fds[ i ] >= 0 ) if( dvd_file->title_fds[ i ] >= 0 )
{
close( dvd_file->title_fds[ i ] ); close( dvd_file->title_fds[ i ] );
dvdcss_close( dvd_file->title_devs[i] );
}
} }
} }
...@@ -839,26 +855,103 @@ static int64_t DVDReadVBlocksUDF( dvd_file_t *dvd_file, uint32_t offset, ...@@ -839,26 +855,103 @@ static int64_t DVDReadVBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
block_count, vector, DVDCSS_READ_DECRYPT ); block_count, vector, DVDCSS_READ_DECRYPT );
} }
static int64_t DVDReadVBlocksPath( dvd_file_t *dvd_file, size_t offset,
size_t block_count, struct iovec *vector )
{
int i;
int ret, ret2;
int off;
ret = 0;
ret2 = 0;
for( i = 0 ; i < 9 ; ++i )
{
if( !dvd_file->title_sizes[ i ] )
{
return 0;
}
if( offset < dvd_file->title_sizes[ i ] )
{
if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] )
{
off = dvdcss_seek( dvd_file->title_devs[ i ],
(int)offset, 0 );
if( off != (int)offset )
{
fprintf( stderr, "libdvdread: Can't seek to block %d\n",
offset );
return 0;
}
ret = dvdcss_readv( dvd_file->title_devs[ i ], vector,
(int)block_count, DVDCSS_READ_DECRYPT );
break;
}
else
{
int part1_size = dvd_file->title_sizes[ i ] - offset;
/* FIXME: Really needs to be a while loop.
(This is only true if you try and read >1GB at a time) */
/* Read part 1 */
off = dvdcss_seek( dvd_file->title_devs[ i ], offset, 0 );
if( off != offset )
{
fprintf( stderr, "libdvdread: Can't seek to block %d\n",
offset );
return 0;
}
ret = dvdcss_readv( dvd_file->title_devs[ i ], vector,
part1_size, DVDCSS_READ_DECRYPT );
if( ret < 0 ) return ret;
/* FIXME: This is wrong if i is the last file in the set.
also error from this read will not show in ret. */
/* Read part 2 */
dvdcss_seek( dvd_file->title_devs[ i + 1 ], 0, 0 );
ret2 = dvdcss_readv( dvd_file->title_devs[ i + 1 ],
vector + part1_size, (int)(block_count - part1_size),
DVDCSS_READ_DECRYPT );
if( ret2 < 0 ) return ret2;
break;
}
}
else
{
offset -= dvd_file->title_sizes[ i ];
}
}
return ( ret + ret2 ) * (int64_t) DVD_VIDEO_LB_LEN;
}
ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset, ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset,
size_t block_count, struct iovec * vector ) size_t block_count, struct iovec * vector )
{ {
int64_t ret; int64_t ret;
if( dvd_file->dvd->isImageFile ) { if( dvd_file->dvd->isImageFile )
ret = DVDReadVBlocksUDF( dvd_file, (uint32_t)offset, {
block_count, vector ); ret = DVDReadVBlocksUDF( dvd_file, (uint32_t)offset,
} else { block_count, vector );
ret = 0;//= DVDReadVBlocksPath( dvd_file, (size_t) offset,
// block_count, vector );
} }
if( ret <= 0 ) { else
{
ret = DVDReadVBlocksPath( dvd_file, (size_t) offset,
block_count, vector );
}
if( ret <= 0 )
{
return (ssize_t) ret; return (ssize_t) ret;
} }
{ {
ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN ); ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN );
if( sret == 0 ) { if( sret == 0 )
fprintf(stderr, "libdvdread: DVDReadVBlocks got %d bytes\n", (int)ret ); {
fprintf(stderr, "libdvdread: DVDReadVBlocks got %d bytes\n", (int)ret );
} }
return sret; return sret;
} }
......
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