📄 dvd_reader.c
字号:
int encrypted )
{
int ret;
ret = dvdcss_seek( device->fd, (int) lb_number, DVDCSS_SEEK_KEY );
if( ret != (int) lb_number ) {
//fprintf( stderr, "libdvdread: Can't seek to block %u\n", lb_number );
return 0;
}
return dvdcss_read( device->fd, (char *) data, (int) block_count, encrypted );
}
/* It's required to either fail or deliver all the blocks asked for. */
int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
size_t block_count, unsigned char *data,
int encrypted )
{
int ret;
size_t count = block_count;
while(count > 0) {
ret = UDFReadBlocksRaw(device, lb_number, count, data, encrypted);
if(ret <= 0) {
/* One of the reads failed or nothing more to read, too bad.
* We won't even bother returning the reads that went ok. */
return ret;
}
count -= (size_t)ret;
lb_number += (uint32_t)ret;
}
return block_count;
}
/* Reopen file by it's location */
void DVDReopen( const char *location, dvd_file_t *file )
{
file->dvd= DVDOpen( location );
}
/* Open file by it's domain type */
dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum, dvd_read_domain_t domain )
{
char filename[ MAX_UDF_FILE_NAME_LEN ];
/* Check arguments. */
if( dvd == NULL || titlenum < 0 )
return NULL;
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:
return DVDOpenVOBUDF( dvd, titlenum, 1 );
case DVD_READ_TITLE_VOBS:
if( titlenum == 0 ) return 0;
return DVDOpenVOBUDF( dvd, titlenum, 0 );
default:
//fprintf( stderr, "libdvdread: Invalid domain for file open.\n" );
return NULL;
}
return DVDOpenFileUDF( dvd, filename );
}
void DVDCloseFile( dvd_file_t *dvd_file )
{
free( dvd_file );
}
/* This is using a single input and starting from 'dvd_file->lb_start' offset.
*
* Reads 'block_count' blocks from 'dvd_file' at block offset 'offset'
* into the buffer located at 'data' and if 'encrypted' is set
* descramble the data if it's encrypted. Returning either an
* negative error or the number of blocks read. */
static int DVDReadBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
size_t block_count, unsigned char *data,
int encrypted )
{
return UDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset,
block_count, data, encrypted );
}
/* This is broken reading more than 2Gb at a time is ssize_t is 32-bit. */
int DVDReadBlocks( dvd_file_t *dvd_file, int offset,
size_t block_count, unsigned char *data )
{
/* Check arguments. */
if( dvd_file == NULL || offset < 0 || data == NULL )
return -1;
/* 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;
/* Here each vobu has it's own dvdcss handle, so no need to update
else {
dvdinput_title( dvd_file->title_devs[ 0 ], (int)dvd_file->lb_start );
}*/
}
return DVDReadBlocksUDF( dvd_file, (unsigned int)offset, block_count, data, 1 );
}
int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset )
{
/* Check arguments. */
if( dvd_file == NULL || offset < 0 )
return -1;
dvd_file->seek_pos = (uint32_t) offset;
return offset;
}
int DVDReadBytes( dvd_file_t *dvd_file, void *data, int byte_size )
{
unsigned char *secbuf;
unsigned int numsec, seek_sector, seek_byte;
int ret;
/* Check arguments. */
if( dvd_file == NULL || data == NULL )
return -1;
seek_sector = dvd_file->seek_pos / DVD_VIDEO_LB_LEN;
seek_byte = dvd_file->seek_pos % DVD_VIDEO_LB_LEN;
numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) +
( ( ( seek_byte + byte_size ) % DVD_VIDEO_LB_LEN ) ? 1 : 0 );
secbuf = (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN );
if( !secbuf ) {
//fprintf( stderr, "libdvdread: Can't allocate memory "
// "for file read!\n" );
return 0;
}
ret = DVDReadBlocksUDF( dvd_file, seek_sector, numsec, secbuf, 0 );
if( ret != (int) numsec ) {
free( secbuf );
return ret < 0 ? ret : 0;
}
memcpy( data, &(secbuf[ seek_byte ]), byte_size );
free( secbuf );
dvd_file->seek_pos += byte_size;
return byte_size;
}
int DVDFileSize( dvd_file_t *dvd_file )
{
/* Check arguments. */
if( dvd_file == NULL )
return -1;
return dvd_file->filesize;
}
int DVDDiscID( dvd_reader_t *dvd, unsigned char *discid )
{
struct md5_ctx ctx;
int title;
/* Check arguments. */
if( dvd == NULL || discid == NULL )
return 0;
/* Go through the first 10 IFO:s, in order,
* and md5sum them, i.e VIDEO_TS.IFO and VTS_0?_0.IFO */
md5_init_ctx( &ctx );
for( title = 0; title < 10; title++ ) {
dvd_file_t *dvd_file = DVDOpenFile( dvd, title, DVD_READ_INFO_FILE );
if( dvd_file != NULL ) {
int bytes_read;
int file_size = dvd_file->filesize * DVD_VIDEO_LB_LEN;
char *buffer = malloc( file_size );
if( buffer == NULL ) {
//fprintf( stderr, "libdvdread: DVDDiscId, failed to "
// "allocate memory for file read!\n" );
return -1;
}
bytes_read = DVDReadBytes( dvd_file, buffer, file_size );
if( bytes_read != file_size ) {
//fprintf( stderr, "libdvdread: DVDDiscId read returned %d bytes"
// ", wanted %d\n", bytes_read, file_size );
DVDCloseFile( dvd_file );
return -1;
}
md5_process_bytes( buffer, file_size, &ctx );
DVDCloseFile( dvd_file );
free( buffer );
}
}
md5_finish_ctx( &ctx, discid );
return 0;
}
int DVDISOVolumeInfo( dvd_reader_t *dvd,
char *volid, unsigned int volid_size,
unsigned char *volsetid, unsigned int volsetid_size )
{
unsigned char *buffer;
int ret;
/* Check arguments. */
if( dvd == NULL )
return 0;
if( dvd->fd == NULL ) {
/* No block access, so no ISO... */
return -1;
}
buffer = malloc( DVD_VIDEO_LB_LEN );
if( buffer == NULL ) {
fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
"allocate memory for file read!\n" );
return -1;
}
ret = UDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );
if( ret != 1 ) {
fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
"read ISO9660 Primary Volume Descriptor!\n" );
return -1;
}
if( (volid != NULL) && (volid_size > 0) ) {
unsigned int n;
for(n = 0; n < 32; n++) {
if(buffer[40+n] == 0x20) {
break;
}
}
if(volid_size > n+1) {
volid_size = n+1;
}
memcpy(volid, &buffer[40], volid_size-1);
volid[volid_size-1] = '\0';
}
if( (volsetid != NULL) && (volsetid_size > 0) ) {
if(volsetid_size > 128) {
volsetid_size = 128;
}
memcpy(volsetid, &buffer[190], volsetid_size);
}
return 0;
}
int DVDUDFVolumeInfo( dvd_reader_t *dvd,
char *volid, unsigned int volid_size,
unsigned char *volsetid, unsigned int volsetid_size )
{
int ret;
/* Check arguments. */
if( dvd == NULL )
return -1;
if( dvd->fd == NULL ) {
/* No block access, so no UDF VolumeSet Identifier */
return -1;
}
if( (volid != NULL) && (volid_size > 0) ) {
ret = UDFGetVolumeIdentifier(dvd, volid, volid_size);
if(!ret) {
return -1;
}
}
if( (volsetid != NULL) && (volsetid_size > 0) ) {
ret = UDFGetVolumeSetIdentifier(dvd, volsetid, volsetid_size);
if(!ret) {
return -1;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -