view libmpdvdkit2/libdvdread_changes.diff @ 15148:067f10ad6538

New section: "menc-feat-dvd-mpeg4-muxing" about how to mux a video obtained with MEncoder into different containers. Based on Rich's guide and some tips by Nico Sabi. Reviewed by The Wanderer, Dominik 'Rathann' Mierzejewski and Diego Biurrun
author gpoirier
date Wed, 13 Apr 2005 18:53:30 +0000
parents d18e40806248
children 5b5ca5c4f381
line wrap: on
line source

--- dvdread/bswap.h	2002-04-07 19:52:00.000000000 +0200
+++ bswap.h	2005-03-01 07:07:45.000000000 +0100
@@ -20,8 +20,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
-#include <config.h>
-
 #if defined(WORDS_BIGENDIAN)
 /* All bigendian systems are fine, just ignore the swaps. */  
 #define B2N_16(x) (void)(x)
@@ -48,13 +46,51 @@
 #define B2N_32(x) x = swap32(x)
 #define B2N_64(x) x = swap64(x)
 
+#elif defined(ARCH_X86)
+inline static unsigned short bswap_16(unsigned short x)
+{
+  __asm("xchgb %b0,%h0" :
+        "=q" (x)        :
+        "0" (x));
+    return x;
+}
+#define B2N_16(x) x = bswap_16(x)
+
+inline static unsigned int bswap_32(unsigned int x)
+{
+ __asm(
+#if __CPU__ > 386
+      "bswap   %0":
+      "=r" (x)     :
+#else
+      "xchgb   %b0,%h0\n"
+      " rorl    $16,%0\n"
+      " xchgb   %b0,%h0":
+      "=q" (x)          :
+#endif
+      "0" (x));
+  return x;
+}
+#define B2N_32(x) x = bswap_32(x)
+
+inline static unsigned long long int bswap_64(unsigned long long int x)
+{
+  register union { __extension__ uint64_t __ll;
+          uint32_t __l[2]; } __x;
+  asm("xchgl    %0,%1":
+      "=r"(__x.__l[0]),"=r"(__x.__l[1]):
+      "0"(bswap_32((unsigned long)x)),"1"(bswap_32((unsigned long)(x>>32))));
+  return __x.__ll;
+}
+#define B2N_64(x) x = bswap_64(x)
+
 /* This is a slow but portable implementation, it has multiple evaluation 
  * problems so beware.
  * FreeBSD and Solaris don't have <byteswap.h> or any other such 
  * functionality! 
  */
 
-#elif defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__)
+#elif defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__) || defined(__CYGWIN__)
 #define B2N_16(x) \
  x = ((((x) & 0xff00) >> 8) | \
       (((x) & 0x00ff) << 8))
--- dvdread/dvd_input.c	2002-05-09 23:32:46.000000000 +0200
+++ dvd_input.c	2005-03-01 07:07:46.000000000 +0100
@@ -21,13 +21,11 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <dlfcn.h>
 
 #include "dvd_reader.h"
 #include "dvd_input.h"
 
-/* For libdvdcss */
-typedef struct dvdcss_s *dvdcss_handle;
+#include "dvdcss.h"
 
 dvdcss_handle (*DVDcss_open)  (const char *);
 int           (*DVDcss_close) (dvdcss_handle);
@@ -36,6 +34,12 @@
 int           (*DVDcss_read)  (dvdcss_handle, void *, int, int);
 char *        (*DVDcss_error) (dvdcss_handle);
 
+dvd_input_t (*DVDinput_open)  (const char *);
+int         (*DVDinput_close) (dvd_input_t);
+int         (*DVDinput_seek)  (dvd_input_t, int, int);
+int         (*DVDinput_title) (dvd_input_t, int); 
+int         (*DVDinput_read)  (dvd_input_t, void *, int, int);
+char *      (*DVDinput_error) (dvd_input_t);
 
 /* The DVDinput handle, add stuff here for new input methods. */
 struct dvd_input_s {
@@ -55,7 +59,7 @@
   dvd_input_t dev;
   
   /* Allocate the handle structure */
-  dev = (dvd_input_t) malloc(sizeof(dvd_input_t));
+  dev = (dvd_input_t) malloc(sizeof(struct dvd_input_s));
   if(dev == NULL) {
     fprintf(stderr, "libdvdread: Could not allocate memory.\n");
     return NULL;
@@ -123,176 +127,26 @@
 
 
 
-
-
-
-/**
- * initialize and open a DVD device or file.
- */
-static dvd_input_t file_open(const char *target)
-{
-  dvd_input_t dev;
-  
-  /* Allocate the library structure */
-  dev = (dvd_input_t) malloc(sizeof(dvd_input_t));
-  if(dev == NULL) {
-    fprintf(stderr, "libdvdread: Could not allocate memory.\n");
-    return NULL;
-  }
-  
-  /* Open the device */
-  dev->fd = open(target, O_RDONLY);
-  if(dev->fd < 0) {
-    perror("libdvdread: Could not open input");
-    free(dev);
-    return NULL;
-  }
-  
-  return dev;
-}
-
-/**
- * return the last error message
- */
-static char *file_error(dvd_input_t dev)
-{
-  /* use strerror(errno)? */
-  return "unknown error";
-}
-
-/**
- * seek into the device.
- */
-static int file_seek(dvd_input_t dev, int blocks, int flags)
-{
-  off_t pos;
-
-  pos = lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET);
-  if(pos < 0) {
-      return pos;
-  }
-  /* assert pos % DVD_VIDEO_LB_LEN == 0 */
-  return (int) (pos / DVD_VIDEO_LB_LEN);
-}
-
-/**
- * set the block for the begining of a new title (key).
- */
-static int file_title(dvd_input_t dev, int block)
-{
-  return -1;
-}
-
-/**
- * read data from the device.
- */
-static int file_read(dvd_input_t dev, void *buffer, int blocks, int flags)
-{
-  size_t len;
-  ssize_t ret;
-  
-  len = (size_t)blocks * DVD_VIDEO_LB_LEN;
-  
-  while(len > 0) {
-    
-    ret = read(dev->fd, buffer, len);
-    
-    if(ret < 0) {
-      /* One of the reads failed, too bad.  We won't even bother
-       * returning the reads that went ok, and as in the posix spec
-       * the file postition is left unspecified after a failure. */
-      return ret;
-    }
-    
-    if(ret == 0) {
-      /* Nothing more to read.  Return the whole blocks, if any, that we got.
-	 and adjust the file possition back to the previous block boundary. */
-      size_t bytes = (size_t)blocks * DVD_VIDEO_LB_LEN - len;
-      off_t over_read = -(bytes % DVD_VIDEO_LB_LEN);
-      /*off_t pos =*/ lseek(dev->fd, over_read, SEEK_CUR);
-      /* should have pos % 2048 == 0 */
-      return (int) (bytes / DVD_VIDEO_LB_LEN);
-    }
-    
-    len -= ret;
-  }
-
-  return blocks;
-}
-
-/**
- * close the DVD device and clean up.
- */
-static int file_close(dvd_input_t dev)
-{
-  int ret;
-
-  ret = close(dev->fd);
-
-  if(ret < 0)
-    return ret;
-
-  free(dev);
-
-  return 0;
-}
-
-
 /**
  * Setup read functions with either libdvdcss or minimal DVD access.
  */
 int DVDInputSetup(void)
 {
-  void *dvdcss_library = NULL;
-  char **dvdcss_version = NULL;
-  
-  dvdcss_library = dlopen("libdvdcss.so.2", RTLD_LAZY);
-  
-  if(dvdcss_library != NULL) {
-#if defined(__OpenBSD__) && !defined(__ELF__)
-#define U_S "_"
-#else
-#define U_S
-#endif
-    DVDcss_open = (dvdcss_handle (*)(const char*))
-      dlsym(dvdcss_library, U_S "dvdcss_open");
-    DVDcss_close = (int (*)(dvdcss_handle))
-      dlsym(dvdcss_library, U_S "dvdcss_close");
-    DVDcss_title = (int (*)(dvdcss_handle, int))
-      dlsym(dvdcss_library, U_S "dvdcss_title");
-    DVDcss_seek = (int (*)(dvdcss_handle, int, int))
-      dlsym(dvdcss_library, U_S "dvdcss_seek");
-    DVDcss_read = (int (*)(dvdcss_handle, void*, int, int))
-      dlsym(dvdcss_library, U_S "dvdcss_read");
-    DVDcss_error = (char* (*)(dvdcss_handle))
-      dlsym(dvdcss_library, U_S "dvdcss_error");
+    DVDcss_open = dvdcss_open;
+    DVDcss_close = dvdcss_close;
+    DVDcss_title = dvdcss_title;
+    DVDcss_seek = dvdcss_seek;
+    DVDcss_read = dvdcss_read;
+    DVDcss_error = dvdcss_error;
     
-    dvdcss_version = (char **)dlsym(dvdcss_library, U_S "dvdcss_interface_2");
-
-    if(dlsym(dvdcss_library, U_S "dvdcss_crack")) {
-      fprintf(stderr, 
-	      "libdvdread: Old (pre-0.0.2) version of libdvdcss found.\n"
-	      "libdvdread: You should get the latest version from "
-	      "http://www.videolan.org/\n" );
-      dlclose(dvdcss_library);
-      dvdcss_library = NULL;
-    } else if(!DVDcss_open  || !DVDcss_close || !DVDcss_title || !DVDcss_seek
-	      || !DVDcss_read || !DVDcss_error || !dvdcss_version) {
-      fprintf(stderr,  "libdvdread: Missing symbols in libdvdcss.so.2, "
-	      "this shouldn't happen !\n");
-      dlclose(dvdcss_library);
-    }
-  }
-  
-  if(dvdcss_library != NULL) {
     /*
     char *psz_method = getenv( "DVDCSS_METHOD" );
     char *psz_verbose = getenv( "DVDCSS_VERBOSE" );
     fprintf(stderr, "DVDCSS_METHOD %s\n", psz_method);
     fprintf(stderr, "DVDCSS_VERBOSE %s\n", psz_verbose);
     */
-    fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD access\n",
-	    *dvdcss_version);
+//    fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD access\n",
+//	    *dvdcss_version);
     
     /* libdvdcss wraper functions */
     DVDinput_open  = css_open;
@@ -303,16 +157,4 @@
     DVDinput_error = css_error;
     return 1;
     
-  } else {
-    fprintf(stderr, "libdvdread: Encrypted DVD support unavailable.\n");
-
-    /* libdvdcss replacement functions */
-    DVDinput_open  = file_open;
-    DVDinput_close = file_close;
-    DVDinput_seek  = file_seek;
-    DVDinput_title = file_title;
-    DVDinput_read  = file_read;
-    DVDinput_error = file_error;
-    return 0;
-  }
 }
--- dvdread/dvd_input.h	2002-05-09 23:21:20.000000000 +0200
+++ dvd_input.h	2005-03-01 07:07:46.000000000 +0100
@@ -36,12 +36,12 @@
 /**
  * Pointers which will be filled either the input meathods functions.
  */
-dvd_input_t (*DVDinput_open)  (const char *);
-int         (*DVDinput_close) (dvd_input_t);
-int         (*DVDinput_seek)  (dvd_input_t, int, int);
-int         (*DVDinput_title) (dvd_input_t, int); 
-int         (*DVDinput_read)  (dvd_input_t, void *, int, int);
-char *      (*DVDinput_error) (dvd_input_t);
+extern dvd_input_t (*DVDinput_open)  (const char *);
+extern int         (*DVDinput_close) (dvd_input_t);
+extern int         (*DVDinput_seek)  (dvd_input_t, int, int);
+extern int         (*DVDinput_title) (dvd_input_t, int); 
+extern int         (*DVDinput_read)  (dvd_input_t, void *, int, int);
+extern char *      (*DVDinput_error) (dvd_input_t);
 
 /**
  * Setup function accessed by dvd_reader.c.  Returns 1 if there is CSS support.
--- dvdread/dvd_reader.c	2002-05-19 17:48:41.000000000 +0200
+++ dvd_reader.c	2005-03-01 07:07:46.000000000 +0100
@@ -17,6 +17,8 @@
  * 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. */
@@ -35,12 +37,24 @@
 
 #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__)
 #include <mntent.h>
 #endif
 
+#ifdef __MINGW32__
+#include <sys/timeb.h>
+static void gettimeofday(struct timeval* t,void* timezone){
+    struct timeb timebuffer;
+    ftime( &timebuffer );
+    t->tv_sec=timebuffer.time;
+    t->tv_usec=1000*timebuffer.millitm;
+}
+#endif
+
 #include "dvd_udf.h"
 #include "dvd_input.h"
 #include "dvd_reader.h"
@@ -144,6 +158,13 @@
 }
 
 
+#ifndef HAVE_MPLAYER
+ #include "get_path.c"
+#else
+ extern char * get_path( char * filename );
+#endif
+
+//extern char * dvdcss_cache_dir;
 
 /**
  * Open a DVD image or block device file.
@@ -152,7 +173,17 @@
 {
     dvd_reader_t *dvd;
     dvd_input_t dev;
+
+    /* setup cache dir is no longer needed, it's now implemented in libdvdcss.c
+    if(!dvdcss_cache_dir){
+	dvdcss_cache_dir=get_path( "" );
+	if ( dvdcss_cache_dir ) { mkdir( dvdcss_cache_dir,493 ); free( dvdcss_cache_dir ); }
+	dvdcss_cache_dir=get_path( "DVDKeys" );
+	if(dvdcss_cache_dir) mkdir( dvdcss_cache_dir,493 );
+    }
+    */
     
+    /* open it */
     dev = DVDinput_open( location );
     if( !dev ) {
 	fprintf( stderr, "libdvdread: Can't open %s for reading\n", location );
@@ -222,7 +253,7 @@
     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 ) ) 
+    if( strncmp( path, "/dev/",  5 ) || !strncmp( path, "/dev/r", 6 ) ) 
       return (char *) strdup( path );
 
     /* Replace "/dev/" with "/dev/r" */
@@ -242,6 +273,16 @@
 
     if( !path ) return 0;
 
+#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 ) {
 	/* If we can't stat the file, give up */
@@ -249,6 +290,7 @@
 	perror("");
 	return 0;
     }
+    }
 
     /* Try to open libdvdcss or fall back to standard functions */
     have_css = DVDInputSetup();
@@ -289,7 +331,9 @@
 	    if( cdir >= 0 ) {
 		chdir( path_copy );
 		new_path = getcwd( NULL, PATH_MAX );
+#ifndef __MINGW32__       
 		fchdir( cdir );
+#endif       
 		close( cdir );
 		if( new_path ) {
 		    free( path_copy );
@@ -364,6 +408,9 @@
             }
             fclose( mntfile );
 	}
+#elif defined(WIN32)	
+	dev_name = strdup(path);
+	auth_drive = DVDOpenImageFile( path, have_css );
 #endif
 	if( !dev_name ) {
 	  fprintf( stderr, "libdvdread: Couldn't find device name.\n" );
@@ -554,8 +601,8 @@
     }
     
     if( dvd->css_state == 1 /* Need key init */ ) {
-        initAllCSSKeys( dvd );
-	dvd->css_state = 2;
+//        initAllCSSKeys( dvd );
+//	dvd->css_state = 2;
     }
     /*    
     if( DVDinput_seek( dvd_file->dvd->dev, 
@@ -631,10 +678,9 @@
             dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
             dvd_file->title_devs[ i ] = DVDinput_open( full_path );
             dvd_file->filesize += dvd_file->title_sizes[ i ];
+            DVDinput_seek( dvd_file->title_devs[ i ], 0, DVDINPUT_SEEK_KEY );
         }
-        if( dvd_file->title_devs[ 0 ] ) {
-	    DVDinput_seek( dvd_file->title_devs[ 0 ], 0, DVDINPUT_SEEK_KEY );
-	} else {
+        if( !dvd_file->title_devs[ 0 ] ) {
             free( dvd_file );
             return 0;
         }
@@ -794,7 +840,10 @@
 		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. */
-		
+
+                /* Does the next part exist? If not then return now. */
+                if( !dvd_file->title_devs[ i + 1 ] ) return ret;
+
                 /* Read part 2 */
                 off = DVDinput_seek( dvd_file->title_devs[ i + 1 ], 
 				     0, DVDINPUT_NOFLAGS );
@@ -846,7 +895,7 @@
     return (ssize_t)ret;
 }
 
-int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset )
+int DVDFileSeek( dvd_file_t *dvd_file, int offset )
 {
    if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) {
        return -1;
--- dvdread/dvd_udf.c	2002-05-06 22:16:31.000000000 +0200
+++ dvd_udf.c	2005-03-01 07:07:46.000000000 +0100
@@ -4,6 +4,9 @@
  *
  * Modifications by:
  *   Billy Biggs <vektor@dumbterm.net>.
+ *   Björn Englund <d4bjorn@dtek.chalmers.se>.
+ *   Joey Parrish <joey@nicewarrior.org>.
+ *     - updated from libdvdread 0.9.4 and removed udf caching
  *
  * dvdudf: parse and read the UDF volume information of a DVD Video
  * Copyright (C) 1999 Christian Wolff for convergence integrated media
@@ -30,8 +33,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
+//#include <assert.h>
+#ifndef __MINGW32__
 #include <sys/ioctl.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -93,6 +98,32 @@
     uint16_t Partition;
 };
 
+struct extent_ad {
+  uint32_t location;
+  uint32_t length;
+};
+
+struct avdp_t {
+  struct extent_ad mvds;
+  struct extent_ad rvds;
+};
+
+struct pvd_t {
+  uint8_t VolumeIdentifier[32];
+  uint8_t VolumeSetIdentifier[128];
+};
+
+struct lbudf {
+  uint32_t lb;
+  uint8_t *data;
+};
+
+struct icbmap {
+  uint32_t lbn;
+  struct AD file;
+  uint8_t filetype;
+};
+
 /* For direct data access, LSB first */
 #define GETN1(p) ((uint8_t)data[p])
 #define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8))
@@ -334,6 +365,67 @@
     return 0;
 }
 
+
+static int UDFGetAVDP( dvd_reader_t *device,
+		       struct avdp_t *avdp)
+{
+  uint8_t Anchor[ DVD_VIDEO_LB_LEN ];
+  uint32_t lbnum, MVDS_location, MVDS_length;
+  uint16_t TagID;
+  uint32_t lastsector;
+  int terminate;
+  struct avdp_t; 
+  
+  /* Find Anchor */
+  lastsector = 0;
+  lbnum = 256;   /* Try #1, prime anchor */
+  terminate = 0;
+  
+  for(;;) {
+    if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) {
+      UDFDescriptor( Anchor, &TagID );
+    } else {
+      TagID = 0;
+    }
+    if (TagID != 2) {
+      /* Not an anchor */
+      if( terminate ) return 0; /* Final try failed */
+      
+      if( lastsector ) {
+	
+	/* We already found the last sector.  Try #3, alternative
+	 * backup anchor.  If that fails, don't try again.
+	 */
+	lbnum = lastsector;
+	terminate = 1;
+      } else {
+	/* TODO: Find last sector of the disc (this is optional). */
+	if( lastsector ) {
+	  /* Try #2, backup anchor */
+	  lbnum = lastsector - 256;
+	} else {
+	  /* Unable to find last sector */
+	  return 0;
+	}
+      }
+    } else {
+      /* It's an anchor! We can leave */
+      break;
+    }
+  }
+  /* Main volume descriptor */
+  UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
+  avdp->mvds.location = MVDS_location;
+  avdp->mvds.length = MVDS_length;
+  
+  /* Backup volume descriptor */
+  UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );
+  avdp->rvds.location = MVDS_location;
+  avdp->rvds.length = MVDS_length;
+  
+  return 1;
+}
+
 /**
  * Looks for partition on the disc.  Returns 1 if partition found, 0 on error.
  *   partnum: Number of the partition, starting at 0.
@@ -342,52 +434,21 @@
 static int UDFFindPartition( dvd_reader_t *device, int partnum,
 			     struct Partition *part ) 
 {
-    uint8_t LogBlock[ DVD_VIDEO_LB_LEN ], Anchor[ DVD_VIDEO_LB_LEN ];
+    uint8_t LogBlock[ DVD_VIDEO_LB_LEN ];
     uint32_t lbnum, MVDS_location, MVDS_length;
     uint16_t TagID;
-    uint32_t lastsector;
-    int i, terminate, volvalid;
+    int i, volvalid;
+    struct avdp_t avdp;
 
-    /* Find Anchor */
-    lastsector = 0;
-    lbnum = 256;   /* Try #1, prime anchor */
-    terminate = 0;
-
-    for(;;) {
-        if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) {
-            UDFDescriptor( Anchor, &TagID );
-        } else {
-            TagID = 0;
-        }
-        if (TagID != 2) {
-            /* Not an anchor */
-            if( terminate ) return 0; /* Final try failed */
-
-            if( lastsector ) {
-
-                /* We already found the last sector.  Try #3, alternative
-                 * backup anchor.  If that fails, don't try again.
-                 */
-                lbnum = lastsector;
-                terminate = 1;
-            } else {
-                /* TODO: Find last sector of the disc (this is optional). */
-                if( lastsector ) {
-                    /* Try #2, backup anchor */
-                    lbnum = lastsector - 256;
-                } else {
-                    /* Unable to find last sector */
-                    return 0;
-                }
-            }
-        } else {
-            /* It's an anchor! We can leave */
-            break;
-        }
+    
+    if(!UDFGetAVDP(device, &avdp)) {
+      return 0;
     }
+
     /* Main volume descriptor */
-    UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
-	
+    MVDS_location = avdp.mvds.location;
+    MVDS_length = avdp.mvds.length;
+
     part->valid = 0;
     volvalid = 0;
     part->VolumeDesc[ 0 ] = '\0';
@@ -422,8 +483,9 @@
                  && ( ( !part->valid ) || ( !volvalid ) ) );
 
         if( ( !part->valid) || ( !volvalid ) ) {
-            /* Backup volume descriptor */
-            UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );
+	  /* Backup volume descriptor */
+	  MVDS_location = avdp.mvds.location;
+	  MVDS_length = avdp.mvds.length;
         }
     } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) );
 
@@ -442,17 +504,18 @@
     char tokenline[ MAX_UDF_FILE_NAME_LEN ];
     char *token;
     uint8_t filetype;
-	
+
     *filesize = 0;
     tokenline[0] = '\0';
     strcat( tokenline, filename );
 
-    /* Find partition, 0 is the standard location for DVD Video.*/
-    if( !UDFFindPartition( device, 0, &partition ) ) return 0;
-
-    /* Find root dir ICB */
-    lbnum = partition.Start;
-    do {
+    
+      /* Find partition, 0 is the standard location for DVD Video.*/
+      if( !UDFFindPartition( device, 0, &partition ) ) return 0;
+      
+      /* Find root dir ICB */
+      lbnum = partition.Start;
+      do {
         if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
             TagID = 0;
         } else {
@@ -469,19 +532,27 @@
     /* Sanity checks. */
     if( TagID != 256 ) return 0;
     if( RootICB.Partition != 0 ) return 0;
-	
+
     /* Find root dir */
     if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) return 0;
     if( filetype != 4 ) return 0;  /* Root dir should be dir */
 
-    /* Tokenize filepath */
-    token = strtok(tokenline, "/");
-    while( token != NULL ) {
-        if( !UDFScanDir( device, File, token, &partition, &ICB ) ) return 0;
-        if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) return 0;
+    {
+      /* Tokenize filepath */
+      token = strtok(tokenline, "/");
+      
+      while( token != NULL ) {
+       
+        if( !UDFScanDir( device, File, token, &partition, &ICB)) {
+         return 0;
+       }
+        if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {
+         return 0;
+       }
         token = strtok( NULL, "/" );
-    }
-    
+      }
+    } 
+
     /* Sanity check. */
     if( File.Partition != 0 ) return 0;
    
@@ -492,3 +563,81 @@
     else
       return partition.Start + File.Location;
 }
+
+
+
+/**
+ * Gets a Descriptor .
+ * Returns 1 if descriptor found, 0 on error.
+ * id, tagid of descriptor
+ * bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN).
+ */
+static int UDFGetDescriptor( dvd_reader_t *device, int id,
+			     uint8_t *descriptor, int bufsize) 
+{
+  uint32_t lbnum, MVDS_location, MVDS_length;
+  struct avdp_t avdp;
+  uint16_t TagID;
+  uint32_t lastsector;
+  int i, terminate;
+  int desc_found = 0;
+  /* Find Anchor */
+  lastsector = 0;
+  lbnum = 256;   /* Try #1, prime anchor */
+  terminate = 0;
+  if(bufsize < DVD_VIDEO_LB_LEN) {
+    return 0;
+  }
+  
+  if(!UDFGetAVDP(device, &avdp)) {
+    return 0;
+  }
+
+  /* Main volume descriptor */
+  MVDS_location = avdp.mvds.location;
+  MVDS_length = avdp.mvds.length;
+  
+  i = 1;
+  do {
+    /* Find  Descriptor */
+    lbnum = MVDS_location;
+    do {
+      
+      if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) {
+	TagID = 0;
+      } else {
+	UDFDescriptor( descriptor, &TagID );
+      }
+      
+      if( (TagID == id) && ( !desc_found ) ) {
+	/* Descriptor */
+	desc_found = 1;
+      }
+    } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )
+	       / DVD_VIDEO_LB_LEN ) && ( TagID != 8 )
+	     && ( !desc_found) );
+    
+    if( !desc_found ) {
+      /* Backup volume descriptor */
+      MVDS_location = avdp.rvds.location;
+      MVDS_length = avdp.rvds.length;
+    }
+  } while( i-- && ( !desc_found )  );
+  
+  return desc_found;
+}
+
+
+static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd)
+{
+  uint8_t pvd_buf[DVD_VIDEO_LB_LEN];
+  
+  if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf))) {
+    return 0;
+  }
+  
+  memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);
+  memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128);
+  
+  return 1;
+}
--- dvdread/ifo_print.c	2002-05-15 21:35:54.000000000 +0200
+++ ifo_print.c	2005-03-01 07:07:46.000000000 +0100
@@ -23,7 +23,7 @@
 #include <inttypes.h>
 #include <string.h>
 #include <ctype.h>
-#include <assert.h>
+//#include <assert.h>
 
 #include "config.h" // Needed for WORDS_BIGENDIAN
 #include "ifo_types.h"
--- dvdread/ifo_print.h	2002-04-07 19:52:01.000000000 +0200
+++ ifo_print.h	2005-03-01 07:07:46.000000000 +0100
@@ -20,8 +20,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <dvdread/ifo_types.h>
-#include <dvdread/dvd_reader.h>
+#include "ifo_types.h"
+#include "dvd_reader.h"
 
 #ifdef __cplusplus
 extern "C" {
--- dvdread/ifo_read.c	2002-05-25 21:37:18.000000000 +0200
+++ ifo_read.c	2005-03-01 07:07:46.000000000 +0100
@@ -22,7 +22,7 @@
 #include <unistd.h>
 #include <inttypes.h>
 #include <string.h>
-#include <assert.h>
+//#include <assert.h>
 
 #include "dvd_reader.h"
 
--- dvdread/ifo_read.h	2002-04-07 19:52:01.000000000 +0200
+++ ifo_read.h	2005-03-01 07:07:46.000000000 +0100
@@ -20,8 +20,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <dvdread/ifo_types.h>
-#include <dvdread/dvd_reader.h>
+#include "ifo_types.h"
+#include "dvd_reader.h"
 
 #ifdef __cplusplus
 extern "C" {
--- dvdread/ifo_types.h	2002-04-07 19:52:01.000000000 +0200
+++ ifo_types.h	2005-03-01 07:07:46.000000000 +0100
@@ -21,7 +21,7 @@
  */
 
 #include <inttypes.h>
-#include <dvdread/dvd_reader.h>
+#include "dvd_reader.h"
 
 
 #undef ATTRIBUTE_PACKED
--- dvdread/nav_print.c	2002-04-07 19:18:06.000000000 +0200
+++ nav_print.c	2005-03-01 07:07:46.000000000 +0100
@@ -25,7 +25,7 @@
 
 #include <stdio.h>
 #include <inttypes.h>
-#include <assert.h>
+//#include <assert.h>
 
 #include "config.h" // Needed for WORDS_BIGENDIAN
 #include "nav_types.h"
--- dvdread/nav_print.h	2002-04-07 20:17:19.000000000 +0200
+++ nav_print.h	2005-03-01 07:07:46.000000000 +0100
@@ -20,7 +20,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <dvdread/nav_types.h>
+#include "nav_types.h"
 
 #ifdef __cplusplus
 extern "C" {
--- dvdread/nav_read.c	2002-04-07 19:52:01.000000000 +0200
+++ nav_read.c	2005-03-01 07:07:46.000000000 +0100
@@ -19,7 +19,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <inttypes.h>
-#include <assert.h>
+//#include <assert.h>
 
 #include "config.h" // Needed for WORDS_BIGENDIAN
 #include "bswap.h"
@@ -95,7 +95,9 @@
   /* pci hli btnit */
   for(i = 0; i < pci->hli.hl_gi.btngr_ns; i++) {
     for(j = 0; j < (36 / pci->hli.hl_gi.btngr_ns); j++) {
+#ifdef HAVE_ASSERT_H
       int n = (36 / pci->hli.hl_gi.btngr_ns) * i + j;
+#endif
       assert(pci->hli.btnit[n].zero1 == 0);
       assert(pci->hli.btnit[n].zero2 == 0);
       assert(pci->hli.btnit[n].zero3 == 0);
--- dvdread/nav_read.h	2002-04-07 20:17:19.000000000 +0200
+++ nav_read.h	2005-03-01 07:07:46.000000000 +0100
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <dvdread/nav_types.h>
+#include "nav_types.h"
 
 #ifdef __cplusplus
 extern "C" {
--- dvdread/nav_types.h	2002-04-07 20:41:59.000000000 +0200
+++ nav_types.h	2005-03-01 07:07:46.000000000 +0100
@@ -30,7 +30,7 @@
  */
 
 #include <inttypes.h>
-#include <dvdread/ifo_types.h> // only dvd_time_t, vm_cmd_t and user_ops_t
+#include "ifo_types.h" // only dvd_time_t, vm_cmd_t and user_ops_t
 
 
 #undef ATTRIBUTE_PACKED