⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvd_reader.c

📁 python的多媒体包,可以实现很多漂亮的功能哦
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
* Copyright (C) 2001, 2002, 2003 Billy Biggs <vektor@dumbterm.net>,
*                                H錵an Hjort <d95hjort@dtek.chalmers.se>,
*                                Bj鰎n Englund <d4bjorn@dtek.chalmers.se>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
*/

//#include "config.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <limits.h>

#include "dvdcss/dvdcss.h"
#include "dvd_udf.h"
#include "dvd_reader.h"
#include "md5.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 */
	int css_state;
	int css_title; /* Last title that we have called dvdinpute_title for. */
	
	/* Information required for an image file. */
	dvdcss_t fd;
	
	/* Information required for a directory path drive. */
	char *path_root;
  
	/* Filesystem cache */
	int udfcache_level; /* 0 - turned off, 1 - on */
	void *udfcache;
};

struct dvd_file_s {
	/* Basic information. */
	dvd_reader_t *dvd;
  
	/* Hack for selecting the right css title. */
	int css_title;
	
	/* Information required for an image file. */
	uint32_t lb_start;
	uint32_t seek_pos;
	
	/* Information required for a directory path drive. */
	size_t title_sizes[ 9 ];
	dvdcss_handle title_devs[ 9 ];
	
	/* Calculated at open-time, size in blocks. */
	int filesize;
};

/**
* Set the level of caching on udf
* level = 0 (no caching)
* level = 1 (caching filesystem info)
*/
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;
}



/**
* Close a DVD block device file.
*/
void DVDClose( dvd_reader_t *dvd )
{
	if( dvd ) {
		if( dvd->fd ) dvdcss_close( dvd->fd );
		if( dvd->path_root ) free( dvd->path_root );
		free( dvd );
	}
}

/**
* Open a DVD block device file.
*/
dvd_reader_t *DVDOpen( const char *location )
{
	dvd_reader_t *dvd;
	dvdcss_t dev;
	
	dev= dvdcss_open((char*)location); 
	if( !dev ) {
		//fprintf( stderr, "libdvdread: Can't open %s for reading\n", location );
		return 0;
	}
	
	dvd = (dvd_reader_t *)malloc( sizeof( dvd_reader_t ) );
	if( !dvd ) 
		return NULL;
	dvd->isImageFile = 1;
	dvd->fd = dev;
	dvd->path_root = 0;
	
	dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
	dvd->udfcache = NULL;
	
	/* Only if DVDCSS_METHOD = title, a bit if it's disc or if
	* DVDCSS_METHOD = key but region missmatch. Unfortunaly we
	* don't have that information. */
  
	dvd->css_state = 1; /* Need key init. */
	dvd->css_title = 0;
	
	return dvd;
}

/**
* Open an unencrypted file on a DVD image file.
*/
dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
{
	uint32_t start, len;
	dvd_file_t *dvd_file;
	
	start = UDFFindFile( dvd, filename, &len );
	if( !start ) return 0;
	
	dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
	if( !dvd_file ) return 0;
	dvd_file->dvd = dvd;
	dvd_file->lb_start = start;
	dvd_file->seek_pos = 0;
	memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
	memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
	dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
	dvd_file->title_sizes[ 0 ]= len / DVD_VIDEO_LB_LEN;
	dvd_file->title_devs[ 0 ]= dvd->fd;
	
	return dvd_file;
}


/* Loop over all titles and call dvdcss_title to crack the keys. */
static int initAllCSSKeys( dvd_reader_t *dvd )
{
	//struct timeval all_s, all_e;
	//struct timeval t_s, t_e;
	char filename[ MAX_UDF_FILE_NAME_LEN ];
	uint32_t start, len;
	int title;
	
	char *nokeys_str = getenv("DVDREAD_NOKEYS");
	if(nokeys_str != NULL)
		return 0;
	
	//fprintf( stderr, "\n" );
	//fprintf( stderr, "libdvdread: Attempting to retrieve all CSS keys\n" );
	//fprintf( stderr, "libdvdread: This can take a _long_ time, please be patient\n\n" );
	
	//gettimeofday(&all_s, NULL);
	
	for( title = 0; title < 100; title++ ) {
		//gettimeofday( &t_s, NULL );
		if( title == 0 ) {
			sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
		} else {
			sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 0 );
		}
		start = UDFFindFile( dvd, filename, &len );
		if( start != 0 && len != 0 ) {
			/* Perform CSS key cracking for this title. */
			//fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n", filename, start );
			if( dvdcss_title( dvd->fd, (int)start ) < 0 ) {
				//fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)\n", filename, start);
			}
			//gettimeofday( &t_e, NULL );
			//fprintf( stderr, "libdvdread: Elapsed time %ld\n",  
			//	(long int) t_e.tv_sec - t_s.tv_sec );
		}
		
		if( !title ) continue;
		
		//gettimeofday( &t_s, NULL );
		//sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 1 );
		start = UDFFindFile( dvd, filename, &len );
		if( start == 0 || len == 0 ) break;
		
		/* Perform CSS key cracking for this title. */
		//fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n", 
		//	filename, start );
		if( dvdcss_title( dvd->fd, (int)start ) < 0 ) {
			//fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)!!\n", filename, start);
		}
		//gettimeofday( &t_e, NULL );
		//fprintf( stderr, "libdvdread: Elapsed time %ld\n",  
		//	(long int) t_e.tv_sec - t_s.tv_sec );
	}
	title--;
	
	//fprintf( stderr, "libdvdread: Found %d VTS's\n", title );
	//gettimeofday(&all_e, NULL);
	//fprintf( stderr, "libdvdread: Elapsed time %ld\n",  
  //	(long int) all_e.tv_sec - all_s.tv_sec );
	
	return 0;
}


/**
* Open an vob file on a DVD.
*/
static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu )
{
	char filename[ MAX_UDF_FILE_NAME_LEN ];
	uint32_t start, len;
	dvd_file_t *dvd_file;
	
	if( title == 0 ) {
		sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
	} else {
		sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
	}
	start = UDFFindFile( dvd, filename, &len );
	if( start == 0 ) return 0;
	
	dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
	if( !dvd_file ) return 0;
	dvd_file->dvd = dvd;
	/*Hack*/ dvd_file->css_title = title << 1 | menu;
	dvd_file->lb_start = start;
	dvd_file->seek_pos = 0;
	memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
	memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
	dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
	
	/* Calculate the complete file size for every file in the VOBS */
	if( !menu ) {
		int cur;
		
		for( cur = 2; cur < 10; cur++ ) {
			sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
			if( !UDFFindFile( dvd, filename, &len ) ) break;
			dvd_file->filesize += len / DVD_VIDEO_LB_LEN;
		}
	}
	
	if( dvd->css_state == 1 /* Need key init */ ) {
		initAllCSSKeys( dvd );
		dvd->css_state = 2;
	}
	/*    
	if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) {
	fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n",
	filename );
	}
	*/
	
	return dvd_file;
}

/* Private  */
int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
										 size_t block_count, unsigned char *data, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -