Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added diffs for XBMC changes to libdvd libs

cores.diff is the differences between include files in lib/libdvd
and xbmc/cores/dvdplayer/dvdinputstreams/dvdnav
  • Loading branch information...
commit 57e27aff0a152ef53d29c80ff07136cd065e77ff 1 parent 421d9fd
@Paxxi Paxxi authored
View
545 lib/libdvd/patches/cores.diff
@@ -0,0 +1,545 @@
+diff -uw dvdnav_diff/config.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/config.h
+--- dvdnav_diff/config.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/config.h 2013-01-26 23:33:20 +0100
+@@ -1,56 +1,95 @@
+-/* config.h. Generated by hand. */
++#pragma once
+
+-#ifndef LIBDVDREAD_CONFIG_H
+-#define LIBDVDREAD_CONFIG_H
++/*
++ * Copyright (C) 2005-2012 Team XBMC
++ * http://www.xbmc.org
++ *
++ * 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, 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 XBMC; see the file COPYING. If not, see
++ * <http://www.gnu.org/licenses/>.
++ *
++ */
+
+-#define HAVE_DLFCN_H 1
++/* config.h. Generated by hand. */
++#if defined(_LINUX)
++#include "PlatformInclude.h"
++#else
++#include <windows.h>
++#endif
++#include <stdio.h>
++
++//#define HAVE_DLFCN_H 1
++#define HAVE_DVDCSS_DVDCSS_H 1
+ /* #undef HAVE_DVDCSS_DVDCSS_H*/
+ /* #undef HAVE_INTTYPES_H */
+ #define HAVE_MEMORY_H 1
+-/* #undef HAVE_STDINT_H */
++#define HAVE_STDINT_H 1
+ #define HAVE_STDLIB_H 1
+ #define HAVE_STRINGS_H 1
+ #define HAVE_STRING_H 1
+ #define HAVE_SYS_STAT_H 1
+ #define HAVE_SYS_TYPES_H 1
+ /* #undef HAVE_UNISTD_H */
++#ifndef PACKAGE
+ #define PACKAGE "libdvdread"
++#endif
++#ifndef PACKAGE_BUGREPORT
+ #define PACKAGE_BUGREPORT ""
++#endif
++#ifndef PACKAGE_NAME
+ #define PACKAGE_NAME ""
++#endif
++#ifndef PACKAGE_STRING
+ #define PACKAGE_STRING ""
++#endif
++#ifndef PACKAGE_TARNAME
+ #define PACKAGE_TARNAME ""
++#endif
++#ifndef PACKAGE_VERSION
+ #define PACKAGE_VERSION ""
++#endif
+ #define STDC_HEADERS 1
++#ifndef VERSION
+ #define VERSION "1.2.6"
++#endif
+ /* #undef WORDS_BIGENDIAN */
+ /* #undef __DARWIN__ */
+ /* #undef const */
+ #define inline __inline
+ /* #undef size_t */
+
+-#define ssize_t __int64
++#define ssize_t int
+
+ #ifndef PATH_MAX
+ #define PATH_MAX MAX_PATH
+ #endif
+
++#ifndef strcasecmp
+ #define strcasecmp stricmp
++#endif
++#ifndef strncasecmp
+ #define strncasecmp strnicmp
++#endif
+
++#ifndef S_ISDIR
+ #define S_ISDIR(m) ((m) & _S_IFDIR)
++#endif
++#ifndef S_ISREG
+ #define S_ISREG(m) ((m) & _S_IFREG)
++#endif
++#ifndef S_ISBLK
+ #define S_ISBLK(m) 0
++#endif
++#ifndef S_ISCHR
+ #define S_ISCHR(m) 0
+-
+-/* Fallback types (very x86-centric, sorry) */
+-typedef unsigned char uint8_t;
+-typedef signed char int8_t;
+-typedef unsigned short uint16_t;
+-typedef signed short int16_t;
+-typedef unsigned int uint32_t;
+-typedef signed int int32_t;
+-typedef unsigned __int64 uint64_t;
+-typedef signed __int64 int64_t;
+-typedef unsigned int uintptr_t;
+-
+-#endif /* LIBDVDREAD_CONFIG_H */
++#endif
+diff -uw dvdnav_diff/decoder.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/decoder.h
+--- dvdnav_diff/decoder.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/decoder.h 2013-02-04 14:58:00 +0100
+@@ -22,6 +22,12 @@
+ #ifndef LIBDVDNAV_DECODER_H
+ #define LIBDVDNAV_DECODER_H
+
++//#include <inttypes.h>
++//#include <sys/time.h>
++
++#include "ifo_types.h" /* vm_cmd_t */
++#include "dvdnav_internal.h"
++
+ /* link command types */
+ typedef enum {
+ LinkNoLink = 0,
+diff -uw dvdnav_diff/dvd_reader.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvd_reader.h
+--- dvdnav_diff/dvd_reader.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvd_reader.h 2013-02-04 14:58:00 +0100
+@@ -24,14 +24,14 @@
+ #define LIBDVDREAD_DVD_READER_H
+
+ #ifdef _MSC_VER
+-#include <config.h>
++#include "config.h"
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #endif
+
+ #include <sys/types.h>
+-#include <inttypes.h>
++//#include <inttypes.h>
+
+ /**
+ * The DVD access interface.
+diff -uw dvdnav_diff/dvd_types.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvd_types.h
+--- dvdnav_diff/dvd_types.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvd_types.h 2013-02-04 14:58:00 +0100
+@@ -26,6 +26,8 @@
+ #ifndef LIBDVDNAV_DVD_TYPES_H
+ #define LIBDVDNAV_DVD_TYPES_H
+
++//#include <inttypes.h>
++
+ /*
+ * DVD Menu ID
+ * (see dvdnav_menu_call())
+@@ -60,7 +62,8 @@
+
+ /* the following types are currently unused */
+
+-#if 0
++//XBMC Needs some of these
++#if 1
+
+ /* Domain */
+ typedef enum {
+@@ -222,6 +225,10 @@
+ DVD_DISPLAY_MODE_4x3Letterboxed = 3
+ } DVDDisplayMode_t;
+
++typedef int DVDAudioSampleFreq_t;
++typedef int DVDAudioSampleQuant_t;
++typedef int DVDChannelNumber_t;
++
+ /* Audio attributes */
+ typedef struct {
+ DVDAudioAppMode_t AppMode;
+@@ -233,9 +240,6 @@
+ DVDAudioSampleQuant_t SampleQuantization;
+ DVDChannelNumber_t NumberOfChannels;
+ } DVDAudioAttributes_t;
+-typedef int DVDAudioSampleFreq_t;
+-typedef int DVDAudioSampleQuant_t;
+-typedef int DVDChannelNumber_t;
+
+ /* Subpicture attributes */
+ typedef enum {
+@@ -255,6 +259,8 @@
+ DVDSubpictureLangExt_t LanguageExtension;
+ } DVDSubpictureAttributes_t;
+
++typedef int DVDVideoCompression_t;
++
+ /* Video attributes */
+ typedef struct {
+ DVDBool_t PanscanPermitted;
+@@ -268,7 +274,6 @@
+ DVDBool_t Line21Field2InGop;
+ int more_to_come;
+ } DVDVideoAttributes_t;
+-typedef int DVDVideoCompression_t;
+
+ #endif
+
+diff -uw dvdnav_diff/dvdnav.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvdnav.h
+--- dvdnav_diff/dvdnav.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvdnav.h 2013-02-04 14:58:00 +0100
+@@ -32,11 +32,14 @@
+ extern "C" {
+ #endif
+
+-# include <dvdnav/dvd_types.h>
+-# include <dvdread/dvd_reader.h>
+-# include <dvdread/nav_types.h>
+-# include <dvdread/ifo_types.h> /* For vm_cmd_t */
+-# include <dvdnav/dvdnav_events.h>
++# include "dvd_types.h"
++# include "dvd_reader.h"
++# include "nav_types.h"
++# include "ifo_types.h" /* For vm_cmd_t */
++# include "dvdnav_events.h"
++# include "dvd_types.h"
++# include "dvd_reader.h"
++# include "ifo_types.h" /* For vm_cmd_t */
+
+
+
+@@ -63,11 +66,6 @@
+ #define DVDNAV_STATUS_ERR 0
+ #define DVDNAV_STATUS_OK 1
+
+-#define DVDNAV_FORMAT_AC3 0
+-#define DVDNAV_FORMAT_MPEGAUDIO 3
+-#define DVDNAV_FORMAT_LPCM 4
+-#define DVDNAV_FORMAT_DTS 5
+-#define DVDNAV_FORMAT_SDDS 6
+
+ /*********************************************************************
+ * initialisation & housekeeping functions *
+@@ -281,7 +279,7 @@
+ /*
+ * Plays the specified title, starting from the specified program
+ */
+-dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t pgcn, int32_t pgn);
++dvdnav_status_t dvdnav_program_play(dvdnav_t *self, int32_t title, int32_t pgcn, int32_t pgn);
+
+ /*
+ * Stores in *times an array (that the application *must* free) of
+@@ -695,6 +693,15 @@
+ */
+ int8_t dvdnav_is_domain_vts(dvdnav_t *self);
+
++/* XBMC added functions */
++int dvdnav_get_nr_of_subtitle_streams(dvdnav_t *self);
++
++int dvdnav_get_nr_of_audio_streams(dvdnav_t *self);
++
++int dvdnav_get_button_info(dvdnav_t* self, int alpha[2][4], int color[2][4]);
++
++int64_t dvdnav_convert_time(dvd_time_t *time);
++
+ ////////// RATDVD stuff ///////////////
+
+ /*
+diff -uw dvdnav_diff/dvdnav_events.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvdnav_events.h
+--- dvdnav_diff/dvdnav_events.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvdnav_events.h 2013-02-04 14:58:00 +0100
+@@ -25,6 +25,10 @@
+ #ifndef LIBDVDNAV_DVDNAV_EVENTS_H
+ #define LIBDVDNAV_DVDNAV_EVENTS_H
+
++#include "ifo_types.h"
++#include "dvd_reader.h"
++#include "nav_types.h"
++
+ /*
+ * DVDNAV_BLOCK_OK
+ *
+diff -uw dvdnav_diff/dvdnav_internal.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvdnav_internal.h
+--- dvdnav_diff/dvdnav_internal.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/dvdnav_internal.h 2013-02-07 14:33:08 +0100
+@@ -1,6 +1,5 @@
+-/* !! DO NO EDIT THIS FILE, it is automatically generated */
+ /*
+- * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
++ * Copyright (C) 2001-2004 Rich Wareham <richwareham@users.sourceforge.net>
+ *
+ * This file is part of libdvdnav, a DVD navigation library.
+ *
+@@ -19,8 +18,8 @@
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+-#ifndef LIBDVDREAD_DVDNAV_INTERNAL_H
+-#define LIBDVDREAD_DVDNAV_INTERNAL_H
++#ifndef LIBDVDNAV_DVDNAV_INTERNAL_H
++#define LIBDVDNAV_DVDNAV_INTERNAL_H
+
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+@@ -28,16 +27,47 @@
+
+ #include <stdlib.h>
+ #include <stdio.h>
+-#include <unistd.h>
++//#include <unistd.h>
+ #include <limits.h>
+ #include <string.h>
+-#include <pthread.h>
+
+-#undef WORDS_BIGENDIAN
++#ifdef WIN32
++
++/* pthread_mutex_* wrapper for win32 */
++#ifndef _LINUX
++#include <windows.h>
++#include <process.h>
++typedef CRITICAL_SECTION pthread_mutex_t;
++#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) DeleteCriticalSection(a)
++#endif // !_LINUX
++
++#ifndef HAVE_GETTIMEOFDAY
++/* replacement gettimeofday implementation */
++#include <sys/timeb.h>
++static inline int _private_gettimeofday( struct timeval *tv, void *tz )
++{
++ struct timeb t;
++ ftime( &t );
++ tv->tv_sec = t.time;
++ tv->tv_usec = t.millitm * 1000;
++ return 0;
++}
++#define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ))
++#endif
++
++#ifndef _LINUX
++#include <io.h> /* read() */
++#define lseek64 _lseeki64
++#endif // !_LINUX
+
+-#include "dvd_reader.h"
+-#include "ifo_read.h"
+-#include "ifo_types.h"
++#else
++
++#include <pthread.h>
++
++#endif /* WIN32 */
+
+ /* Uncomment for VM command tracing */
+ /* #define TRACE */
+@@ -48,7 +78,7 @@
+ #include "vmcmd.h"
+
+ /* 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
+@@ -126,8 +156,6 @@
+ /* General data */
+ char path[MAX_PATH_LEN]; /* Path to DVD device/dir */
+ dvd_file_t *file; /* Currently opened file */
+- int open_vtsN; /* The domain and number of the... */
+- int open_domain; /* ..currently opened VOB */
+
+ /* Position data */
+ vm_position_t position_next;
+@@ -147,6 +175,7 @@
+ int started; /* vm_start has been called? */
+ int use_read_ahead; /* 1 - use read-ahead cache, 0 - don't */
+ int pgc_based; /* positioning works PGC based instead of PG based */
++ int cur_cell_time; /* time expired since the beginning of the current cell, read from the dsi */
+
+ /* VM */
+ vm_t *vm;
+@@ -159,24 +188,38 @@
+ char err_str[MAX_ERR_LEN];
+ };
+
++/** HELPER FUNCTIONS **/
++
++/* converts a dvd_time_t to PTS ticks */
++int64_t dvdnav_convert_time(dvd_time_t *time);
++
++/* XBMC added functions */
++/*
++ * Get current playback state
++ */
++dvdnav_status_t dvdnav_get_state(dvdnav_t *self, dvd_state_t *save_state);
++
++/*
++ * Resume playback state
++ */
++dvdnav_status_t dvdnav_set_state(dvdnav_t *self, dvd_state_t *save_state);
++/* end XBMC */
++
+ /** USEFUL MACROS **/
+
+ #ifdef __GNUC__
+-#define printerrf(format, args...) snprintf(this->err_str, MAX_ERR_LEN, format, ## args);
++#define printerrf(format, args...) \
++ do { if (this) snprintf(this->err_str, MAX_ERR_LEN, format, ## args); } while (0)
+ #else
+ #ifdef _MSC_VER
+-#define printerrf(str) snprintf(this->err_str, MAX_ERR_LEN, str);
++#define printerrf(str) \
++ do { if (this) snprintf(this->err_str, MAX_ERR_LEN, str); } while (0)
+ #else
+-#define printerrf(...) snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__);
++#define printerrf(...) \
++ do { if (this) snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__); } while (0)
+ #endif /* WIN32 */
+ #endif
+-#define printerr(str) strncpy(this->err_str, str, MAX_ERR_LEN);
+-
+-/* Save my typing */
+-#define S_ERR DVDNAV_STATUS_ERR
+-
+-#ifndef _MSC_VER
+-#define S_OK DVDNAV_STATUS_OK
+-#endif /* MSC_VER */
++#define printerr(str) \
++ do { if (this) strncpy(this->err_str, str, MAX_ERR_LEN - 1); } while (0)
+
+-#endif /* LIBDVDREAD_DVDNAV_INTERNAL_H */
++#endif /* LIBDVDNAV_DVDNAV_INTERNAL_H */
+diff -uw dvdnav_diff/ifo_types.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/ifo_types.h
+--- dvdnav_diff/ifo_types.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/ifo_types.h 2013-02-04 14:58:00 +0100
+@@ -22,8 +22,8 @@
+ #ifndef LIBDVDREAD_IFO_TYPES_H
+ #define LIBDVDREAD_IFO_TYPES_H
+
+-#include <inttypes.h>
+-#include "dvdread/dvd_reader.h"
++//#include <inttypes.h>
++#include "dvd_reader.h"
+
+
+ #undef ATTRIBUTE_PACKED
+diff -uw dvdnav_diff/nav_types.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/nav_types.h
+--- dvdnav_diff/nav_types.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/nav_types.h 2013-02-04 14:58:00 +0100
+@@ -28,9 +28,27 @@
+ #ifndef LIBDVDREAD_NAV_TYPES_H
+ #define LIBDVDREAD_NAV_TYPES_H
+
+-#include <inttypes.h>
++//#include <inttypes.h>
+ #include "ifo_types.h" /* only dvd_time_t, vm_cmd_t and user_ops_t */
+
++
++#undef ATTRIBUTE_PACKED
++#undef PRAGMA_PACK_BEGIN
++#undef PRAGMA_PACK_END
++
++#if defined(__GNUC__)
++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
++#define ATTRIBUTE_PACKED __attribute__ ((packed))
++#define PRAGMA_PACK 0
++#endif
++#endif
++
++#if !defined(ATTRIBUTE_PACKED)
++#define ATTRIBUTE_PACKED
++#define PRAGMA_PACK 1
++#endif
++
++
+ /* The length including the substream id byte. */
+ #define PCI_BYTES 0x3d4
+ #define DSI_BYTES 0x3fa
+@@ -41,6 +59,12 @@
+ /* Remove this */
+ #define DSI_START_BYTE 1031
+
++
++#if PRAGMA_PACK
++#pragma pack(1)
++#endif
++
++
+ /**
+ * PCI General Information
+ */
+diff -uw dvdnav_diff/vm.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/vm.h
+--- dvdnav_diff/vm.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/vm.h 2013-02-07 14:33:08 +0100
+@@ -23,6 +23,9 @@
+ #ifndef LIBDVDNAV_VM_H
+ #define LIBDVDNAV_VM_H
+
++#include "remap.h"
++#include "dvdnav_internal.h"
++
+ /* DOMAIN enum */
+
+ typedef enum {
+@@ -156,11 +159,8 @@
+ int vm_get_audio_active_stream(vm_t *vm);
+ int vm_get_subp_active_stream(vm_t *vm, int mode);
+ void vm_get_angle_info(vm_t *vm, int *current, int *num_avail);
+-// _XBMC #if 0
+-/* 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);
+-// _XBMC #endif
+ void vm_get_video_res(vm_t *vm, int *width, int *height);
+ int vm_get_video_aspect(vm_t *vm);
+ int vm_get_video_scale_permission(vm_t *vm);
+@@ -180,5 +180,7 @@
+ void vm_position_print(vm_t *vm, vm_position_t *position);
+ #endif
+
++/* XBMC added functions */
++vm_t* dvdnav_get_vm(dvdnav_t *self);
+
+ #endif /* LIBDVDNAV_VM_H */
+diff -uw dvdnav_diff/vmcmd.h xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/vmcmd.h
+--- dvdnav_diff/vmcmd.h 2013-02-07 14:42:34 +0100
++++ xbmc/xbmc/cores/dvdplayer/DVDInputStreams/dvdnav/vmcmd.h 2013-02-04 14:58:00 +0100
+@@ -22,6 +22,8 @@
+ #ifndef LIBDVDNAV_VMCMD_H
+ #define LIBDVDNAV_VMCMD_H
+
++//#include <inttypes.h>
++
+ void vm_print_mnemonic(vm_cmd_t *command);
+ void vm_print_cmd(int row, vm_cmd_t *command);
+
View
365 lib/libdvd/patches/libdvdcss.diff
@@ -0,0 +1,365 @@
+diff -uwr libdvdcss-1.2.12/src/device.c xbmc/lib/libdvd/libdvdcss/src/device.c
+--- libdvdcss-1.2.12/src/device.c 2012-03-12 00:07:48 +0100
++++ xbmc/lib/libdvd/libdvdcss/src/device.c 2013-02-07 14:42:34 +0100
+@@ -23,6 +23,10 @@
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *****************************************************************************/
+
++/*
++ Modifications for XBMC are all contained within _XBOX (real xbox hardware) or WITH_CACHE
++*/
++
+ /*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+@@ -368,11 +372,20 @@
+
+ #if defined( WIN32 )
+ dvdcss->b_file = 1;
++#if defined( _XBOX )
++ // If we've passed over the device string make sure we don't try
++ // to use file based handling (libc) - we want Win2k routines ...
++ if (!stricmp(psz_device, "\\Device\\Cdrom0"))
++ dvdcss->b_file = 0;
++ else
++ dvdcss->b_file = stricmp(psz_device, "D:");
++#else
+ /* If device is "X:" or "X:\", we are not actually opening a file. */
+ if (psz_device[0] && psz_device[1] == ':' &&
+ (!psz_device[2] || (psz_device[2] == '\\' && !psz_device[3])))
+ dvdcss->b_file = 0;
+
++#endif // _XBOX
+ /* Initialize readv temporary buffer */
+ dvdcss->p_readv_buffer = NULL;
+ dvdcss->i_readv_buf_size = 0;
+@@ -450,11 +463,13 @@
+ }
+ else /* ASPI */
+ {
++#if !defined(_XBOX)
+ struct w32_aspidev *fd = (struct w32_aspidev *) dvdcss->i_fd;
+
+ /* Unload aspi and free w32_aspidev structure */
+ FreeLibrary( (HMODULE) fd->hASPI );
+ free( (void*) dvdcss->i_fd );
++#endif // !_XBOX
+ }
+
+ /* Free readv temporary buffer */
+@@ -510,9 +525,14 @@
+ #if defined( WIN32 )
+ static int win2k_open ( dvdcss_t dvdcss, char const *psz_device )
+ {
++#ifdef _XBOX
++ char psz_dvd[70];
++ strcpy(psz_dvd, "cdrom0:");
++#else
+ char psz_dvd[7];
+ snprintf( psz_dvd, 7, "\\\\.\\%c:", psz_device[0] );
+
++#endif
+ /* To work around an M$ bug in IOCTL_DVD_READ_STRUCTURE, we need read
+ * _and_ write access to the device (so we can make SCSI Pass Through
+ * Requests). Unfortunately this is only allowed if you have
+@@ -521,17 +541,24 @@
+ * won't send back the right result).
+ * (See Microsoft Q241374: Read and Write Access Required for SCSI
+ * Pass Through Requests) */
++
++#ifdef WITH_CACHE
++ DWORD flags = FILE_FLAG_NO_BUFFERING; /* we handle buffering ourself */
++#else
++ DWORD flags = FILE_FLAG_RANDOM_ACCESS;
++#endif //!_XBOX
++
+ dvdcss->i_fd = (int)
+ CreateFile( psz_dvd, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING,
+- FILE_FLAG_RANDOM_ACCESS, NULL );
++ flags, NULL );
+
+ if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE )
+ dvdcss->i_fd = (int)
+ CreateFile( psz_dvd, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING,
+- FILE_FLAG_RANDOM_ACCESS, NULL );
++ flags, NULL );
+
+ if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE )
+ {
+@@ -727,6 +754,9 @@
+ static int win2k_seek( dvdcss_t dvdcss, int i_blocks )
+ {
+ LARGE_INTEGER li_seek;
++#ifdef WITH_CACHE
++ int iBytesToSkip;
++#endif
+
+ #ifndef INVALID_SET_FILE_POINTER
+ # define INVALID_SET_FILE_POINTER ((DWORD)-1)
+@@ -738,6 +768,28 @@
+ return i_blocks;
+ }
+
++#ifdef WITH_CACHE
++
++ // if our buffer contains the position which we want to seek too, we can
++ // just decrease dwCacheBufferSize
++ iBytesToSkip = (i_blocks - dvdcss->i_pos) * DVDCSS_BLOCK_SIZE;
++ if (iBytesToSkip > 0 && iBytesToSkip < dvdcss->buffer_size)
++ {
++ dvdcss->buffer_size -= iBytesToSkip;
++ dvdcss->i_pos = i_blocks;
++ return dvdcss->i_pos;
++ }
++ else if (iBytesToSkip < 0 && (DISC_CACHE_SIZE - dvdcss->buffer_size) >= -iBytesToSkip)
++ {
++ // we want to seek backwards, and we have enough old data in our buffer
++ dvdcss->buffer_size -= iBytesToSkip; // since iBytesToSkip is negative, dwCacheBufferSize will get bigger
++ dvdcss->i_pos = i_blocks;
++ return dvdcss->i_pos;
++ }
++ else dvdcss->buffer_size = 0;
++
++#endif
++
+ li_seek.QuadPart = (LONGLONG)i_blocks * DVDCSS_BLOCK_SIZE;
+
+ li_seek.LowPart = SetFilePointer( (HANDLE) dvdcss->i_fd,
+@@ -827,6 +879,66 @@
+ {
+ int i_bytes;
+
++#ifdef WITH_CACHE
++
++ if (dvdcss->buffer_size < i_blocks * DVDCSS_BLOCK_SIZE)
++ {
++ // we don't have enough data in our buffer
++ int iRemaining = i_blocks * DVDCSS_BLOCK_SIZE;
++ int iCopied = 0;
++ // copy data we already have and read again into the cache
++ if (dvdcss->buffer_size > 0) memcpy(p_buffer, dvdcss->buffer + (DISC_CACHE_SIZE - dvdcss->buffer_size), dvdcss->buffer_size);
++ iCopied = dvdcss->buffer_size;
++ iRemaining -= dvdcss->buffer_size;
++ (BYTE*)p_buffer += iCopied;
++ dvdcss->buffer_size = 0;
++
++ // if remaining size is bigger >= DISC_CACHE_SIZE, don't cache it. Just read
++ if (iRemaining >= DISC_CACHE_SIZE)
++ {
++ if (!ReadFile((HANDLE)dvdcss->i_fd, p_buffer, iRemaining, (LPDWORD)&i_bytes, NULL))
++ {
++ dvdcss->i_pos = -1;
++ return -1;
++ }
++ dvdcss->i_pos += (i_bytes + iCopied) / DVDCSS_BLOCK_SIZE;
++ return (i_bytes + iCopied) / DVDCSS_BLOCK_SIZE;
++ }
++ else
++ {
++ // read a chunk into the cache and copy the needed bytes into p_buffer
++ if (!ReadFile((HANDLE)dvdcss->i_fd, dvdcss->buffer, DISC_CACHE_SIZE, &dvdcss->buffer_size, NULL))
++ {
++ // read error, maybe we tried to read to much. Try again but now without cache
++ if (!ReadFile((HANDLE)dvdcss->i_fd, p_buffer, iRemaining, (LPDWORD)&i_bytes, NULL))
++ {
++ dvdcss->i_pos = -1;
++ return -1;
++ }
++ dvdcss->i_pos += (i_bytes + iCopied) / DVDCSS_BLOCK_SIZE;
++ return (i_bytes + iCopied) / DVDCSS_BLOCK_SIZE;
++ }
++ // copy bytes into the buffer
++ memcpy(p_buffer, dvdcss->buffer, iRemaining);
++ dvdcss->buffer_size -= iRemaining;
++ dvdcss->i_pos += (iRemaining + iCopied) / DVDCSS_BLOCK_SIZE;
++ return (iRemaining + iCopied) / DVDCSS_BLOCK_SIZE;
++ }
++ }
++ else
++ {
++ // we have enough data in our cache, just copy it
++ memcpy(p_buffer, dvdcss->buffer + (DISC_CACHE_SIZE - dvdcss->buffer_size), i_blocks * DVDCSS_BLOCK_SIZE);
++ dvdcss->buffer_size -= i_blocks * DVDCSS_BLOCK_SIZE;
++ dvdcss->i_pos += i_blocks;
++ return i_blocks;
++ }
++
++ dvdcss->i_pos = -1;
++ return -1;
++
++#else // WITH_CACHE
++
+ if( !ReadFile( (HANDLE) dvdcss->i_fd, p_buffer,
+ i_blocks * DVDCSS_BLOCK_SIZE,
+ (LPDWORD)&i_bytes, NULL ) )
+@@ -837,6 +949,7 @@
+
+ dvdcss->i_pos += i_bytes / DVDCSS_BLOCK_SIZE;
+ return i_bytes / DVDCSS_BLOCK_SIZE;
++#endif // WITH_CACHE
+ }
+
+ static int aspi_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
+diff -uwr libdvdcss-1.2.12/src/ioctl.c xbmc/lib/libdvd/libdvdcss/src/ioctl.c
+--- libdvdcss-1.2.12/src/ioctl.c 2012-03-12 00:07:48 +0100
++++ xbmc/lib/libdvd/libdvdcss/src/ioctl.c 2013-02-07 14:42:34 +0100
+@@ -373,6 +373,37 @@
+
+ memcpy( p_key, dvdbs.discKeyStructures, DVD_DISCKEY_SIZE );
+
++#elif defined( _XBOX )
++ // the next piece of code will read the disc key on the xbox for all drives (samsung included)
++ // but for some reason it takes 15 - 20 seconds longer to load a dvd if mplayer has the dvd key
++ // so we let this part fail and will only use the modified ioctl_ReadTitleKey code.
++ // don't get this delay, and i'm surprised it worked as the ReadTitleKey function didn't work.
++
++ DWORD dwBytesRead;
++ DVD_READ_STRUCTURE st;
++ char buffer[DVD_DISCKEY_SIZE];
++
++ memset( &buffer, 0, sizeof( buffer ) );
++ memset( &st, 0, sizeof( st ) );
++
++ st.BlockByteOffset.QuadPart = 0;
++ st.SessionId = *pi_agid;
++ st.Format = DvdDiskKeyDescriptor;
++
++ i_ret = DeviceIoControl((HANDLE) i_fd, IOCTL_DVD_READ_STRUCTURE, &st,
++ sizeof(st), buffer, DVD_DISCKEY_SIZE, &dwBytesRead, NULL ) ? 0 : -1;
++
++ if (i_ret < 0) // didn't work
++ {
++ printf("Failed to read disc key\n");
++ return i_ret;
++ }
++
++ // copy the returned key into our key buffer
++ int i;
++ for (i = 0; i < DVD_DISCKEY_SIZE; i++)
++ p_key[i] = buffer[i+4];
++
+ #elif defined( WIN32 )
+ if( WIN2K ) /* NT/2k/XP */
+ {
+@@ -541,6 +572,25 @@
+
+ memcpy( p_key, dvdbs.titleKeyValue, DVD_KEY_SIZE );
+
++#elif defined( _XBOX ) && 0 //Faulty wrong key returned, original for WIN32 works thou so use it instead
++ DWORD dwBytesRead;
++ DVD_READ_STRUCTURE st;
++ char buffer[2048+4];
++
++ memset( &buffer, 0, sizeof( buffer ) );
++
++ st.BlockByteOffset.QuadPart = (LONGLONG) i_pos * 2048 /*DVDCSS_BLOCK_SIZE*/;
++ st.SessionId = *pi_agid;
++ st.Format = DvdDiskKeyDescriptor;
++
++ i_ret = DeviceIoControl((HANDLE) i_fd, IOCTL_DVD_READ_STRUCTURE, &st, sizeof(st), buffer, 2048+4, &dwBytesRead, NULL ) ? 0 : -1;
++ if( i_ret < 0 )
++ {
++ return i_ret;
++ }
++
++ memcpy( p_key, &(buffer[4]), 2048);
++
+ #elif defined( WIN32 )
+ if( WIN2K ) /* NT/2k/XP */
+ {
+@@ -693,8 +743,13 @@
+ ULONG id;
+ DWORD tmp;
+
++#if defined( _XBOX)
++ i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION,
++ NULL, 0, &id, sizeof(id), &tmp, NULL ) ? 0 : -1;
++#else
+ i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION,
+ &tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;
++#endif
+
+ *pi_agid = id;
+ }
+@@ -1336,8 +1391,13 @@
+
+ memcpy( key->KeyData, p_challenge, DVD_CHALLENGE_SIZE );
+
++#if defined(_XBOX)
++ i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
++ key->KeyLength, NULL, 0, &tmp, NULL ) ? 0 : -1;
++#else
+ i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
+ key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
++#endif
+ }
+ else
+ {
+diff -uwr libdvdcss-1.2.12/src/ioctl.h xbmc/lib/libdvd/libdvdcss/src/ioctl.h
+--- libdvdcss-1.2.12/src/ioctl.h 2012-03-12 00:07:48 +0100
++++ xbmc/lib/libdvd/libdvdcss/src/ioctl.h 2013-02-07 14:42:34 +0100
+@@ -324,7 +324,11 @@
+ typedef DWORD (CALLBACK *GETASPI32SUPPORTINFO)(VOID);
+ typedef DWORD (CALLBACK *SENDASPI32COMMAND)(LPVOID);
+
++#if defined(_XBOX)
++#define WIN2K 1
++#else
+ #define WIN2K ( GetVersion() < 0x80000000 )
++#endif // _XBOX
+ #define ASPI_HAID 0
+ #define ASPI_TARGET 0
+ #define DTYPE_CDROM 0x05
+diff -uwr libdvdcss-1.2.12/src/libdvdcss.c xbmc/lib/libdvd/libdvdcss/src/libdvdcss.c
+--- libdvdcss-1.2.12/src/libdvdcss.c 2012-03-12 00:07:48 +0100
++++ xbmc/lib/libdvd/libdvdcss/src/libdvdcss.c 2013-02-07 14:42:34 +0100
+@@ -195,6 +195,10 @@
+ dvdcss->b_debug = 0;
+ dvdcss->b_errors = 0;
+
++#ifdef WITH_CACHE
++ dvdcss->buffer_size = 0;
++#endif
++
+ /*
+ * Find verbosity from DVDCSS_VERBOSE environment variable
+ */
+@@ -388,7 +392,7 @@
+ dvdcss->b_scrambled = i_ret;
+ }
+ }
+-
++ /* if wo don't have b_ioctls, we don't have a disk key, make sure area is nulled */
+ memset( dvdcss->css.p_disc_key, 0, KEY_SIZE );
+ /* If disc is CSS protected and the ioctls work, authenticate the drive */
+ if( dvdcss->b_scrambled && dvdcss->b_ioctls )
+@@ -533,8 +537,26 @@
+ goto nocache;
+ }
+
++#ifdef _XBOX
++ //due to xbox file system having a limited length on folders/files,
++ //make separate folder for disk name first
++ if(psz_title[0] == '\0')
++ strcat(psz_title, "NONAME");
++
++ i += sprintf( dvdcss->psz_cachefile + i, "/%s", psz_title);
++
++ i_ret = mkdir( dvdcss->psz_cachefile );
++ if( i_ret < 0 && errno != EEXIST )
++ {
++ print_error( dvdcss, "failed creating cache titledirectory" );
++ dvdcss->psz_cachefile[0] = '\0';
++ goto nocache;
++ }
++ i += sprintf( dvdcss->psz_cachefile + i, "/%s%s", psz_serial, psz_key );
++#else
+ i += sprintf( dvdcss->psz_cachefile + i, "/%s-%s%s", psz_title,
+ psz_serial, psz_key );
++#endif
+ #if !defined( WIN32 ) || defined( SYS_CYGWIN )
+ i_ret = mkdir( dvdcss->psz_cachefile, 0755 );
+ #else
View
766 lib/libdvd/patches/libdvdnav.diff
@@ -0,0 +1,766 @@
+diff -uwr libdvdnav-4.2.0/Makefile xbmc/lib/libdvd/libdvdnav/Makefile
+--- libdvdnav-4.2.0/Makefile 2008-12-30 15:48:46 +0100
++++ xbmc/lib/libdvd/libdvdnav/Makefile 2013-02-07 14:42:34 +0100
+@@ -112,7 +112,7 @@
+ # Clean targets
+
+ clean:
+- rm -rf *~ $(.OBJDIR)/* version.h
++ rm -rf *~ $(.OBJDIR)/*
+
+ pcedit = sed \
+ -e 's,@prefix@,$(PREFIX),' \
+diff -uwr libdvdnav-4.2.0/src/dvdnav/dvdnav.h xbmc/lib/libdvd/libdvdnav/src/dvdnav/dvdnav.h
+--- libdvdnav-4.2.0/src/dvdnav/dvdnav.h 2011-02-26 21:32:32 +0100
++++ xbmc/lib/libdvd/libdvdnav/src/dvdnav/dvdnav.h 2013-02-07 14:42:34 +0100
+@@ -695,6 +695,42 @@
+ */
+ int8_t dvdnav_is_domain_vts(dvdnav_t *self);
+
++////////// RATDVD stuff ///////////////
++
++/*
++ * Get the number of audio streams.
++ */
++int32_t dvdnav_get_audio_stream_count(dvdnav_t * self);
++
++/*
++ * Get the number of subpicture streams.
++ */
++int32_t dvdnav_get_subpicture_stream_count(dvdnav_t * self);
++
++/*
++ * Get attributes of the current audio stream.
++ */
++dvdnav_status_t dvdnav_get_audio_info(dvdnav_t * self, int32_t streamid, audio_attr_t* audio_attributes);
++
++/*
++ * Get attributes of the current subpicture stream.
++ */
++dvdnav_status_t dvdnav_get_stitle_info(dvdnav_t * self, int32_t streamid, subp_attr_t* stitle_attributes);
++
++/*
++ * Get information about the current video stream
++ */
++dvdnav_status_t dvdnav_get_video_info(dvdnav_t * self, video_attr_t* video_attributes);
++
++/*
++ * Select the audio stream to be played
++ */
++dvdnav_status_t dvdnav_audio_change(dvdnav_t *self, int32_t audio);
++
++/*
++ * Select the spu stream to be displayed
++ */
++dvdnav_status_t dvdnav_subpicture_change(dvdnav_t *self, int32_t subpicture);
+
+ #ifdef __cplusplus
+ }
+diff -uwr libdvdnav-4.2.0/src/dvdnav.c xbmc/lib/libdvd/libdvdnav/src/dvdnav.c
+--- libdvdnav-4.2.0/src/dvdnav.c 2010-07-31 01:34:12 +0200
++++ xbmc/lib/libdvd/libdvdnav/src/dvdnav.c 2013-02-07 14:42:34 +0100
+@@ -337,7 +337,9 @@
+ }
+ #endif
+
+- if(num_angle != 0) {
++ /* only use ILVU information if we are at the last vobunit in ILVU */
++ /* otherwise we will miss nav packets from vobunits inbetween */
++ if(num_angle != 0 && (nav_dsi->sml_pbi.category & 0x5000) == 0x5000 ) {
+
+ if((next = nav_pci->nsml_agli.nsml_agl_dsta[angle-1]) != 0) {
+ if((next & 0x3fffffff) != 0) {
+@@ -466,6 +468,10 @@
+ /* Decode nav into pci and dsi. Then get next VOBU info. */
+ if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) {
+ printerr("Expected NAV packet but none found.");
++#ifdef _XBMC
++ /* skip this cell as we won't recover from this*/
++ vm_get_next_cell(this->vm);
++#endif
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+@@ -618,9 +624,17 @@
+ cell_event->pgc_length = dvdnav_convert_time(&state->pgc->playback_time);
+
+ cell_event->cell_start = 0;
+- for (i = 1; i < state->cellN; i++)
++ for (i = 0; i < state->cellN; i++)
++ {
++ /* only count the first angle cell */
++ if( state->pgc->cell_playback[i].block_type == BLOCK_TYPE_ANGLE_BLOCK
++ && state->pgc->cell_playback[i].block_mode != BLOCK_MODE_FIRST_CELL )
++ continue;
++
+ cell_event->cell_start +=
+- dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time);
++ dvdnav_convert_time(&state->pgc->cell_playback[i].playback_time);
++ }
++ cell_event->cell_start-= dvdnav_convert_time(&state->pgc->cell_playback[state->cellN-1].playback_time);
+
+ cell_event->pg_start = 0;
+ for (i = 1; i < state->pgc->program_map[state->pgN-1]; i++)
+@@ -769,6 +783,10 @@
+ /* Decode nav into pci and dsi. Then get next VOBU info. */
+ if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) {
+ printerr("Expected NAV packet but none found.");
++#ifdef _XBMC
++ /* skip this cell as we won't recover from this */
++ vm_get_next_cell(this->vm);
++#endif
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+@@ -1166,6 +1184,10 @@
+
+ ops.ops_int = 0;
+
++ if(!this) {
++ printerr("Passed a NULL pointer.");
++ return ops.ops_struct;
++ }
+ if(!this->started) {
+ printerr("Virtual DVD machine not started.");
+ return ops.ops_struct;
+@@ -1180,3 +1202,263 @@
+
+ return ops.ops_struct;
+ }
++
++#ifdef _XBMC
++
++vm_t* dvdnav_get_vm(dvdnav_t *this) {
++ if(!this) return 0;
++ return this->vm;
++}
++
++int dvdnav_get_nr_of_subtitle_streams(dvdnav_t *this)
++{
++ int i;
++ int count = 0;
++
++ if (this && this->vm && this->vm->state.pgc)
++ {
++ for (i = 0; i < 32; i++)
++ {
++ if (this->vm->state.pgc->subp_control[i] & (1<<31)) count++;
++ }
++ }
++ return count;
++
++ /* old code
++ if(!this || !this->vm || !this->vm->vtsi || !this->vm->vtsi->vtsi_mat) return 0;
++
++ switch ((this->vm->state).domain) {
++ case VTS_DOMAIN:
++ return this->vm->vtsi->vtsi_mat->nr_of_vts_subp_streams;
++ case VTSM_DOMAIN:
++ return this->vm->vtsi->vtsi_mat->nr_of_vtsm_subp_streams; // 1
++ case VMGM_DOMAIN:
++ case FP_DOMAIN:
++ return this->vm->vmgi->vmgi_mat->nr_of_vmgm_subp_streams; // 1
++ }
++
++ return 0;
++ */
++}
++
++int dvdnav_get_nr_of_audio_streams(dvdnav_t *this)
++{
++ int i;
++ int count = 0;
++
++ if (this && this->vm && this->vm->state.pgc)
++ {
++ for (i = 0; i < 8; i++)
++ {
++ if (this->vm->state.pgc->audio_control[i] & (1<<15)) count++;
++ }
++ }
++ return count;
++
++ /* old code
++ if(!this || !this->vm || !this->vm->vtsi || !this->vm->vtsi->vtsi_mat) return 0;
++
++ switch ((this->vm->state).domain) {
++ case VTS_DOMAIN:
++ return this->vm->vtsi->vtsi_mat->nr_of_vts_audio_streams;
++ case VTSM_DOMAIN:
++ return this->vm->vtsi->vtsi_mat->nr_of_vtsm_audio_streams; // 1
++ case VMGM_DOMAIN:
++ case FP_DOMAIN:
++ return this->vm->vmgi->vmgi_mat->nr_of_vmgm_audio_streams; // 1
++ }
++
++ return 0;
++ */
++}
++
++/* return the alpha and color for the current active button
++ * color, alpha [0][] = selection
++ * color, alpha = color
++ *
++ * argsize = [2][4]
++ */
++int dvdnav_get_button_info(dvdnav_t* this, int alpha[2][4], int color[2][4])
++{
++ int current_button, current_button_color, i;
++ pci_t* pci;
++
++ if (!this) return -1;
++
++ pci = dvdnav_get_current_nav_pci(this);
++ if (!pci) return -1;
++
++ dvdnav_get_current_highlight(this, &current_button);
++ current_button_color = pci->hli.btnit[current_button - 1].btn_coln;
++
++ for (i = 0; i < 2; i++)
++ {
++ alpha[i][0] = pci->hli.btn_colit.btn_coli[current_button_color - 1][i] >> 0 & 0xf;
++ alpha[i][1] = pci->hli.btn_colit.btn_coli[current_button_color - 1][i] >> 4 & 0xf;
++ alpha[i][2] = pci->hli.btn_colit.btn_coli[current_button_color - 1][i] >> 8 & 0xf;
++ alpha[i][3] = pci->hli.btn_colit.btn_coli[current_button_color - 1][i] >> 12 & 0xf;
++
++ color[i][0] = pci->hli.btn_colit.btn_coli[current_button_color - 1][i] >> 16 & 0xf;
++ color[i][1] = pci->hli.btn_colit.btn_coli[current_button_color - 1][i] >> 20 & 0xf;
++ color[i][2] = pci->hli.btn_colit.btn_coli[current_button_color - 1][i] >> 24 & 0xf;
++ color[i][3] = pci->hli.btn_colit.btn_coli[current_button_color - 1][i] >> 28 & 0xf;
++ }
++
++ return 0;
++}
++
++/*
++ * the next stuff is taken from ratdvd
++ */
++
++#undef printerr
++#define printerr(str) strncpy(self->err_str, str, MAX_ERR_LEN);
++
++dvdnav_status_t dvdnav_get_audio_info(dvdnav_t * self, int32_t streamid, audio_attr_t* audio_attributes)
++{
++ if(!self) {
++ printerr("Passed a NULL pointer.");
++ return -1;
++ }
++ if(!self->started) {
++ printerr("Virtual DVD machine not started.");
++ return -1;
++ }
++
++ pthread_mutex_lock(&self->vm_lock);
++ audio_attr_t attributes = vm_get_audio_attr(self->vm,streamid);
++ pthread_mutex_unlock(&self->vm_lock);
++ audio_attributes->audio_format = attributes.audio_format;
++ audio_attributes->multichannel_extension = attributes.multichannel_extension;
++ audio_attributes->lang_type = attributes.lang_type;
++ audio_attributes->application_mode = attributes.application_mode;
++ audio_attributes->quantization = attributes.quantization;
++ audio_attributes->sample_frequency = attributes.sample_frequency;
++ audio_attributes->channels = attributes.channels;
++ audio_attributes->lang_code = attributes.lang_code;
++ audio_attributes->lang_extension = attributes.lang_extension;
++ audio_attributes->code_extension = attributes.code_extension;
++ audio_attributes->unknown3 = attributes.unknown3;
++ audio_attributes->app_info = attributes.app_info;
++ return DVDNAV_STATUS_OK;
++}
++
++dvdnav_status_t dvdnav_get_stitle_info(dvdnav_t * self
++ , int32_t streamid, subp_attr_t* stitle_attributes)
++{
++ if(!self) {
++ printerr("Passed a NULL pointer.");
++ return -1;
++ }
++ if(!self->started) {
++ printerr("Virtual DVD machine not started.");
++ return -1;
++ }
++
++ pthread_mutex_lock(&self->vm_lock);
++ subp_attr_t attributes = vm_get_subp_attr(self->vm,streamid);
++ pthread_mutex_unlock(&self->vm_lock);
++ stitle_attributes->code_mode = attributes.code_mode;
++ stitle_attributes->zero1 = attributes.zero1;
++ stitle_attributes->type = attributes.type;
++ stitle_attributes->zero2 = attributes.zero2;
++ stitle_attributes->lang_code = attributes.lang_code;
++ stitle_attributes->lang_extension = attributes.lang_extension;
++ stitle_attributes->code_extension = attributes.code_extension;
++ return DVDNAV_STATUS_OK;
++}
++
++dvdnav_status_t dvdnav_get_video_info(dvdnav_t * self, video_attr_t* video_attributes)
++{
++ if(!self) {
++ printerr("Passed a NULL pointer.");
++ return -1;
++ }
++ if(!self->started) {
++ printerr("Virtual DVD machine not started.");
++ return -1;
++ }
++
++ pthread_mutex_lock(&self->vm_lock);
++ video_attr_t attributes = vm_get_video_attr(self->vm);
++ pthread_mutex_unlock(&self->vm_lock);
++
++ video_attributes->video_format = attributes.video_format;
++ video_attributes->permitted_df = attributes.permitted_df;
++ video_attributes->display_aspect_ratio = attributes.display_aspect_ratio;
++ video_attributes->mpeg_version = attributes.mpeg_version;
++ video_attributes->film_mode = attributes.film_mode;
++ video_attributes->letterboxed = attributes.letterboxed;
++ video_attributes->picture_size = attributes.picture_size;
++ video_attributes->bit_rate = attributes.bit_rate;
++ video_attributes->unknown1 = attributes.unknown1;
++ video_attributes->line21_cc_2 = attributes.line21_cc_2;
++ video_attributes->line21_cc_1 = attributes.line21_cc_1;
++ return DVDNAV_STATUS_OK;
++}
++
++dvdnav_status_t dvdnav_audio_change(dvdnav_t *self, int32_t audio)
++{
++ int32_t num;
++
++ if(!self) {
++ printerr("Passed a NULL pointer.");
++ return DVDNAV_STATUS_ERR;
++ }
++
++ num = dvdnav_get_nr_of_audio_streams(self);
++ pthread_mutex_lock(&self->vm_lock);
++ /* Set subp AUDIO if valid */
++ if((audio >= 0) && (audio <= num)) {
++ self->vm->state.AST_REG = audio;
++ } else {
++ //printerr("Passed an invalid audio number.");
++ pthread_mutex_unlock(&self->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++ pthread_mutex_unlock(&self->vm_lock);
++
++ return DVDNAV_STATUS_OK;
++}
++
++dvdnav_status_t dvdnav_subpicture_change(dvdnav_t *self, int32_t subpicture)
++{
++ int32_t num;
++
++ if(!self) {
++ printerr("Passed a NULL pointer.");
++ return DVDNAV_STATUS_ERR;
++ }
++
++ num = dvdnav_get_nr_of_subtitle_streams(self);
++ pthread_mutex_lock(&self->vm_lock);
++ /* Set subp SPRM if valid */
++ if((subpicture >= 0) && (subpicture <= num)) {
++ self->vm->state.SPST_REG = subpicture | 0x40;
++ } else if (subpicture & 0x80) {
++ self->vm->state.SPST_REG = subpicture & ~0x80;
++ } else {
++ self->vm->state.SPST_REG = subpicture;
++ //printerr("Passed an invalid subpicture number.");
++ //pthread_mutex_unlock(&self->vm_lock);
++ //return DVDNAV_STATUS_ERR;
++ }
++ pthread_mutex_unlock(&self->vm_lock);
++
++ return DVDNAV_STATUS_OK;
++}
++
++void dvdnav_lock(dvdnav_t *self)
++{
++ // we do not check for null pointer problems
++ pthread_mutex_lock(&self->vm_lock);
++}
++
++void dvdnav_unlock(dvdnav_t *self)
++{
++ // we do not check for null pointer problems
++ pthread_mutex_unlock(&self->vm_lock);
++}
++
++#endif // _XBMC
++
+diff -uwr libdvdnav-4.2.0/src/dvdnav_internal.h xbmc/lib/libdvd/libdvdnav/src/dvdnav_internal.h
+--- libdvdnav-4.2.0/src/dvdnav_internal.h 2010-06-01 12:02:38 +0200
++++ xbmc/lib/libdvd/libdvdnav/src/dvdnav_internal.h 2013-02-07 14:42:34 +0100
+@@ -175,6 +175,18 @@
+ /* converts a dvd_time_t to PTS ticks */
+ int64_t dvdnav_convert_time(dvd_time_t *time);
+
++/* XBMC added functions */
++/*
++ * Get current playback state
++ */
++dvdnav_status_t dvdnav_get_state(dvdnav_t *this, dvd_state_t *save_state);
++
++/*
++ * Resume playback state
++ */
++dvdnav_status_t dvdnav_set_state(dvdnav_t *this, dvd_state_t *save_state);
++/* end XBMC */
++
+ /** USEFUL MACROS **/
+
+ #ifdef __GNUC__
+diff -uwr libdvdnav-4.2.0/src/read_cache.c xbmc/lib/libdvd/libdvdnav/src/read_cache.c
+--- libdvdnav-4.2.0/src/read_cache.c 2008-12-30 15:48:46 +0100
++++ xbmc/lib/libdvd/libdvdnav/src/read_cache.c 2013-02-07 14:42:34 +0100
+@@ -338,7 +338,7 @@
+ pthread_mutex_lock(&cache->lock);
+ for (i = 0; i < READ_CACHE_CHUNKS; i++) {
+ if (cache->chunk[i].cache_buffer && buf >= cache->chunk[i].cache_buffer &&
+- buf < cache->chunk[i].cache_buffer + cache->chunk[i].cache_malloc_size * DVD_VIDEO_LB_LEN) {
++ buf < cache->chunk[i].cache_buffer + cache->chunk[i].cache_malloc_size * DVD_VIDEO_LB_LEN && cache->chunk[i].usage_count > 0) {
+ cache->chunk[i].usage_count--;
+ }
+ }
+diff -uwr libdvdnav-4.2.0/src/searching.c xbmc/lib/libdvd/libdvdnav/src/searching.c
+--- libdvdnav-4.2.0/src/searching.c 2011-10-07 19:06:24 +0200
++++ xbmc/lib/libdvd/libdvdnav/src/searching.c 2013-02-07 14:42:34 +0100
+@@ -121,6 +121,12 @@
+ return DVDNAV_STATUS_ERR;
+ }
+
++ if((state->pgc->prohibited_ops.title_or_time_play == 1) ||
++ (this->pci.pci_gi.vobu_uop_ctl.title_or_time_play == 1 )){
++ printerr("operation forbidden.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
+
+ this->cur_cell_time = 0;
+ if (this->pgc_based) {
+@@ -136,24 +142,109 @@
+ last_cell_nr = state->pgc->nr_of_cells;
+ }
+
++ /* FIXME: using time map is not going to work unless we are pgc_based */
++ /* we'd need to recalculate the time to be relative to full pgc first*/
++ if(!this->pgc_based)
++ {
++#ifdef LOG_DEBUG
++ fprintf(MSG_OUT, "libdvdnav: time_search - not pgc based\n");
++#endif
++ goto timemapdone;
++ }
++
++ if(!this->vm->vtsi->vts_tmapt){
++ /* no time map for this program chain */
++#ifdef LOG_DEBUG
++ fprintf(MSG_OUT, "libdvdnav: time_search - no time map for this program chain\n");
++#endif
++ goto timemapdone;
++ }
++
++ if(this->vm->vtsi->vts_tmapt->nr_of_tmaps < state->pgcN){
++ /* to few time maps for this program chain */
++#ifdef LOG_DEBUG
++ fprintf(MSG_OUT, "libdvdnav: time_search - to few time maps for this program chain\n");
++#endif
++ goto timemapdone;
++ }
++
++ /* get the tmpat corresponding to the pgc */
++ vts_tmap_t *tmap = &(this->vm->vtsi->vts_tmapt->tmap[state->pgcN-1]);
++
++ if(tmap->tmu == 0){
++ /* no time unit for this time map */
++#ifdef LOG_DEBUG
++ fprintf(MSG_OUT, "libdvdnav: time_search - no time unit for this time map\n");
++#endif
++ goto timemapdone;
++ }
++
++ /* time is in pts (90khz clock), get the number of tmu's that represent */
++ /* first entry defines at time tmu not time zero */
++ int entry = time / tmap->tmu / 90000 - 1;
++ if(entry > tmap->nr_of_entries)
++ entry = tmap->nr_of_entries -1;
++
++ if(entry > 0)
++ {
++ /* get the table entry, disregarding marking of discontinuity */
++ target = tmap->map_ent[entry] & 0x7fffffff;
++ }
++ else
++ {
++ /* start from first vobunit */
++ target = state->pgc->cell_playback[first_cell_nr-1].first_sector;;
++ }
++
++ /* if we have an additional entry we can interpolate next position */
++ /* allowed only if next entry isn't discontinious */
++
++ if( entry < tmap->nr_of_entries - 1)
++ {
++ const uint32_t target2 = tmap->map_ent[entry+1];
++ const uint64_t timeunit = tmap->tmu*90000;
++ if( !( target2 & 0x80000000) )
++ {
++ length = target2 - target;
++ target += (uint32_t) (length * ( time - (entry+1)*timeunit ) / timeunit);
++ }
++ }
++ found = 1;
++
++timemapdone:
++
+ found = 0;
+- for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) {
++ for(cell_nr = first_cell_nr; cell_nr <= last_cell_nr; cell_nr ++) {
+ cell = &(state->pgc->cell_playback[cell_nr-1]);
+ if(cell->block_type == BLOCK_TYPE_ANGLE_BLOCK && cell->block_mode != BLOCK_MODE_FIRST_CELL)
+ continue;
++
++ if(found) {
++
++ if (target >= cell->first_sector
++ && target <= cell->last_sector)
++ break;
++
++ } else {
++
+ length = dvdnav_convert_time(&cell->playback_time);
+- if (target >= length) {
+- target -= length;
++ if (time >= length) {
++ time -= length;
+ } else {
+ /* FIXME: there must be a better way than interpolation */
+- target = target * (cell->last_sector - cell->first_sector + 1) / length;
++ target = time * (cell->last_sector - cell->first_sector + 1) / length;
+ target += cell->first_sector;
+
++ #ifdef LOG_DEBUG
++ if( cell->first_sector > target || target > cell->last_sector )
++ fprintf(MSG_OUT, "libdvdnav: time_search - sector is not within cell min:%u, max:%u, cur:%u\n", cell->first_sector, cell->last_sector, target);
++ #endif
++
+ found = 1;
+ break;
+ }
+ }
+-
++ }
+ if(found) {
+ uint32_t vobu;
+ #ifdef LOG_DEBUG
+@@ -202,6 +293,7 @@
+
+ result = dvdnav_get_position(this, &target, &length);
+ if(!result) {
++ printerr("Cannot get current position");
+ return DVDNAV_STATUS_ERR;
+ }
+
+@@ -213,7 +305,7 @@
+ return DVDNAV_STATUS_ERR;
+ }
+ #ifdef LOG_DEBUG
+- fprintf(MSG_OUT, "libdvdnav: seeking to offset=%lu pos=%u length=%u\n", offset, target, length);
++ fprintf(MSG_OUT, "libdvdnav: seeking to offset=%llu pos=%u length=%u\n", offset, target, length);
+ fprintf(MSG_OUT, "libdvdnav: Before cellN=%u blockN=%u\n", state->cellN, state->blockN);
+ #endif
+
+@@ -654,3 +746,62 @@
+ free(tmp);
+ return retval;
+ }
++
++dvdnav_status_t dvdnav_get_state(dvdnav_t *this, dvd_state_t *save_state)
++{
++ if(!this || !this->vm) return DVDNAV_STATUS_ERR;
++
++ pthread_mutex_lock(&this->vm_lock);
++
++ if( !vm_get_state(this->vm, save_state) )
++ {
++ printerr("Failed to get vm state.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_OK;
++}
++
++dvdnav_status_t dvdnav_set_state(dvdnav_t *this, dvd_state_t *save_state)
++{
++ if(!this || !this->vm)
++ {
++ printerr("Passed a NULL pointer.");
++ return DVDNAV_STATUS_ERR;
++ }
++
++ if(!this->started) {
++ printerr("Virtual DVD machine not started.");
++ return DVDNAV_STATUS_ERR;
++ }
++
++ pthread_mutex_lock(&this->vm_lock);
++
++ /* reset the dvdnav state */
++ memset(&this->pci,0,sizeof(this->pci));
++ memset(&this->dsi,0,sizeof(this->dsi));
++ this->last_cmd_nav_lbn = SRI_END_OF_CELL;
++
++ /* Set initial values of flags */
++ this->position_current.still = 0;
++ this->skip_still = 0;
++ this->sync_wait = 0;
++ this->sync_wait_skip = 0;
++ this->spu_clut_changed = 0;
++
++
++ /* set the state. this will also start the vm on that state */
++ /* means the next read block should be comming from that new */
++ /* state */
++ if( !vm_set_state(this->vm, save_state) )
++ {
++ printerr("Failed to set vm state.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_OK;
++}
+diff -uwr libdvdnav-4.2.0/src/vm/vm.c xbmc/lib/libdvd/libdvdnav/src/vm/vm.c
+--- libdvdnav-4.2.0/src/vm/vm.c 2010-11-22 00:59:44 +0100
++++ xbmc/lib/libdvd/libdvdnav/src/vm/vm.c 2013-02-07 14:42:34 +0100
+@@ -255,6 +255,15 @@
+ fprintf(MSG_OUT, "libdvdnav: ifoRead_TITLE_VOBU_ADMAP vtsi failed\n");
+ return 0;
+ }
++ if(!ifoRead_VTS_TMAPT(vm->vtsi)) {
++ fprintf(MSG_OUT, "libdvdnav: ifoRead_VTS_TMAPT vtsi failed\n");
++ return 0;
++ }
++ if(!ifoRead_TITLE_C_ADT(vm->vtsi)) {
++ fprintf(MSG_OUT, "libdvdnav: ifoRead_TITLE_C_ADT vtsi failed\n");
++ return 0;
++ }
++
@Voyager1 Collaborator

@elupus @paxxi - I'm currently porting libdvdnav and libdvdread 4.2.1 to a development branch. I have a question regarding the two tests above in vm.c (function ifoOpenNewVTSI) which have been part of our xbmc added patches (already back in 4.1.3): if(!ifoRead_VTS_TMAPT(vm->vtsi)) and if(!ifoRead_TITLE_C_ADT(vm->vtsi)) - any idea why these were added? I'm trying to eliminate a couple of reasons why certain DVDs apparently play correctly with vanilla libdvd 4.2.x but not with our patched version...

@elupus Collaborator
elupus added a note
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ (vm->state).vtsN = vtsN;
+
+ return 1;
+@@ -390,7 +399,15 @@
+ /* return 0; Not really used for now.. */
+ }
+ /* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */
++#ifdef _XBMC
++ if(DVDUDFVolumeInfo(vm->dvd, vm->dvd_name, sizeof(vm->dvd_name), NULL, 0))
++ if(DVDISOVolumeInfo(vm->dvd, vm->dvd_name, sizeof(vm->dvd_name), NULL, 0))
++ strcpy(vm->dvd_name, "");
++
++ fprintf(MSG_OUT, "libdvdnav: vm: DVD Title: %s\n", vm->dvd_name);
++#else
+ dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot);
++#endif
+ vm->map = remap_loadmap(vm->dvd_name);
+ }
+ if (vm->vmgi) {
+@@ -846,7 +863,7 @@
+ }
+ }
+
+-#if 0
++// XBMC #if 0
+ /* currently unused */
+ void vm_get_audio_info(vm_t *vm, int *current, int *num_avail) {
+ switch ((vm->state).domain) {
+@@ -884,7 +901,7 @@
+ break;
+ }
+ }
+-#endif
++// XBMC #endif
+
+ void vm_get_video_res(vm_t *vm, int *width, int *height) {
+ video_attr_t attr = vm_get_video_attr(vm);
+@@ -1981,6 +1998,50 @@
+ ifoClose(ifo);
+ }
+
++int vm_get_state(vm_t *vm, dvd_state_t *save_state) {
++ *save_state = vm->state;
++
++ /* remove the pgc pointer as it might not be valid later*/
++ save_state->pgc = NULL;
++
++ return 1;
++}
++
++int vm_set_state(vm_t *vm, dvd_state_t *save_state) {
++
++ /* restore state from save_state as taken from ogle */
++
++ /* open the needed vts */
++ if( !ifoOpenNewVTSI(vm, vm->dvd, save_state->vtsN) ) return 0;
++ // sets state.vtsN
++
++ vm->state = *save_state;
++ /* set state.domain before calling */
++ //calls get_pgcit()
++ // needs state.domain and sprm[0] set
++ // sets pgcit depending on state.domain
++ //writes: state.pgc
++ // state.pgN
++ // state.TT_PGCN_REG
++
++ if( !set_PGCN(vm, save_state->pgcN) ) return 0;
++ save_state->pgc = vm->state.pgc;
++
++ /* set the rest of state after the call */
++ vm->state = *save_state;
++
++ /* if we are not in standard playback, we must get all data */
++ /* otherwise we risk loosing stillframes, and overlays */
++ if(vm->state.domain != VTS_DOMAIN)
++ vm->state.blockN = 0;
++
++ /* force a flush of data here */
++ /* we don't need a hop seek here as it's a complete state*/
++ vm->hop_channel++;
++
++ return 1;
++}
++
+ /* Debug functions */
+
+ #ifdef TRACE
+diff -uwr libdvdnav-4.2.0/src/vm/vm.h xbmc/lib/libdvd/libdvdnav/src/vm/vm.h
+--- libdvdnav-4.2.0/src/vm/vm.h 2010-07-31 01:34:16 +0200
++++ xbmc/lib/libdvd/libdvdnav/src/vm/vm.h 2013-02-07 14:42:34 +0100
+@@ -156,11 +156,11 @@
+ int vm_get_audio_active_stream(vm_t *vm);
+ int vm_get_subp_active_stream(vm_t *vm, int mode);
+ void vm_get_angle_info(vm_t *vm, int *current, int *num_avail);
+-#if 0
++// _XBMC #if 0
+ /* 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
++// _XBMC #endif
+ void vm_get_video_res(vm_t *vm, int *width, int *height);
+ int vm_get_video_aspect(vm_t *vm);
+ int vm_get_video_scale_permission(vm_t *vm);
+@@ -170,6 +170,9 @@
+ ifo_handle_t *vm_get_title_ifo(vm_t *vm, uint32_t title);
+ void vm_ifo_close(ifo_handle_t *ifo);
+
++int vm_get_state(vm_t *vm, dvd_state_t *save_state);
++int vm_set_state(vm_t *vm, dvd_state_t *save_state);
++
+ /* Uncomment for VM command tracing */
+ /* #define TRACE */
+ #ifdef TRACE
+Only in xbmc/lib/libdvd/libdvdnav: version.h
View
296 lib/libdvd/patches/libdvdread.diff
@@ -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
@Voyager1

@elupus @paxxi - I'm currently porting libdvdnav and libdvdread 4.2.1 to a development branch. I have a question regarding the two tests above in vm.c (function ifoOpenNewVTSI) which have been part of our xbmc added patches (already back in 4.1.3): if(!ifoRead_VTS_TMAPT(vm->vtsi)) and if(!ifoRead_TITLE_C_ADT(vm->vtsi)) - any idea why these were added? I'm trying to eliminate a couple of reasons why certain DVDs apparently play correctly with vanilla libdvd 4.2.x but not with our patched version...

@elupus
Please sign in to comment.
Something went wrong with that request. Please try again.