Index: mythtv/libs/libmythdvdnav/dvdnav/vm/vm.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdnav/vm/vm.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdnav/vm/vm.c	(working copy)
@@ -54,6 +54,8 @@
 #ifdef __OS2__
 #define INCL_DOS
 #include <os2.h>
+#include <io.h>     /* setmode() */
+#include <fcntl.h>  /* O_BINARY  */
 #endif
 
 /*
@@ -144,15 +146,17 @@
     ULONG ulAction;
     ULONG rc;
 
-    rc = DosOpen( name, &hfile, &ulAction, 0, FILE_NORMAL,
+    rc = DosOpenL(name, &hfile, &ulAction, 0, FILE_NORMAL,
                   OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
                   OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE | OPEN_FLAGS_DASD,
-                  NULL );
+                  NULL);
 
-    if( rc )
+    if(rc)
         return -1;
 
-    return ( int )hfile;
+    setmode(hfile, O_BINARY);
+
+    return (int)hfile;
 }
 #endif
 
@@ -354,8 +358,6 @@
       fprintf(MSG_OUT, "libdvdnav: vm: failed to open/read the DVD\n");
       return 0;
     }
-    dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot);
-    vm->map  = remap_loadmap(vm->dvd_name);
     vm->vmgi = ifoOpenVMGI(vm->dvd);
     if(!vm->vmgi) {
       fprintf(MSG_OUT, "libdvdnav: vm: failed to read VIDEO_TS.IFO\n");
@@ -386,6 +388,8 @@
       /* return 0; Not really used for now.. */
     }
     /* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */
+    dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot);
+    vm->map  = remap_loadmap(vm->dvd_name);
   }
   if (vm->vmgi) {
     int i, mask;
@@ -861,8 +865,8 @@
     break;
   }
 }
+#endif
 
-/* currently unused */
 void vm_get_subp_info(vm_t *vm, int *current, int *num_avail) {
   switch ((vm->state).domain) {
   case VTS_DOMAIN:
@@ -905,7 +909,6 @@
     break;
   }
 }
-#endif
 
 int vm_get_video_aspect(vm_t *vm) {
   int aspect = vm_get_video_attr(vm).display_aspect_ratio;
@@ -1717,6 +1720,7 @@
 /* Figure out the correct pgN from the cell and update (vm->state). */
 static int set_PGN(vm_t *vm) {
   int new_pgN = 0;
+  int dummy, part;
 
   while(new_pgN < (vm->state).pgc->nr_of_programs
 	&& (vm->state).cellN >= (vm->state).pgc->program_map[new_pgN])
@@ -1733,15 +1737,8 @@
     if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
       return 0; /* ?? */
     pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;
-    if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) {
-      int dummy, part;
       vm_get_current_title_part(vm, &dummy, &part);
       (vm->state).PTTN_REG = part;
-    } else {
-      /* FIXME: Handle RANDOM or SHUFFLE titles.
-      fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n");
-      */
-    }
   }
   return 1;
 }
Index: mythtv/libs/libmythdvdnav/dvdnav/vm/vm.h
===================================================================
--- mythtv/libs/libmythdvdnav/dvdnav/vm/vm.h	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdnav/vm/vm.h	(working copy)
@@ -160,8 +160,8 @@
 /* currently unused */
 void vm_get_audio_info(vm_t *vm, int *current, int *num_avail);
 void vm_get_subp_info(vm_t *vm, int *current, int *num_avail);
+#endif
 void vm_get_video_res(vm_t *vm, int *width, int *height);
-#endif
 int  vm_get_video_aspect(vm_t *vm);
 int  vm_get_video_scale_permission(vm_t *vm);
 int  vm_get_video_format(vm_t *vm);
Index: mythtv/libs/libmythdvdnav/dvdnav/dvdnav.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdnav/dvdnav.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdnav/dvdnav.c	(working copy)
@@ -845,6 +845,23 @@
   return retval;
 }
 
+int dvdnav_get_video_resolution(dvdnav_t *this, uint32_t *width, uint32_t *height) {
+  int w, h;
+
+  if(!this->started) {
+    printerr("Virtual DVD machine not started.");
+    return -1;
+  }
+
+  pthread_mutex_lock(&this->vm_lock);
+  vm_get_video_res(this->vm, &w, &h);
+  pthread_mutex_unlock(&this->vm_lock);
+
+  *width  = w;
+  *height = h;
+  return 0;
+}
+
 uint8_t dvdnav_get_video_scale_permission(dvdnav_t *this) {
   uint8_t         retval;
 
Index: mythtv/libs/libmythdvdnav/dvdnav/dvdnav_internal.h
===================================================================
--- mythtv/libs/libmythdvdnav/dvdnav/dvdnav_internal.h	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdnav/dvdnav_internal.h	(working copy)
@@ -34,7 +34,7 @@
 #define pthread_mutex_init(a, b) InitializeCriticalSection(a)
 #define pthread_mutex_lock(a)    EnterCriticalSection(a)
 #define pthread_mutex_unlock(a)  LeaveCriticalSection(a)
-#define pthread_mutex_destroy(a)
+#define pthread_mutex_destroy(a) DeleteCriticalSection(a)
 
 #if HAVE_GETTIMEOFDAY == 0
 /* replacement gettimeofday implementation */
@@ -60,7 +60,7 @@
 #endif /* WIN32 */
 
 /* where should libdvdnav write its messages (stdout/stderr) */
-#define MSG_OUT stdout
+#define MSG_OUT stderr
 
 /* Maximum length of an error string */
 #define MAX_ERR_LEN 255
Index: mythtv/libs/libmythdvdnav/dvdnav/dvdnav.h
===================================================================
--- mythtv/libs/libmythdvdnav/dvdnav/dvdnav.h	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdnav/dvdnav.h	(working copy)
@@ -561,6 +561,11 @@
 uint8_t dvdnav_get_video_aspect(dvdnav_t *self);
 
 /*
+ * Get video resolution.
+ */
+int dvdnav_get_video_resolution(dvdnav_t *self, uint32_t *width, uint32_t *height);
+
+/*
  * Get video scaling permissions.
  * The scaling permission does only change on VTS boundaries.
  * See the DVDNAV_VTS_CHANGE event.
Index: mythtv/libs/libmythdvdnav/dvdread/dvd_reader.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/dvd_reader.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/dvd_reader.c	(working copy)
@@ -20,8 +20,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "config.h"
-
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h> /* For the timing of dvdcss_title crack. */
@@ -30,6 +28,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <ctype.h>
 #include <unistd.h>
 #include <limits.h>
 #include <dirent.h>
@@ -53,7 +52,7 @@
 #define lseek64 _lseeki64
 #endif
 
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__DARWIN__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
 #define SYS_BSD 1
 #endif
 
@@ -249,7 +248,7 @@
 
   if( have_css ) {
     /* Only if DVDCSS_METHOD = title, a bit if it's disc or if
-     * DVDCSS_METHOD = key but region missmatch. Unfortunaly we
+     * DVDCSS_METHOD = key but region mismatch. Unfortunately we
      * don't have that information. */
 
     dvd->css_state = 1; /* Need key init. */
@@ -304,13 +303,19 @@
 #endif
 
 #if defined(SYS_BSD)
-/* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recomended to _not_ use r
+/* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recommended 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) */
+   BSD/OS  /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do)
+   returns a string allocated with strdup. It should be freed 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 */
@@ -323,6 +328,7 @@
   strcat( new_path, path + strlen( "/dev/" ) );
 
   return new_path;
+#endif /* __FreeBSD__ || __DragonFly__ */
 }
 #endif
 
@@ -330,26 +336,26 @@
 dvd_reader_t *DVDOpen( const char *ppath )
 {
   struct stat fileinfo;
-  int ret, have_css;
+  int ret, have_css, retval, cdir = -1;
   dvd_reader_t *ret_val = NULL;
   char *dev_name = NULL;
-  char *path;
+  char *path = NULL, *new_path = NULL, *path_copy = NULL;
 
-#ifdef _MSC_VER
+#if defined(_WIN32) || defined(__OS2__)
       int len;
 #endif
 
   if( ppath == NULL )
-    return 0;
+    goto DVDOpen_error;
 
       path = strdup(ppath);
   if( path == NULL )
-    return 0;
+    goto DVDOpen_error;
 
   /* Try to open libdvdcss or fall back to standard functions */
   have_css = dvdinput_setup();
 
-#ifdef _MSC_VER
+#if defined(_WIN32) || defined(__OS2__)
   /* Strip off the trailing \ if it is not a drive */
   len = strlen(path);
   if ((len > 1) &&
@@ -374,8 +380,7 @@
     /* If we can't stat the file, give up */
     fprintf( stderr, "libdvdread: Can't stat %s\n", path );
     perror("");
-    free(path);
-    return NULL;
+    goto DVDOpen_error;
   }
 
   /* First check if this is a block/char device or a file*/
@@ -386,20 +391,20 @@
     /**
      * Block devices and regular files are assumed to be DVD-Video images.
      */
+    dvd_reader_t *dvd = NULL;
 #if defined(__sun)
-    ret_val = DVDOpenImageFile( sun_block2char( path ), have_css );
+    dev_name = sun_block2char( path );
 #elif defined(SYS_BSD)
-    ret_val = DVDOpenImageFile( bsd_block2char( path ), have_css );
+    dev_name = bsd_block2char( path );
 #else
-    ret_val = DVDOpenImageFile( path, have_css );
+    dev_name = strdup( path );
 #endif
-
+    dvd = DVDOpenImageFile( dev_name, have_css );
+    free( dev_name );
     free(path);
-    return ret_val;
-
+    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__)
@@ -407,38 +412,40 @@
 #endif
 
     /* XXX: We should scream real loud here. */
-    if( !(path_copy = strdup( path ) ) ) {
-      free(path);
-      return NULL;
-    }
+    if( !(path_copy = strdup( path ) ) )
+      goto DVDOpen_error;
 
 #ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange */
               /* Also WIN32 does not have symlinks, so we don't need this bit of code. */
 
-    /* Resolve any symlinks and get the absolut dir name. */
+    /* Resolve any symlinks and get the absolute dir name. */
     {
-      char *new_path;
-      int cdir = open( ".", O_RDONLY );
-
-      if( cdir >= 0 ) {
-        chdir( path_copy );
+      if( ( cdir  = open( ".", O_RDONLY ) ) >= 0 ) {
+        if( chdir( path_copy ) == -1 ) {
+          goto DVDOpen_error;
+        }
         new_path = malloc(PATH_MAX+1);
         if(!new_path) {
-          free(path);
-          return NULL;
+          goto DVDOpen_error;
         }
-        getcwd(new_path, PATH_MAX );
-        fchdir( cdir );
+        if( getcwd( new_path, PATH_MAX ) == NULL ) {
+          goto DVDOpen_error;
+        }
+        retval = fchdir( cdir );
         close( cdir );
-          free( path_copy );
-          path_copy = new_path;
+        cdir = -1;
+        if( retval == -1 ) {
+          goto DVDOpen_error;
+        }
+        path_copy = new_path;
+        new_path = NULL;
       }
     }
 #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.
+     * is the mount point for a DVD-ROM which we can use instead.
      */
 
     if( strlen( path_copy ) > 1 ) {
@@ -447,6 +454,13 @@
       }
     }
 
+#if defined(_WIN32) || defined(__OS2__)
+    if(strlen(path_copy) > TITLES_MAX) {
+      if(!strcasecmp(&(path_copy[strlen( path_copy ) - TITLES_MAX]),
+                       "\\video_ts"))
+        path_copy[strlen(path_copy) - (TITLES_MAX-1)] = '\0';
+    }
+#endif
     if( strlen( path_copy ) > TITLES_MAX ) {
       if( !strcasecmp( &(path_copy[ strlen( path_copy ) - TITLES_MAX ]),
                        "/video_ts" ) ) {
@@ -508,11 +522,17 @@
       }
       fclose( mntfile );
     }
-#elif defined(_MSC_VER) || defined(__OS2__)
+#elif defined(_WIN32) || defined(__OS2__)
+#ifdef __OS2__
+    /* Use DVDOpenImageFile() only if it is a drive */
+    if(isalpha(path[0]) && path[1] == ':' &&
+        ( !path[2] ||
+          ((path[2] == '\\' || path[2] == '/') && !path[3])))
+#endif
     auth_drive = DVDOpenImageFile( path, have_css );
 #endif
 
-#if !defined(_MSC_VER) && !defined(__OS2__)
+#if !defined(_WIN32) && !defined(__OS2__)
     if( !dev_name ) {
       fprintf( stderr, "libdvdread: Couldn't find device name.\n" );
     } else if( !auth_drive ) {
@@ -522,12 +542,14 @@
 #else
     if( !auth_drive ) {
         fprintf( stderr, "libdvdread: Device %s inaccessible, "
-                 "CSS authentication not available.\n", dev_name );
+                 "CSS authentication not available.\n", path );
     }
 #endif
 
     free( dev_name );
+    dev_name = NULL;
     free( path_copy );
+    path_copy = NULL;
 
     /**
      * If we've opened a drive, just use that.
@@ -544,9 +566,17 @@
       return ret_val;
   }
 
+DVDOpen_error:
   /* If it's none of the above, screw it. */
   fprintf( stderr, "libdvdread: Could not open %s\n", path );
+  if( path != NULL )
     free( path );
+  if ( path_copy != NULL )
+    free( path_copy );
+  if ( cdir >= 0 )
+    close( cdir );
+  if ( new_path != NULL )
+    free( new_path );
   return NULL;
 }
 
@@ -875,9 +905,7 @@
   int i;
 
   if( dvd_file ) {
-    if( dvd_file->dvd->isImageFile ) {
-      ;
-    } else {
+    if( !dvd_file->dvd->isImageFile ) {
       for( i = 0; i < TITLES_MAX; ++i ) {
         if( dvd_file->title_devs[ i ] ) {
           dvdinput_close( dvd_file->title_devs[i] );
@@ -890,6 +918,180 @@
   }
 }
 
+static int DVDFileStatVOBUDF( dvd_reader_t *dvd, int title,
+                              int menu, dvd_stat_t *statbuf )
+{
+  char filename[ MAX_UDF_FILE_NAME_LEN ];
+  uint32_t size;
+  off_t tot_size;
+  off_t parts_size[ 9 ];
+  int nr_parts = 0;
+  int n;
+
+  if( title == 0 )
+    sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
+  else
+    sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
+
+  if( !UDFFindFile( dvd, filename, &size ) )
+    return -1;
+
+  tot_size = size;
+  nr_parts = 1;
+  parts_size[ 0 ] = size;
+
+  if( !menu ) {
+    int cur;
+
+    for( cur = 2; cur < 10; cur++ ) {
+      sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
+      if( !UDFFindFile( dvd, filename, &size ) )
+        break;
+
+      parts_size[ nr_parts ] = size;
+      tot_size += size;
+      nr_parts++;
+    }
+  }
+
+  statbuf->size = tot_size;
+  statbuf->nr_parts = nr_parts;
+  for( n = 0; n < nr_parts; n++ )
+    statbuf->parts_size[ n ] = parts_size[ n ];
+
+  return 0;
+}
+
+
+static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title,
+                               int menu, dvd_stat_t *statbuf )
+{
+  char filename[ MAX_UDF_FILE_NAME_LEN ];
+  char full_path[ PATH_MAX + 1 ];
+  struct stat fileinfo;
+  off_t tot_size;
+  off_t parts_size[ 9 ];
+  int nr_parts = 0;
+  int n;
+
+  if( title == 0 )
+    sprintf( filename, "VIDEO_TS.VOB" );
+  else
+    sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
+
+  if( !findDVDFile( dvd, filename, full_path ) )
+    return -1;
+
+  if( stat( full_path, &fileinfo ) < 0 ) {
+    fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+    return -1;
+  }
+
+  tot_size = fileinfo.st_size;
+  nr_parts = 1;
+  parts_size[ 0 ] = fileinfo.st_size;
+
+  if( !menu ) {
+    int cur;
+    for( cur = 2; cur < 10; cur++ ) {
+      sprintf( filename, "VTS_%02d_%d.VOB", title, cur );
+      if( !findDVDFile( dvd, filename, full_path ) )
+        break;
+
+      if( stat( full_path, &fileinfo ) < 0 ) {
+        fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+        break;
+      }
+
+      parts_size[ nr_parts ] = fileinfo.st_size;
+      tot_size += parts_size[ nr_parts ];
+      nr_parts++;
+    }
+  }
+
+  statbuf->size = tot_size;
+  statbuf->nr_parts = nr_parts;
+  for( n = 0; n < nr_parts; n++ )
+    statbuf->parts_size[ n ] = parts_size[ n ];
+
+  return 0;
+}
+
+
+int DVDFileStat( dvd_reader_t *dvd, int titlenum,
+                 dvd_read_domain_t domain, dvd_stat_t *statbuf )
+{
+  char filename[ MAX_UDF_FILE_NAME_LEN ];
+  char full_path[ PATH_MAX + 1 ];
+  struct stat fileinfo;
+  uint32_t size;
+
+  /* Check arguments. */
+  if( dvd == NULL || titlenum < 0 ) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  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:
+    if( dvd->isImageFile )
+      return DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf );
+    else
+      return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf );
+
+    break;
+  case DVD_READ_TITLE_VOBS:
+    if( titlenum == 0 )
+      return -1;
+
+    if( dvd->isImageFile )
+      return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf );
+    else
+      return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf );
+
+    break;
+  default:
+    fprintf( stderr, "libdvdread: Invalid domain for file stat.\n" );
+    errno = EINVAL;
+    return -1;
+  }
+
+  if( dvd->isImageFile ) {
+    if( UDFFindFile( dvd, filename, &size ) ) {
+      statbuf->size = size;
+      statbuf->nr_parts = 1;
+      statbuf->parts_size[ 0 ] = size;
+      return 0;
+    }
+  } else {
+    if( findDVDFile( dvd, filename, full_path ) ) {
+      if( stat( full_path, &fileinfo ) < 0 )
+        fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+      else {
+        statbuf->size = fileinfo.st_size;
+        statbuf->nr_parts = 1;
+        statbuf->parts_size[ 0 ] = statbuf->size;
+        return 0;
+      }
+    }
+  }
+  return -1;
+}
+
 /* Internal, but used from dvd_udf.c */
 int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
                       size_t block_count, unsigned char *data,
Index: mythtv/libs/libmythdvdnav/dvdread/nav_print.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/nav_print.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/nav_print.c	(working copy)
@@ -23,8 +23,6 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "config.h"
-
 #include <stdio.h>
 #include <inttypes.h>
 
Index: mythtv/libs/libmythdvdnav/dvdread/dvd_input.h
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/dvd_input.h	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/dvd_input.h	(working copy)
@@ -31,6 +31,17 @@
 
 typedef struct dvd_input_s *dvd_input_t;
 
+#if defined( __MINGW32__ )
+#   undef  lseek
+#   define lseek  _lseeki64
+#   undef  off_t
+#   define off_t off64_t
+#   undef  stat
+#   define stat  _stati64
+#   define fstat _fstati64
+#   define wstat _wstati64
+#endif
+
 /**
  * Function pointers that will be filled in by the input implementation.
  * These functions provide the main API.
Index: mythtv/libs/libmythdvdnav/dvdread/bitreader.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/bitreader.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/bitreader.c	(working copy)
@@ -18,8 +18,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "config.h"
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
Index: mythtv/libs/libmythdvdnav/dvdread/dvd_reader.h
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/dvd_reader.h	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/dvd_reader.h	(working copy)
@@ -70,6 +70,15 @@
 typedef struct dvd_file_s dvd_file_t;
 
 /**
+ * Public type that is used to provide statistics on a handle.
+ */
+typedef struct {
+  off_t size;          /**< Total size of file in bytes */
+  int nr_parts;        /**< Number of file parts */
+  off_t parts_size[9]; /**< Size of each part in bytes */
+} dvd_stat_t;
+
+/**
  * Opens a block device of a DVD-ROM file, or an image file, or a directory
  * name for a mounted DVD or HD copy of a DVD.
  *
@@ -117,6 +126,33 @@
 } dvd_read_domain_t;
 
 /**
+ * Stats a file on the DVD given the title number and domain.
+ * The information about the file is stored in a dvd_stat_t
+ * which contains information about the size of the file and
+ * the number of parts in case of a multipart file and the respective
+ * sizes of the parts.
+ * A multipart file is for instance VTS_02_1.VOB, VTS_02_2.VOB, VTS_02_3.VOB
+ * The size of VTS_02_1.VOB will be stored in stat->parts_size[0],
+ * VTS_02_2.VOB in stat->parts_size[1], ...
+ * The total size (sum of all parts) is stored in stat->size and
+ * stat->nr_parts will hold the number of parts.
+ * Only DVD_READ_TITLE_VOBS (VTS_??_[1-9].VOB) can be multipart files.
+ *
+ * This function is only of use if you want to get the size of each file
+ * in the filesystem. These sizes are not needed to use any other
+ * functions in libdvdread.
+ *
+ * @param dvd  A dvd read handle.
+ * @param titlenum Which Video Title Set should be used, VIDEO_TS is 0.
+ * @param domain Which domain.
+ * @param stat Pointer to where the result is stored.
+ * @return If successful 0, otherwise -1.
+ *
+ * int DVDFileStat(dvd, titlenum, domain, stat);
+ */
+int DVDFileStat(dvd_reader_t *, int, dvd_read_domain_t, dvd_stat_t *);
+
+/**
  * Opens a file on the DVD given the title number and domain.
  *
  * If the title number is 0, the video manager information is opened
Index: mythtv/libs/libmythdvdnav/dvdread/dvdread_internal.h
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/dvdread_internal.h	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/dvdread_internal.h	(working copy)
@@ -19,9 +19,9 @@
 #ifndef LIBDVDREAD_DVDREAD_INTERNAL_H
 #define LIBDVDREAD_DVDREAD_INTERNAL_H
 
-#ifdef _MSC_VER
+#ifdef _WIN32
 #include <unistd.h>
-#endif /* _MSC_VER */
+#endif /* _WIN32 */
 
 #define CHECK_VALUE(arg)                                                \
   if(!(arg)) {                                                          \
Index: mythtv/libs/libmythdvdnav/dvdread/dvd_udf.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/dvd_udf.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/dvd_udf.c	(working copy)
@@ -28,8 +28,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "config.h"
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -445,6 +443,10 @@
 
   L_EA = GETN4( 168 );
   L_AD = GETN4( 172 );
+
+  if (176 + L_EA + L_AD > DVD_VIDEO_LB_LEN)
+    return 0;
+
   p = 176 + L_EA;
   while( p < 176 + L_EA + L_AD ) {
     switch( flags & 0x0007 ) {
@@ -928,8 +930,7 @@
   if(GetUDFCache(device, PVDCache, 0, pvd))
     return 1;
 
-  if(!UDFGetDescriptor( device, 1, pvd_buf,
-                    sizeof(pvd_buf_base) - (pvd_buf - pvd_buf_base)))
+  if(!UDFGetDescriptor( device, 1, pvd_buf, DVD_VIDEO_LB_LEN))
     return 0;
 
   memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);
Index: mythtv/libs/libmythdvdnav/dvdread/md5.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/md5.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/md5.c	(working copy)
@@ -20,10 +20,6 @@
 
 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
 #include <sys/types.h>
 
 #include <stdlib.h>
Index: mythtv/libs/libmythdvdnav/dvdread/ifo_print.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/ifo_print.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/ifo_print.c	(working copy)
@@ -130,7 +130,7 @@
     printf("(please send a bug report), ");
   }
 
-  // Wide is allways allowed..!!!
+  // Wide is always allowed..!!!
   switch(attr->permitted_df) {
   case 0:
     printf("pan&scan+letterboxed, ");
@@ -328,7 +328,7 @@
   case 1: // Normal audio
     printf("Normal Caption ");
     break;
-  case 2: // visually imparied
+  case 2: // visually impaired
     printf("Audio for visually impaired ");
     break;
   case 3: // Directors 1
@@ -685,7 +685,7 @@
         break;
       case 2:
       case 3:
-        printf("(send bug repport) ");
+        printf("(send bug report) ");
         break;
       }
     }
@@ -781,7 +781,7 @@
     }
   }
 
-  /* Memmory offsets to div. tables. */
+  /* Memory offsets to div. tables. */
   ifoPrint_PGC_COMMAND_TBL(pgc->command_tbl);
   ifoPrint_PGC_PROGRAM_MAP(pgc->program_map, pgc->nr_of_programs);
   ifoPrint_CELL_PLAYBACK(pgc->cell_playback, pgc->nr_of_cells);
@@ -806,7 +806,7 @@
     printf("\tTitle playback type: (%02x)\n",
            *(uint8_t *)&(tt_srpt->title[i].pb_ty));
     printf("\t\t%s\n",
-           tt_srpt->title[i].pb_ty.multi_or_random_pgc_title ? "Random or Shuffle" : "Sequencial");
+           tt_srpt->title[i].pb_ty.multi_or_random_pgc_title ? "Random or Shuffle" : "Sequential");
     if (tt_srpt->title[i].pb_ty.jlc_exists_in_cell_cmd) printf("\t\tJump/Link/Call exists in cell cmd\n");
     if (tt_srpt->title[i].pb_ty.jlc_exists_in_prepost_cmd) printf("\t\tJump/Link/Call exists in pre/post cmd\n");
     if (tt_srpt->title[i].pb_ty.jlc_exists_in_button_cmd) printf("\t\tJump/Link/Call exists in button cmd\n");
@@ -1109,7 +1109,7 @@
       printf("No PGCI Unit table present\n");
     }
 
-    printf("\nParental Manegment Information table\n");
+    printf("\nParental Management Information table\n");
     printf(  "------------------------------------\n");
     if(ifohandle->ptl_mait) {
       ifoPrint_PTL_MAIT(ifohandle->ptl_mait);
@@ -1129,12 +1129,13 @@
       printf("No Text Data Manager Information present\n");
     }
 
-    printf("\nMenu Cell Adress table\n");
+
+    printf("\nMenu Cell Address table\n");
     printf(  "-----------------\n");
     if(ifohandle->menu_c_adt) {
       ifoPrint_C_ADT(ifohandle->menu_c_adt);
     } else {
-      printf("No Menu Cell Adress table present\n");
+      printf("No Menu Cell Address table present\n");
     }
 
     printf("\nVideo Manager Menu VOBU address map\n");
@@ -1176,12 +1177,12 @@
       printf("No VTS Time Map table present\n");
     }
 
-    printf("\nMenu Cell Adress table\n");
+    printf("\nMenu Cell Address table\n");
     printf(  "-----------------\n");
     if(ifohandle->menu_c_adt) {
       ifoPrint_C_ADT(ifohandle->menu_c_adt);
     } else {
-      printf("No Cell Adress table present\n");
+      printf("No Cell Address table present\n");
     }
 
     printf("\nVideo Title Set Menu VOBU address map\n");
Index: mythtv/libs/libmythdvdnav/dvdread/dvd_input.c
===================================================================
--- mythtv/libs/libmythdvdnav/dvdread/dvd_input.c	(revision 25404)
+++ mythtv/libs/libmythdvdnav/dvdread/dvd_input.c	(working copy)
@@ -19,13 +19,12 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "config.h"
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
 
+#include "config.h"
 #include "dvdread/dvd_reader.h"
 #include "dvd_input.h"
 
@@ -170,7 +169,7 @@
   }
 
   /* Open the device */
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
   dev->fd = open(target, O_RDONLY);
 #else
   dev->fd = open(target, O_RDONLY | O_BINARY);
