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

📄 dvd_reader.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- *//* * Copyright (C) 2001, 2002, 2003 Billy Biggs <vektor@dumbterm.net>, *                                H錵an Hjort <d95hjort@dtek.chalmers.se>, *                                Bj鰎n Englund <d4bjorn@dtek.chalmers.se> * * Modified for use with MPlayer, changes contained in libdvdread_changes.diff. * detailed changelog at http://svn.mplayerhq.hu/mplayer/trunk/ * $Id: dvd_reader.c,v 1.2 2008/03/03 08:11:34 dsqiu Exp $ * * 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 <sys/time.h> /* For the timing of dvdcss_title crack. */#include <fcntl.h>#include <mplaylib.h>#include <mplaylib.h>#include <errno.h>#include <mplaylib.h>#include <mplaylib.h>#include <dirent.h> #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__DARWIN__) || defined(__DragonFly__)#define SYS_BSD 1#endif#if defined(__sun)#include <sys/mnttab.h>#elif defined(hpux)#include </usr/conf/h/mnttab.h>#elif defined(SYS_BSD)#include <fstab.h>#elif defined(__linux__) || defined(__CYGWIN__)#include <mntent.h>#endif#include "dvd_reader.h"#include "dvd_input.h"#include "dvd_udf.h"#include "md5.h"#include "dvdread_internal.h"#define DEFAULT_UDF_CACHE_LEVEL 0struct 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. */  dvd_input_t dev;  /* Information required for a directory path drive. */  char *path_root;    /* Filesystem cache */  int udfcache_level; /* 0 - turned off, 1 - on */  void *udfcache;  /* block aligned malloc */  void *align;    /* error message verbosity level */  int verbose;};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 ];  dvd_input_t title_devs[ 9 ];  /* Calculated at open-time, size in blocks. */  ssize_t filesize;};#define DVDREAD_VERBOSE_DEFAULT 0int get_verbose(void){  char *dvdread_verbose;  int verbose;    dvdread_verbose = getenv("DVDREAD_VERBOSE");  if(dvdread_verbose) {    verbose = (int)strtol(dvdread_verbose, NULL, 0);  } else {    verbose = DVDREAD_VERBOSE_DEFAULT;  }  return verbose;}int dvdread_verbose(dvd_reader_t *dvd){  return dvd->verbose;}dvd_reader_t *device_of_file(dvd_file_t *file){  return file->dvd;}/** * Returns the compiled version. (DVDREAD_VERSION as an int) */int DVDVersion(void){  return DVDREAD_VERSION;}/** * 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;}void *GetAlignHandle(dvd_reader_t *device){  struct dvd_reader_s *dev = (struct dvd_reader_s *)device;    return dev->align;}void SetAlignHandle(dvd_reader_t *device, void *align){  struct dvd_reader_s *dev = (struct dvd_reader_s *)device;  dev->align = align;}/* 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;      if(dvd->verbose >= 1) {    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. */      if(dvd->verbose >= 1) {        fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",                  filename, start );      }      if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {        if(dvd->verbose >= 0) {          fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)\n", filename, start);        }      }      gettimeofday( &t_e, NULL );      if(dvd->verbose >= 1) {        fprintf( stderr, "libdvdread: Elapsed time %ld\n",                   (long int) t_e.tv_sec - t_s.tv_sec );      }    }                if( title == 0 ) 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. */    if(dvd->verbose >= 1) {      fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",                filename, start );    }    if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {      if(dvd->verbose >= 0) {        fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)!!\n", filename, start);      }    }    gettimeofday( &t_e, NULL );    if(dvd->verbose >= 1) {      fprintf( stderr, "libdvdread: Elapsed time %ld\n",                 (long int) t_e.tv_sec - t_s.tv_sec );    }  }  title--;      if(dvd->verbose >= 1) {    fprintf( stderr, "libdvdread: Found %d VTS's\n", title );  }  gettimeofday(&all_e, NULL);  if(dvd->verbose >= 1) {    fprintf( stderr, "libdvdread: Elapsed time %ld\n",               (long int) all_e.tv_sec - all_s.tv_sec );  }  return 0;}/** * Open a DVD image or block device file. * Checks if the root directory in the udf image file can be found. * If not it assumes this isn't a valid udf image and returns NULL */static dvd_reader_t *DVDOpenImageFile( const char *location, int have_css ){  dvd_reader_t *dvd;  dvd_input_t dev;  int verbose;  verbose = get_verbose();  dev = dvdinput_open( location );  if( !dev ) {    if(verbose >= 1) {      fprintf( stderr, "libdvdread: Can't open '%s' for reading: %s\n",               location, strerror(errno));    }    return NULL;  }  dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );  if( !dvd ) {    int tmp_errno = errno;    dvdinput_close(dev);    errno = tmp_errno;    return NULL;  }  dvd->verbose = verbose;  dvd->isImageFile = 1;  dvd->dev = dev;  dvd->path_root = NULL;      dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;  dvd->udfcache = NULL;  dvd->align = NULL;  if( have_css ) {    /* 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;    /* sanity check, is it a valid UDF image, can we find the root dir */  if(!UDFFindFile(dvd, "/", NULL)) {    dvdinput_close(dvd->dev);    if(dvd->udfcache) {      FreeUDFCache(dvd, dvd->udfcache);    }    if(dvd->align) {      if(dvd->verbose >= 0) {        fprintf(stderr, "libdvdread: DVDOpenImageFile(): Memory leak in align functions 1\n");      }    }    free(dvd);    return NULL;  }  return dvd;}static dvd_reader_t *DVDOpenPath( const char *path_root ){  dvd_reader_t *dvd;  dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );  if( !dvd ) {    return NULL;  }  dvd->verbose = get_verbose();  dvd->isImageFile = 0;  dvd->dev = 0;  dvd->path_root = strdup( path_root );  if(!dvd->path_root) {    free(dvd);    return 0;  }  dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;  dvd->udfcache = NULL;  dvd->align = NULL;  dvd->css_state = 0; /* Only used in the UDF path */  dvd->css_title = 0; /* Only matters in the UDF path */  return dvd;}#if defined(__sun)/* /dev/rdsk/c0t6d0s0 (link to /devices/...)   /vol/dev/rdsk/c0t6d0/??   /vol/rdsk/<name> */static char *sun_block2char( const char *path ){  char *new_path;  /* Must contain "/dsk/" */   if( !strstr( path, "/dsk/" ) ) return (char *) strdup( path );  /* Replace "/dsk/" with "/rdsk/" */  new_path = malloc( strlen(path) + 2 );  strcpy( new_path, path );  strcpy( strstr( new_path, "/dsk/" ), "" );  strcat( new_path, "/rdsk/" );  strcat( new_path, strstr( path, "/dsk/" ) + strlen( "/dsk/" ) );  return new_path;}#endif#if defined(SYS_BSD)/* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recomended to _not_ use r   update: FreeBSD and DragonFly no longer uses the prefix so don't add it.   OpenBSD /dev/rcd0c, it needs to be the raw device   NetBSD  /dev/rcd0[d|c|..] d for x86, c (for non x86), perhaps others   Darwin  /dev/rdisk0,  it needs to be the raw device   BSD/OS  /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do)      returns a string allocated with strdup which should be free()'d when   no longer used.*/static char *bsd_block2char( const char *path ){#if defined(__FreeBSD__) || defined(__DragonFly__)  return (char *) strdup( path );#else  char *new_path;  /* If it doesn't start with "/dev/" or does start with "/dev/r" exit */   if( strncmp( path, "/dev/",  5 ) || !strncmp( path, "/dev/r", 6 ) )     return (char *) strdup( path );  /* Replace "/dev/" with "/dev/r" */  new_path = malloc( strlen(path) + 2 );  strcpy( new_path, "/dev/r" );  strcat( new_path, path + strlen( "/dev/" ) );  return new_path;#endif /* __FreeBSD__ || __DragonFly__ */}#endifdvd_reader_t *DVDOpen( const char *path ){  struct stat fileinfo;  int ret, have_css;  char *dev_name = NULL;  int internal_errno = 0;  int verbose;  if( path == NULL ) {    errno = EINVAL;    return NULL;  }    verbose = get_verbose();#ifdef WIN32  /* Stat doesn't work on devices under mingwin/cygwin. */  if( path[0] && path[1] == ':' && path[2] == '\0' )    {      /* Don't try to stat the file */      fileinfo.st_mode = S_IFBLK;    }  else#endif    {      ret = stat( path, &fileinfo );      if( ret < 0 ) {        int tmp_errno = errno;        /* If we can't stat the file, give up */        if(verbose >= 1) {          fprintf( stderr, "libdvdread: Can't stat '%s': %s\n",                   path, strerror(errno));        }        errno = tmp_errno;        return NULL;      }    }  /* Try to open libdvdcss or fall back to standard functions */  have_css = dvdinput_setup();  /* First check if this is a block/char device or a file*/  if( S_ISBLK( fileinfo.st_mode ) ||       S_ISCHR( fileinfo.st_mode ) ||       S_ISREG( fileinfo.st_mode ) ) {    /**     * Block devices and regular files are assumed to be DVD-Video images.     */    dvd_reader_t *dvd = NULL;#if defined(__sun)    dev_name = sun_block2char( path );#elif defined(SYS_BSD)    dev_name = bsd_block2char( path );#else    dev_name = strdup( path );#endif    dvd = DVDOpenImageFile( dev_name, have_css );    free( dev_name );        return dvd;  } else if( S_ISDIR( fileinfo.st_mode ) ) {    dvd_reader_t *auth_drive = 0;    char *path_copy;#if defined(SYS_BSD)    struct fstab* fe;#elif defined(__sun) || defined(__linux__) || defined(__CYGWIN__)    FILE *mntfile;#endif    /* XXX: We should scream real loud here. */    if( !(path_copy = strdup( path ) ) ) return 0;#ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange */    /* Resolve any symlinks and get the absolut dir name. */    {      char *new_path;      char *current_path;      current_path = malloc(PATH_MAX);      if(current_path) {        if(!getcwd(current_path, PATH_MAX)) {          free(current_path);          current_path = NULL;        }      }      if(current_path) {        chdir( path_copy );        new_path = malloc(PATH_MAX);        if(new_path) {          if(!getcwd(new_path, PATH_MAX )) {            free(new_path);            new_path = NULL;          }        }        chdir(current_path);        free(current_path);        if( new_path ) {          free( path_copy );          path_copy = new_path;        }      }    }#endif            /**     * If we're being asked to open a directory, check if that directory     * is the mountpoint for a DVD-ROM which we can use instead.     */    if( strlen( path_copy ) > 1 ) {      if( path_copy[ strlen( path_copy ) - 1 ] == '/' ) {        path_copy[ strlen( path_copy ) - 1 ] = '\0';

⌨️ 快捷键说明

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