[libdvd] update patch for libdvdread
[vuplus_xbmc] / lib / libdvd / patches / 01-libdvdread.diff
diff --git a/lib/libdvd/patches/01-libdvdread.diff b/lib/libdvd/patches/01-libdvdread.diff
new file mode 100644 (file)
index 0000000..fbf185f
--- /dev/null
@@ -0,0 +1,296 @@
+diff -uwr libdvdread-4.2.0/Makefile xbmc/lib/libdvd/libdvdread/Makefile
+--- libdvdread-4.2.0/Makefile  2008-12-31 09:43:04 +0100
++++ xbmc/lib/libdvd/libdvdread/Makefile        2013-02-07 14:42:34 +0100
+@@ -121,7 +121,7 @@
+ # Clean targets
+ clean:
+-      rm -rf  *~ $(.OBJDIR)/* version.h
++      rm -rf  *~ $(.OBJDIR)/* 
+ distclean: clean
+diff -uwr libdvdread-4.2.0/src/dvd_input.h xbmc/lib/libdvd/libdvdread/src/dvd_input.h
+--- libdvdread-4.2.0/src/dvd_input.h   2010-06-01 19:07:14 +0200
++++ xbmc/lib/libdvd/libdvdread/src/dvd_input.h 2013-02-07 14:42:34 +0100
+@@ -34,6 +34,13 @@
+ #if defined( __MINGW32__ )
+ #   undef  lseek
+ #   define lseek  _lseeki64
++#   undef  fseeko
++#   define fseeko fseeko64
++#   undef  ftello
++#   define ftello ftello64
++#   define flockfile(...)
++#   define funlockfile(...)
++#   define getc_unlocked getc
+ #   undef  off_t
+ #   define off_t off64_t
+ #   undef  stat
+diff -uwr libdvdread-4.2.0/src/dvd_reader.c xbmc/lib/libdvd/libdvdread/src/dvd_reader.c
+--- libdvdread-4.2.0/src/dvd_reader.c  2011-06-15 20:09:16 +0200
++++ xbmc/lib/libdvd/libdvdread/src/dvd_reader.c        2013-02-07 14:42:34 +0100
+@@ -32,6 +32,11 @@
+ #include <unistd.h>
+ #include <limits.h>
+ #include <dirent.h>
++#ifndef WIN32
++#include <paths.h>
++#endif
++
++#define WITH_CACHE
+ /* misc win32 helpers */
+ #ifdef WIN32
+@@ -105,6 +110,10 @@
+   uint32_t lb_start;
+   uint32_t seek_pos;
++#ifdef WITH_CACHE
++    char cache[DVD_VIDEO_LB_LEN];
++    uint32_t lb_cache;
++#endif
+   /* Information required for a directory path drive. */
+   size_t title_sizes[ TITLES_MAX ];
+   dvd_input_t title_devs[ TITLES_MAX ];
+@@ -617,6 +626,10 @@
+   memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
+   dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
++#ifdef WITH_CACHE
++    dvd_file->lb_cache = -1;
++#endif
++
+   return dvd_file;
+ }
+@@ -628,6 +641,18 @@
+  */
+ static int findDirFile( const char *path, const char *file, char *filename )
+ {
++#if defined(_XBMC)
++      struct stat fileinfo;
++
++      // no emulated opendir function in xbmc, so we'll
++      // check if the file exists by stat'ing it ...
++      sprintf(filename, "%s%s%s", path,
++                     ( ( path[ strlen( path ) - 1 ] == '/' ) ? "" : "/" ),
++                     file );
++
++      if (stat(filename, &fileinfo) == 0) return 0;
++      
++#else
+   DIR *dir;
+   struct dirent *ent;
+@@ -644,6 +669,7 @@
+     }
+   }
+   closedir(dir);
++#endif // _XBMC
+   return -1;
+ }
+@@ -722,6 +748,9 @@
+   dvd_file->title_devs[ 0 ] = dev;
+   dvd_file->filesize = dvd_file->title_sizes[ 0 ];
++#ifdef WITH_CACHE
++    dvd_file->lb_cache = -1;
++#endif
+   return dvd_file;
+ }
+@@ -749,6 +778,9 @@
+   memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
+   dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
++#ifdef WITH_CACHE
++    dvd_file->lb_cache = -1;
++#endif
+   /* Calculate the complete file size for every file in the VOBS */
+   if( !menu ) {
+     int cur;
+@@ -792,6 +824,10 @@
+   memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
+   dvd_file->filesize = 0;
++#ifdef WITH_CACHE
++    dvd_file->lb_cache = -1;
++#endif
++
+   if( menu ) {
+     dvd_input_t dev;
+@@ -1203,6 +1239,100 @@
+   return ret + ret2;
+ }
++#ifdef WITH_CACHE
++
++/* returns true aslong as the sector isn't all zeros */
++int DVDCheckSector(unsigned char *data, int offset)
++{
++  int i = 0;
++  int32_t *p = (int32_t*)data + (DVD_VIDEO_LB_LEN>>2)*offset;
++  for(;i<(DVD_VIDEO_LB_LEN<<2);i++) {
++    if(*(p+i) != 0)
++      break;
++  }
++  return (i!=(DVD_VIDEO_LB_LEN>>2));
++}
++
++int DVDReadBlocksCached( dvd_file_t *dvd_file, int offset, 
++                     size_t block_count, unsigned char *data, int encrypted )
++{
++    int ret=0;
++    /* Check arguments. */
++    if( dvd_file == NULL || offset < 0 || data == NULL )
++      return -1;
++
++    if(encrypted & DVDINPUT_READ_DECRYPT) {
++      /* 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;
++        if( dvd_file->dvd->isImageFile ) {
++        dvdinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start );
++        } 
++        /* 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 );
++        }*/
++      }
++    }
++
++    /* check if first sector is in cache */
++    int cachehit = 0;
++    if( offset == dvd_file->lb_cache ) {
++      memcpy( data, dvd_file->cache, DVD_VIDEO_LB_LEN );
++      block_count--;
++      offset++;
++      data+=DVD_VIDEO_LB_LEN;
++      cachehit = 1;
++    }
++
++
++    if( block_count > 0 )
++    {
++      if( dvd_file->dvd->isImageFile )
++              ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset, 
++                                          block_count, data, encrypted );
++      else
++              ret = DVDReadBlocksPath( dvd_file, (unsigned int)offset, 
++                                          block_count, data, encrypted );      
++
++      if(ret<0)
++        return ret;
++
++      /* here is a hack for drive wich don't handle layerchange properly */
++      /* they start returning zero data while laser is shifting position */
++      /* normally just doing a reread will get the correct data */
++      if( dvd_file->dvd->isImageFile )
++      {
++        /* check sectors from the back */
++        int count = ret; /* previous call could have returned fewer than requested */
++        int i = count-1;
++        for(;i>=0;i--)
++          if(!DVDCheckSector(data, i)) break;
++
++        if(i>=0) {
++          fprintf( stderr, "libdvdread: potential layer change. %d zero sectors detected starting at %d!\n", i+1, offset);
++
++          /* reread the invalid sectors */
++          count = DVDReadBlocksUDF( dvd_file, (uint32_t)offset+i,
++                                          count-i, data+DVD_VIDEO_LB_LEN*i, encrypted );
++
++          if(count<0)
++            return count;
++        }
++      }
++
++    }
++    
++    if(ret>0)
++    { /* store last sector read into cache */
++      dvd_file->lb_cache = offset+ret-1;
++      memcpy( dvd_file->cache, data+(DVD_VIDEO_LB_LEN*(ret-1)), DVD_VIDEO_LB_LEN );
++    }
++    
++    return (ssize_t)(ret+cachehit);
++}
++#endif
++
+ /* This is broken reading more than 2Gb at a time is ssize_t is 32-bit. */
+ ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
+                        size_t block_count, unsigned char *data )
+@@ -1213,6 +1343,10 @@
+   if( dvd_file == NULL || offset < 0 || data == NULL )
+     return -1;
++#ifdef WITH_CACHE
++    return (ssize_t)DVDReadBlocksCached( dvd_file, offset, block_count, data, DVDINPUT_READ_DECRYPT );
++#endif
++
+   /* 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;
+@@ -1295,6 +1429,10 @@
+     return 0;
+   }
++#ifdef WITH_CACHE
++      ret = DVDReadBlocksCached( dvd_file, (uint32_t) seek_sector, 
++                              (size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
++#else
+   if( dvd_file->dvd->isImageFile ) {
+     ret = DVDReadBlocksUDF( dvd_file, (uint32_t) seek_sector,
+                             (size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
+@@ -1302,6 +1440,7 @@
+     ret = DVDReadBlocksPath( dvd_file, seek_sector,
+                              (size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
+   }
++#endif
+   if( ret != (int) numsec ) {
+     free( secbuf_base );
+Only in xbmc/lib/libdvd/libdvdread: version.h
+diff -uwr libdvdread-4.2.0/version.sh xbmc/lib/libdvd/libdvdread/version.sh
+--- libdvdread-4.2.0/version.sh        2008-05-01 11:27:16 +0200
++++ xbmc/lib/libdvd/libdvdread/version.sh      2013-02-07 14:42:34 +0100
+@@ -1,18 +1,18 @@
+-#!/bin/sh
+-
+-svn_revision=`cd "$1" && LC_ALL=C svn info 2> /dev/null | grep Revision | cut -d' ' -f2`
+-test $svn_revision || svn_revision=`cd "$1" && grep revision .svn/entries 2>/dev/null | \
+-                                    cut -d '"' -f2 2> /dev/null`
+-test $svn_revision || svn_revision=UNKNOWN
+-
+-if test "$svn_revision" = UNKNOWN && test -n "$2"; then
+-    NEW_REVISION="#define VERSION \"$2\""
+-else
+-    NEW_REVISION="#define VERSION \"SVN-r$svn_revision\""
+-fi
+-OLD_REVISION=`cat version.h 2> /dev/null`
+-
+-# Update version.h only on revision changes to avoid spurious rebuilds
+-if test "$NEW_REVISION" != "$OLD_REVISION"; then
+-    echo "$NEW_REVISION" > version.h
+-fi
++##!/bin/sh
++#
++#svn_revision=`cd "$1" && LC_ALL=C svn info 2> /dev/null | grep Revision | cut -d' ' -f2`
++#test $svn_revision || svn_revision=`cd "$1" && grep revision .svn/entries 2>/dev/null | \
++#                                    cut -d '"' -f2 2> /dev/null`
++#test $svn_revision || svn_revision=UNKNOWN
++#
++#if test "$svn_revision" = UNKNOWN && test -n "$2"; then
++#    NEW_REVISION="#define VERSION \"$2\""
++#else
++#    NEW_REVISION="#define VERSION \"SVN-r$svn_revision\""
++#fi
++#OLD_REVISION=`cat version.h 2> /dev/null`
++#
++## Update version.h only on revision changes to avoid spurious rebuilds
++#if test "$NEW_REVISION" != "$OLD_REVISION"; then
++#    echo "$NEW_REVISION" > version.h
++#fi