OSDN Git Service

add libdvdnav support
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Mon, 27 Apr 2009 15:18:05 +0000 (15:18 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Mon, 27 Apr 2009 15:18:05 +0000 (15:18 +0000)
emulates the vm of a dvd player in order to navigate the disc more reliably
it is optional and disabled by default
CLI option '--dvdnav' enables.  GUI's have a new option in preferences.
When dvdnav is enabled, you can also select angles (cli '--angle')

git-svn-id: svn://localhost/HandBrake/trunk@2355 b64f7644-9d1e-0410-96f1-a4d463321fa5

38 files changed:
contrib/libdvdnav/A00-log-stderr.patch [new file with mode: 0644]
contrib/libdvdnav/P00-mingw-no-examples.patch [new file with mode: 0644]
contrib/libdvdnav/module.defs [new file with mode: 0644]
contrib/libdvdnav/module.rules [new file with mode: 0644]
contrib/libdvdread/A00-volume-name.patch [new file with mode: 0644]
contrib/libdvdread/P00-darwin-css-vlc-dylib.patch
contrib/libdvdread/P01-cygwin.patch [deleted file]
contrib/libdvdread/P02-mingw-ssize_t.patch [deleted file]
contrib/libdvdread/P03-mingw-disable-dlopen.patch [deleted file]
contrib/libdvdread/P04-mingw-endian-macros.patch [deleted file]
contrib/libdvdread/P05-mingw-large-file.patch
contrib/libdvdread/P06-darwin.patch [new file with mode: 0644]
contrib/libdvdread/module.defs
gtk/src/Makefile.am
gtk/src/callbacks.c
gtk/src/ghb.ui
gtk/src/hb-backend.c
gtk/src/hb-backend.h
gtk/src/internal_defaults.xml
gtk/src/widgetdeps.c
libhb/common.h
libhb/dvd.c
libhb/dvd.h [new file with mode: 0644]
libhb/dvdnav.c [new file with mode: 0644]
libhb/hb.h
libhb/internal.h
libhb/module.defs
libhb/reader.c
libhb/scan.c
macosx/Controller.h
macosx/Controller.mm
macosx/English.lproj/MainMenu.xib
macosx/English.lproj/Preferences.xib
macosx/HBPreferencesController.m
macosx/HandBrake.xcodeproj/project.pbxproj
make/include/main.defs
test/module.defs
test/test.c

diff --git a/contrib/libdvdnav/A00-log-stderr.patch b/contrib/libdvdnav/A00-log-stderr.patch
new file mode 100644 (file)
index 0000000..36435dc
--- /dev/null
@@ -0,0 +1,12 @@
+diff -Naur libdvdnav.orig/src/dvdnav_internal.h libdvdnav/src/dvdnav_internal.h
+--- libdvdnav.orig/src/dvdnav_internal.h       2008-10-03 13:11:43.000000000 -0700
++++ libdvdnav/src/dvdnav_internal.h    2009-04-24 14:23:04.000000000 -0700
+@@ -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
diff --git a/contrib/libdvdnav/P00-mingw-no-examples.patch b/contrib/libdvdnav/P00-mingw-no-examples.patch
new file mode 100644 (file)
index 0000000..0e06186
--- /dev/null
@@ -0,0 +1,21 @@
+diff -Naur libdvdnav.orig/Makefile.am libdvdnav/Makefile.am
+--- libdvdnav.orig/Makefile.am 2008-10-03 16:11:46.000000000 -0400
++++ libdvdnav/Makefile.am      2009-04-24 02:53:15.000000000 -0400
+@@ -1,7 +1,7 @@
+ include $(top_srcdir)/misc/Makefile.common
+-SUBDIRS = src examples doc misc m4
++SUBDIRS = src doc misc m4
+ EXTRA_DIST = autogen.sh \
+            AUTHORS \
+diff -Naur libdvdnav.orig/configure.ac libdvdnav/configure.ac
+--- libdvdnav.orig/configure.ac        2009-01-08 17:57:11.000000000 -0500
++++ libdvdnav/configure.ac     2009-04-24 02:52:34.000000000 -0400
+@@ -252,5 +252,4 @@
+ misc/relchk.sh
+ m4/Makefile
+ doc/Makefile
+-examples/Makefile
+ ])
diff --git a/contrib/libdvdnav/module.defs b/contrib/libdvdnav/module.defs
new file mode 100644 (file)
index 0000000..4134146
--- /dev/null
@@ -0,0 +1,9 @@
+$(eval $(call import.MODULE.defs,LIBDVDNAV,libdvdnav,LIBDVDREAD))
+$(eval $(call import.CONTRIB.defs,LIBDVDNAV))
+
+LIBDVDNAV.FETCH.url = http://download.m0k.org/handbrake/contrib/libdvdnav-svn1168.tar.gz
+LIBDVDNAV.EXTRACT.tarbase = libdvdnav
+
+LIBDVDNAV.CONFIGURE.bootstrap = rm -fr aclocal.m4 autom4te.cache; autoreconf -fiv;
+
+LIBDVDNAV.CONFIGURE.extra += --with-dvdread-config=$(call fn.ABSOLUTE,$(CONTRIB.build/)bin/dvdread-config)
diff --git a/contrib/libdvdnav/module.rules b/contrib/libdvdnav/module.rules
new file mode 100644 (file)
index 0000000..8d23cca
--- /dev/null
@@ -0,0 +1,2 @@
+$(eval $(call import.MODULE.rules,LIBDVDNAV))
+$(eval $(call import.CONTRIB.rules,LIBDVDNAV))
diff --git a/contrib/libdvdread/A00-volume-name.patch b/contrib/libdvdread/A00-volume-name.patch
new file mode 100644 (file)
index 0000000..af7018e
--- /dev/null
@@ -0,0 +1,12 @@
+diff -Naur libdvdread.orig/src/dvd_udf.c libdvdread/src/dvd_udf.c
+--- libdvdread.orig/src/dvd_udf.c      2009-01-08 14:57:10.000000000 -0800
++++ libdvdread/src/dvd_udf.c   2009-04-23 13:36:08.000000000 -0700
+@@ -928,7 +928,7 @@
+   if(GetUDFCache(device, PVDCache, 0, pvd))
+     return 1;
+-  if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf)))
++  if(!UDFGetDescriptor( device, 1, pvd_buf, DVD_VIDEO_LB_LEN))
+     return 0;
+   memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);
index cb01815..d6c5f6d 100644 (file)
@@ -1,12 +1,12 @@
-diff -Naur libdvdread.orig/dvdread/dvd_input.c libdvdread/dvdread/dvd_input.c
---- libdvdread.orig/dvdread/dvd_input.c        2005-09-19 09:43:08.000000000 -0400
-+++ libdvdread/dvdread/dvd_input.c     2009-02-21 10:22:42.000000000 -0500
-@@ -332,7 +332,7 @@
+diff -Naur libdvdread.orig/src/dvd_input.c libdvdread/src/dvd_input.c
+--- libdvdread.orig/src/dvd_input.c    2009-01-08 14:57:10.000000000 -0800
++++ libdvdread/src/dvd_input.c 2009-04-24 09:02:34.000000000 -0700
+@@ -285,7 +285,7 @@
+   /* dlopening libdvdcss */
  
- #else
--  dvdcss_library = dlopen("libdvdcss.so.2", RTLD_LAZY);
-+  dvdcss_library = dlopen("/Applications/VLC.app/Contents/MacOS/lib/libdvdcss.2.dylib", RTLD_LAZY);
-   if(dvdcss_library != NULL) {
- #if defined(__OpenBSD__) && !defined(__ELF__)
+ #ifdef __APPLE__
+-  #define CSS_LIB "libdvdcss.2.dylib"
++  #define CSS_LIB "/Applications/VLC.app/Contents/MacOS/lib/libdvdcss.2.dylib"
+ #elif defined(WIN32)
+   #define CSS_LIB "libdvdcss.dll"
+ #elif defined(__OS2__)
diff --git a/contrib/libdvdread/P01-cygwin.patch b/contrib/libdvdread/P01-cygwin.patch
deleted file mode 100644 (file)
index fbb1f12..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-diff -Naur libdvdread/configure libdvdread/configure
---- libdvdread/configure       2006-10-06 04:14:24.000000000 -0400
-+++ libdvdread/configure       2008-10-04 08:51:17.153181000 -0400
-@@ -3550,9 +3550,6 @@
- _ACEOF
-     ;;
--  x*mingw32* | x*cygwin*)
--    CFLAGS="${CFLAGS} -Dssize_t=long"
--    ;;
-   x*)
-     ;;
- esac
-diff -Naur libdvdread/configure.in libdvdread/configure.in
---- libdvdread/configure.in    2006-10-06 04:12:31.000000000 -0400
-+++ libdvdread/configure.in    2008-10-04 08:51:26.356306000 -0400
-@@ -15,9 +15,6 @@
-     CFLAGS="${CFLAGS} -no-cpp-precomp"
-     AC_DEFINE(__DARWIN__, 1, Have a Mac OS X system)
-     ;;
--  x*mingw32* | x*cygwin*)
--    CFLAGS="${CFLAGS} -Dssize_t=long"
--    ;;
-   x*)
-     ;;
- esac
\ No newline at end of file
diff --git a/contrib/libdvdread/P02-mingw-ssize_t.patch b/contrib/libdvdread/P02-mingw-ssize_t.patch
deleted file mode 100644 (file)
index a4dc5ed..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-diff -Naur libdvdread.orig/configure libdvdread/configure
---- libdvdread.orig/configure  2006-10-06 04:14:24.000000000 -0400
-+++ libdvdread/configure       2009-03-10 17:45:06.000000000 -0400
-@@ -3550,9 +3550,6 @@
- _ACEOF
-     ;;
--  x*mingw32* | x*cygwin*)
--    CFLAGS="${CFLAGS} -Dssize_t=long"
--    ;;
-   x*)
-     ;;
- esac
-diff -Naur libdvdread.orig/configure.in libdvdread/configure.in
---- libdvdread.orig/configure.in       2006-10-06 04:12:31.000000000 -0400
-+++ libdvdread/configure.in    2009-03-10 17:45:06.000000000 -0400
-@@ -15,9 +15,6 @@
-     CFLAGS="${CFLAGS} -no-cpp-precomp"
-     AC_DEFINE(__DARWIN__, 1, Have a Mac OS X system)
-     ;;
--  x*mingw32* | x*cygwin*)
--    CFLAGS="${CFLAGS} -Dssize_t=long"
--    ;;
-   x*)
-     ;;
- esac
diff --git a/contrib/libdvdread/P03-mingw-disable-dlopen.patch b/contrib/libdvdread/P03-mingw-disable-dlopen.patch
deleted file mode 100644 (file)
index 5155262..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-diff -Naur libdvdread.orig/configure libdvdread/configure
---- libdvdread.orig/configure  2006-10-06 04:14:24.000000000 -0400
-+++ libdvdread/configure       2009-03-10 17:48:56.000000000 -0400
-@@ -18889,11 +18889,6 @@
- echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
- if test $ac_cv_lib_dl_dlopen = yes; then
-    DL_LIBS=-ldl
--else
--  { { echo "$as_me:$LINENO: error: You need libdl (dlopen)" >&5
--echo "$as_me: error: You need libdl (dlopen)" >&2;}
--   { (exit 1); exit 1; }; }
--
- fi
-diff -Naur libdvdread.orig/dvdread/dvd_input.c libdvdread/dvdread/dvd_input.c
---- libdvdread.orig/dvdread/dvd_input.c        2005-09-19 09:43:08.000000000 -0400
-+++ libdvdread/dvdread/dvd_input.c     2009-03-10 18:01:43.000000000 -0400
-@@ -44,18 +44,6 @@
- char *      (*dvdinput_error) (dvd_input_t);
--#ifdef HAVE_DVDCSS_DVDCSS_H
--/* linking to libdvdcss */
--#include <dvdcss/dvdcss.h>
--#define DVDcss_open(a) dvdcss_open((char*)(a))
--#define DVDcss_close   dvdcss_close
--#define DVDcss_seek    dvdcss_seek
--#define DVDcss_title   dvdcss_title
--#define DVDcss_read    dvdcss_read
--#define DVDcss_error   dvdcss_error
--#else
--/* dlopening libdvdcss */
--#include <dlfcn.h>
- typedef struct dvdcss_s *dvdcss_handle;
- static dvdcss_handle (*DVDcss_open)  (const char *);
- static int           (*DVDcss_close) (dvdcss_handle);
-@@ -63,7 +51,6 @@
- static int           (*DVDcss_title) (dvdcss_handle, int); 
- static int           (*DVDcss_read)  (dvdcss_handle, void *, int, int);
- static char *        (*DVDcss_error) (dvdcss_handle);
--#endif
- /* The DVDinput handle, add stuff here for new input methods. */
- struct dvd_input_s {
-@@ -290,17 +277,7 @@
-  */
- void dvdinput_free(void)
- {
--#ifdef HAVE_DVDCSS_DVDCSS_H
--  /* linked statically, nothing to free */
-   return;
--#else
--  if(dvdcss_library) {
--    dlclose(dvdcss_library);
--    dvdcss_library = NULL;
--  }
--  dvdcss_library_init = 0;
--  return;
--#endif
- }
-@@ -324,58 +301,6 @@
-   verbose = get_verbose();
-   
--#ifdef HAVE_DVDCSS_DVDCSS_H
--  /* linking to libdvdcss */
--  dvdcss_library = &dvdcss_library;  /* Give it some value != NULL */
--  /* the DVDcss_* functions have been #defined at the top */
--  dvdcss_version = &dvdcss_interface_2;
--
--#else
--
--  dvdcss_library = dlopen("libdvdcss.so.2", RTLD_LAZY);
--
--  if(dvdcss_library != NULL) {
--#if defined(__OpenBSD__) && !defined(__ELF__)
--#define U_S "_"
--#else
--#define U_S
--#endif
--    DVDcss_open = (dvdcss_handle (*)(const char*))
--      dlsym(dvdcss_library, U_S "dvdcss_open");
--    DVDcss_close = (int (*)(dvdcss_handle))
--      dlsym(dvdcss_library, U_S "dvdcss_close");
--    DVDcss_title = (int (*)(dvdcss_handle, int))
--      dlsym(dvdcss_library, U_S "dvdcss_title");
--    DVDcss_seek = (int (*)(dvdcss_handle, int, int))
--      dlsym(dvdcss_library, U_S "dvdcss_seek");
--    DVDcss_read = (int (*)(dvdcss_handle, void*, int, int))
--      dlsym(dvdcss_library, U_S "dvdcss_read");
--    DVDcss_error = (char* (*)(dvdcss_handle))
--      dlsym(dvdcss_library, U_S "dvdcss_error");
--    
--    dvdcss_version = (char **)dlsym(dvdcss_library, U_S "dvdcss_interface_2");
--
--    if(dlsym(dvdcss_library, U_S "dvdcss_crack")) {
--      if(verbose >= 0) {
--        fprintf(stderr, 
--                "libdvdread: Old (pre-0.0.2) version of libdvdcss found.\n"
--                "libdvdread: You should get the latest version from "
--                "http://www.videolan.org/\n" );
--      }
--      dlclose(dvdcss_library);
--      dvdcss_library = NULL;
--    } else if(!DVDcss_open  || !DVDcss_close || !DVDcss_title || !DVDcss_seek
--              || !DVDcss_read || !DVDcss_error || !dvdcss_version) {
--      if(verbose >= 0) {
--        fprintf(stderr,  "libdvdread: Missing symbols in libdvdcss.so.2, "
--                "this shouldn't happen !\n");
--      }
--      dlclose(dvdcss_library);
--      dvdcss_library = NULL;
--    }
--  }
--#endif /* HAVE_DVDCSS_DVDCSS_H */
--
-   dvdcss_library_init = 1;
-   
-   if(dvdcss_library) {
-diff -Naur libdvdread.orig/dvdread/dvd_reader.c libdvdread/dvdread/dvd_reader.c
---- libdvdread.orig/dvdread/dvd_reader.c       2006-10-06 03:58:03.000000000 -0400
-+++ libdvdread/dvdread/dvd_reader.c    2009-03-10 17:51:22.000000000 -0400
-@@ -183,7 +183,7 @@
-   dev->align = align;
- }
--#ifdef WIN32 /* replacement gettimeofday implementation */
-+#if defined(WIN32) && !defined(__MINGW32__) /* replacement gettimeofday implementation */
- #include <sys/timeb.h>
- static int gettimeofday( struct timeval *tv, void *tz )
- {
diff --git a/contrib/libdvdread/P04-mingw-endian-macros.patch b/contrib/libdvdread/P04-mingw-endian-macros.patch
deleted file mode 100644 (file)
index 872b851..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-diff -Naur libdvdread.orig/dvdread/bswap.h libdvdread/dvdread/bswap.h
---- libdvdread.orig/dvdread/bswap.h    2006-06-06 16:03:37.000000000 -0400
-+++ libdvdread/dvdread/bswap.h 2009-03-13 21:05:23.000000000 -0400
-@@ -83,6 +83,25 @@
- #define B2N_32(x) x = OSSwapBigToHostConstInt32(x)
- #define B2N_64(x) x = OSSwapBigToHostConstInt64(x)
-+#elif defined(__MINGW32__)
-+#define B2N_16(x)                               \
-+  x = ((((x) & 0xff00) >> 8) |                  \
-+       (((x) & 0x00ff) << 8))
-+#define B2N_32(x)                               \
-+  x = ((((x) & 0xff000000) >> 24) |             \
-+       (((x) & 0x00ff0000) >>  8) |             \
-+       (((x) & 0x0000ff00) <<  8) |             \
-+       (((x) & 0x000000ff) << 24))
-+#define B2N_64(x)                               \
-+  x = ((((x) & 0xff00000000000000ULL) >> 56) |     \
-+       (((x) & 0x00ff000000000000ULL) >> 40) |     \
-+       (((x) & 0x0000ff0000000000ULL) >> 24) |     \
-+       (((x) & 0x000000ff00000000ULL) >>  8) |     \
-+       (((x) & 0x00000000ff000000ULL) <<  8) |     \
-+       (((x) & 0x0000000000ff0000ULL) << 24) |     \
-+       (((x) & 0x000000000000ff00ULL) << 40) |     \
-+       (((x) & 0x00000000000000ffULL) << 56))
-+
- #else
- #if defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__) || defined(WIN32) || defined(__BEOS__) || defined(__INTERIX)
- /* These systems don't have swap macros */
index 7ed9b65..480d1e9 100644 (file)
@@ -1,6 +1,7 @@
---- libdvdread.orig/dvdread/dvd_input.h        2005-09-06 12:23:00.000000000 -0700
-+++ libdvdread/dvdread/dvd_input.h     2009-03-25 15:01:39.000000000 -0700
-@@ -28,6 +28,24 @@
+diff -Naur libdvdread.orig/src/dvd_input.h libdvdread/src/dvd_input.h
+--- libdvdread.orig/src/dvd_input.h    2008-10-03 13:11:30.000000000 -0700
++++ libdvdread/src/dvd_input.h 2009-04-23 13:47:04.000000000 -0700
+@@ -29,6 +29,24 @@
  
  #define DVDINPUT_READ_DECRYPT    (1 << 0)
  
@@ -25,4 +26,3 @@
  typedef struct dvd_input_s *dvd_input_t;
  
  /**
-
diff --git a/contrib/libdvdread/P06-darwin.patch b/contrib/libdvdread/P06-darwin.patch
new file mode 100644 (file)
index 0000000..b6efc2e
--- /dev/null
@@ -0,0 +1,25 @@
+diff -Naur libdvdread.orig/configure.ac libdvdread/configure.ac
+--- libdvdread.orig/configure.ac       2009-01-08 17:57:10.000000000 -0500
++++ libdvdread/configure.ac    2009-04-24 01:50:56.000000000 -0400
+@@ -145,6 +145,9 @@
+   *cygwin*)
+     LDFLAGS="-no-undefined $LDFLAGS"
+     ;;
++  *darwin*)
++    CFLAGS="${CFLAGS} -D__DARWIN__"
++    ;;
+   *os2*)
+     LDFLAGS="-no-undefined -Zbin-files $LDFLAGS"
+     ;;
+diff -Naur libdvdread.orig/src/dvd_reader.c libdvdread/src/dvd_reader.c
+--- libdvdread.orig/src/dvd_reader.c   2009-03-13 21:28:21.000000000 -0400
++++ libdvdread/src/dvd_reader.c        2009-04-24 01:35:43.000000000 -0400
+@@ -314,7 +314,7 @@
+   char *new_path;
+   /* If it doesn't start with "/dev/" or does start with "/dev/r" exit */
+-  if( !strncmp( path, "/dev/",  5 ) || strncmp( path, "/dev/r", 6 ) )
++  if( strncmp( path, "/dev/",  5 ) || !strncmp( path, "/dev/r", 6 ) )
+     return (char *) strdup( path );
+   /* Replace "/dev/" with "/dev/r" */
index 99b7092..3db333b 100644 (file)
@@ -1,5 +1,7 @@
 $(eval $(call import.MODULE.defs,LIBDVDREAD,libdvdread))
 $(eval $(call import.CONTRIB.defs,LIBDVDREAD))
 
-LIBDVDREAD.FETCH.url = http://download.m0k.org/handbrake/contrib/libdvdread-0.9.7.tar.gz
+LIBDVDREAD.FETCH.url = http://download.m0k.org/handbrake/contrib/libdvdread-svn1168.tar.gz
 LIBDVDREAD.EXTRACT.tarbase = libdvdread
+
+LIBDVDREAD.CONFIGURE.bootstrap = rm -fr aclocal.m4 autom4te.cache; autoreconf -fiv;
index 41eb765..71b3ac3 100644 (file)
@@ -2,13 +2,13 @@
 
 if MINGW
 HB_LIBS= \
-       -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -ldca -ldvdread \
+       -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -ldca -ldvdnav -ldvdread \
        -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate \
        -lx264 -lxvidcore -lmp4v2 -lswscale -ltheora -lfaad -lz \
        -lbz2 -liberty -lpthreadGC2
 else
 HB_LIBS= \
-       -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -ldca -ldvdread \
+       -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -ldca -ldvdnav -ldvdread \
        -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate \
        -lx264 -lxvidcore -lmp4v2 -lswscale -ltheora -lfaad -lz \
        -lbz2 -lpthread
index f8362a5..00229f1 100644 (file)
@@ -1233,6 +1233,10 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
        widget = GHB_WIDGET (ud->builder, "start_chapter");
        gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo->num_chapters);
+
+       widget = GHB_WIDGET (ud->builder, "angle");
+       gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
+       gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo->angle_count);
        ud->dont_clear_presets = FALSE;
 }
 
@@ -1951,6 +1955,17 @@ ghb_backend_events(signal_user_data_t *ud)
        ghb_track_status();
        ghb_get_status(&status);
        progress = GTK_PROGRESS_BAR(GHB_WIDGET (ud->builder, "progressbar"));
+       if (status.scan.state == GHB_STATE_IDLE && 
+               status.queue.state == GHB_STATE_IDLE)
+       {
+               static gboolean prev_dvdnav;
+               gboolean dvdnav = ghb_settings_get_boolean(ud->settings, "use_dvdnav");
+               if (dvdnav != prev_dvdnav)
+               {
+                       hb_dvd_set_dvdnav(dvdnav);
+                       prev_dvdnav = dvdnav;
+               }
+       }
        // First handle the status of title scans
        // Then handle the status of the queue
        if (status.scan.state & GHB_STATE_SCANNING)
index bd9d2bb..489ebbb 100644 (file)
     <property name="page_size">0</property>
     <property name="value">0</property>
   </object>
+  <object class="GtkAdjustment" id="adjustment27">
+    <property name="upper">10</property>
+    <property name="lower">1</property>
+    <property name="page_increment">1</property>
+    <property name="step_increment">1</property>
+    <property name="page_size">0</property>
+    <property name="value">1</property>
+  </object>
   <object class="GtkAdjustment" id="preview_progress_adj">
     <property name="upper">100</property>
     <property name="lower">0</property>
                                   </packing>
                                 </child>
                                 <child>
+                                  <object class="GtkAlignment" id="alignment47">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <property name="xalign">0</property>
+                                    <property name="xscale">0</property>
+                                    <property name="left_padding">16</property>
+                                    <child>
+                                      <object class="GtkHBox" id="hbox44">
+                                        <property name="visible">True</property>
+                                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                        <property name="spacing">7</property>
+                                        <child>
+                                          <object class="GtkLabel" id="angle_label">
+                                            <property name="visible">True</property>
+                                            <property name="label" translatable="yes">Angle:</property>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                            <property name="position">4</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkSpinButton" id="angle">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                            <property name="adjustment">adjustment27</property>
+                                            <signal name="value_changed" handler="setting_widget_changed_cb"/>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="position">5</property>
+                                          </packing>
+                                        </child>
+                                      </object>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="position">3</property>
+                                  </packing>
+                                </child>
+                                <child>
                                   <object class="GtkAlignment" id="alignment41">
                                     <property name="visible">True</property>
                                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                                   </object>
                                   <packing>
                                     <property name="expand">False</property>
-                                    <property name="position">3</property>
+                                    <property name="position">4</property>
                                   </packing>
                                 </child>
                               </object>
@@ -3404,6 +3456,21 @@ auto-generated destination name.</property>
                           </packing>
                         </child>
                         <child>
+                          <object class="GtkCheckButton" id="use_dvdnav">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="tooltip_text">Experimental dvdnav support.  
+Dvdnav can read some discs that dvdread can not.</property>
+                            <property name="label" translatable="yes">Use dvdnav (Experimental)</property>
+                            <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="pref_changed_cb"/>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">3</property>
+                          </packing>
+                        </child>
+                        <child>
                           <object class="GtkCheckButton" id="reduce_hd_preview">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
@@ -3416,7 +3483,7 @@ non-hidef screens.  </property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="position">3</property>
+                            <property name="position">4</property>
                           </packing>
                         </child>
                         <child>
@@ -3462,7 +3529,7 @@ increases scan duration.</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="position">4</property>
+                            <property name="position">5</property>
                           </packing>
                         </child>
 
@@ -3502,7 +3569,7 @@ in the Video settings tab.</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="position">5</property>
+                            <property name="position">6</property>
                           </packing>
                         </child>
                         <child>
@@ -3519,7 +3586,7 @@ location as the movie.</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="position">6</property>
+                            <property name="position">7</property>
                           </packing>
                         </child>
 
@@ -3557,7 +3624,7 @@ location as the movie.</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="position">7</property>
+                            <property name="position">8</property>
                           </packing>
                         </child>
 
@@ -3570,7 +3637,7 @@ location as the movie.</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="position">8</property>
+                            <property name="position">9</property>
                           </packing>
                         </child>
                         <child>
@@ -3582,7 +3649,7 @@ location as the movie.</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="position">9</property>
+                            <property name="position">10</property>
                           </packing>
                         </child>
                       </object>
index 8deac88..140ce0e 100644 (file)
@@ -2541,6 +2541,8 @@ ghb_get_title_info(ghb_title_info_t *tinfo, gint titleindex)
        tinfo->minutes = title->minutes;
        tinfo->seconds = title->seconds;
        tinfo->duration = title->duration;
+
+       tinfo->angle_count = title->angle_count;
        return TRUE;
 }
 
index b4f6977..2b27d53 100644 (file)
@@ -74,6 +74,7 @@ typedef struct
        gint minutes;
        gint seconds;
        gint64 duration;
+       gint angle_count;
 } ghb_title_info_t;
 
 typedef struct
index 986463e..f2bc8d3 100644 (file)
@@ -4,6 +4,8 @@
 <dict>
        <key>Initialization</key>
        <dict>
+               <key>angle</key>
+               <integer>1</integer>
                <key>anamorphic</key>
                <true />
                <key>autoscale</key>
                <string>1</string>
                <key>nocheckvquality</key>
                <false />
+               <key>use_dvdnav</key>
+               <false />
                <key>reduce_hd_preview</key>
                <true />
                <key>preview_count</key>
index 26bf0fb..6a6945f 100644 (file)
@@ -27,6 +27,9 @@ static dependency_t dep_map[] =
        {"title", "chapters_tab", "none", TRUE, FALSE},
        {"title", "start_chapter", "none", TRUE, FALSE},
        {"title", "end_chapter", "none", TRUE, FALSE},
+       {"title", "angle", "none", TRUE, FALSE},
+       {"use_dvdnav", "angle", "FALSE", TRUE, TRUE},
+       {"use_dvdnav", "angle_label", "FALSE", TRUE, TRUE},
        {"vquality_type_bitrate", "VideoAvgBitrate", "TRUE", FALSE, FALSE},
        {"vquality_type_target", "VideoTargetSize", "TRUE", FALSE, FALSE},
        {"vquality_type_constant", "VideoQualitySlider", "TRUE", FALSE, FALSE},
index 5a6320a..73ebfda 100644 (file)
@@ -245,6 +245,7 @@ struct hb_job_s
     int subtitle_force;
     char * native_language;
 
+    int             angle;              // dvd angle to encode
     int             frame_to_stop;       // declare eof when we hit this frame
     int64_t         pts_to_stop;        // declare eof when we pass this pts in
                                         //  the time-linearized input stream
@@ -481,6 +482,7 @@ struct hb_title_s
     int         block_start;
     int         block_end;
     int         block_count;
+    int         angle_count;
 
     /* Visual-friendly duration */
     int         hours;
index 479157e..8bc6194 100644 (file)
@@ -6,47 +6,55 @@
 
 #include "hb.h"
 #include "lang.h"
+#include "dvd.h"
 
 #include "dvdread/ifo_read.h"
 #include "dvdread/nav_read.h"
 
-struct hb_dvd_s
+static hb_dvd_t    * hb_dvdread_init( char * path );
+static void          hb_dvdread_close( hb_dvd_t ** _d );
+static char        * hb_dvdread_name( char * path );
+static int           hb_dvdread_title_count( hb_dvd_t * d );
+static hb_title_t  * hb_dvdread_title_scan( hb_dvd_t * d, int t );
+static int           hb_dvdread_start( hb_dvd_t * d, int title, int chapter );
+static void          hb_dvdread_stop( hb_dvd_t * d );
+static int           hb_dvdread_seek( hb_dvd_t * d, float f );
+static int           hb_dvdread_read( hb_dvd_t * d, hb_buffer_t * b );
+static int           hb_dvdread_chapter( hb_dvd_t * d );
+static int           hb_dvdread_angle_count( hb_dvd_t * d );
+static void          hb_dvdread_set_angle( hb_dvd_t * d, int angle );
+
+hb_dvd_func_t hb_dvdread_func =
 {
-    char         * path;
-
-    dvd_reader_t * reader;
-    ifo_handle_t * vmg;
-
-    int            vts;
-    int            ttn;
-    ifo_handle_t * ifo;
-    dvd_file_t   * file;
-
-    pgc_t        * pgc;
-    int            cell_start;
-    int            cell_end;
-    int            title_start;
-    int            title_end;
-    int            title_block_count;
-    int            cell_cur;
-    int            cell_next;
-    int            cell_overlap;
-    int            block;
-    int            pack_len;
-    int            next_vobu;
-    int            in_cell;
-    int            in_sync;
-    uint16_t       cur_vob_id;
-    uint8_t        cur_cell_id;
+    hb_dvdread_init,
+    hb_dvdread_close,
+    hb_dvdread_name,
+    hb_dvdread_title_count,
+    hb_dvdread_title_scan,
+    hb_dvdread_start,
+    hb_dvdread_stop,
+    hb_dvdread_seek,
+    hb_dvdread_read,
+    hb_dvdread_chapter,
+    hb_dvdread_angle_count,
+    hb_dvdread_set_angle
 };
 
+static hb_dvd_func_t *dvd_methods = &hb_dvdread_func;
+
 /***********************************************************************
  * Local prototypes
  **********************************************************************/
-static void FindNextCell( hb_dvd_t * );
+static void FindNextCell( hb_dvdread_t * );
 static int  dvdtime2msec( dvd_time_t * );
+static int hb_dvdread_is_break( hb_dvdread_t * d );
 
-char * hb_dvd_name( char * path )
+hb_dvd_func_t * hb_dvdread_methods( void )
+{
+    return &hb_dvdread_func;
+}
+
+static char * hb_dvdread_name( char * path )
 {
     static char name[1024];
     unsigned char unused[1024];
@@ -70,15 +78,17 @@ char * hb_dvd_name( char * path )
 }
 
 /***********************************************************************
- * hb_dvd_init
+ * hb_dvdread_init
  ***********************************************************************
  *
  **********************************************************************/
-hb_dvd_t * hb_dvd_init( char * path )
+hb_dvd_t * hb_dvdread_init( char * path )
 {
-    hb_dvd_t * d;
+    hb_dvd_t * e;
+    hb_dvdread_t * d;
 
-    d = calloc( sizeof( hb_dvd_t ), 1 );
+    e = calloc( sizeof( hb_dvd_t ), 1 );
+    d = &(e->dvdread);
 
     /* Open device */
     if( !( d->reader = DVDOpen( path ) ) )
@@ -99,7 +109,7 @@ hb_dvd_t * hb_dvd_init( char * path )
 
     d->path = strdup( path );
 
-    return d;
+    return e;
 
 fail:
     if( d->vmg )    ifoClose( d->vmg );
@@ -109,19 +119,21 @@ fail:
 }
 
 /***********************************************************************
- * hb_dvd_title_count
+ * hb_dvdread_title_count
  **********************************************************************/
-int hb_dvd_title_count( hb_dvd_t * d )
+static int hb_dvdread_title_count( hb_dvd_t * e )
 {
+    hb_dvdread_t *d = &(e->dvdread);
     return d->vmg->tt_srpt->nr_of_srpts;
 }
 
 /***********************************************************************
- * hb_dvd_title_scan
+ * hb_dvdread_title_scan
  **********************************************************************/
-hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
+static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
 {
 
+    hb_dvdread_t *d = &(e->dvdread);
     hb_title_t   * title;
     ifo_handle_t * vts = NULL;
     int            pgc_id, pgn, i;
@@ -198,7 +210,7 @@ hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
 
     if( global_verbosity_level == 3 )
     {
-        ifoPrint( d->reader, title->vts );
+        ifo_print( d->reader, title->vts );
     }
 
     /* Position of the title in the VTS */
@@ -635,12 +647,13 @@ cleanup:
 }
 
 /***********************************************************************
- * hb_dvd_start
+ * hb_dvdread_start
  ***********************************************************************
  * Title and chapter start at 1
  **********************************************************************/
-int hb_dvd_start( hb_dvd_t * d, int title, int chapter )
+static int hb_dvdread_start( hb_dvd_t * e, int title, int chapter )
 {
+    hb_dvdread_t *d = &(e->dvdread);
     int pgc_id, pgn;
     int i;
 
@@ -696,12 +709,13 @@ int hb_dvd_start( hb_dvd_t * d, int title, int chapter )
 }
 
 /***********************************************************************
- * hb_dvd_stop
+ * hb_dvdread_stop
  ***********************************************************************
  *
  **********************************************************************/
-void hb_dvd_stop( hb_dvd_t * d )
+static void hb_dvdread_stop( hb_dvd_t * e )
 {
+    hb_dvdread_t *d = &(e->dvdread);
     if( d->ifo )
     {
         ifoClose( d->ifo );
@@ -715,12 +729,13 @@ void hb_dvd_stop( hb_dvd_t * d )
 }
 
 /***********************************************************************
- * hb_dvd_seek
+ * hb_dvdread_seek
  ***********************************************************************
  *
  **********************************************************************/
-int hb_dvd_seek( hb_dvd_t * d, float f )
+static int hb_dvdread_seek( hb_dvd_t * e, float f )
 {
+    hb_dvdread_t *d = &(e->dvdread);
     int count, sizeCell;
     int i;
 
@@ -737,7 +752,7 @@ int hb_dvd_seek( hb_dvd_t * d, float f )
             d->cur_cell_id = 0;
             FindNextCell( d );
 
-            /* Now let hb_dvd_read find the next VOBU */
+            /* Now let hb_dvdread_read find the next VOBU */
             d->next_vobu = d->pgc->cell_playback[i].first_sector + count;
             d->pack_len  = 0;
             break;
@@ -805,12 +820,13 @@ int is_nav_pack( unsigned char *buf )
 
 
 /***********************************************************************
- * hb_dvd_read
+ * hb_dvdread_read
  ***********************************************************************
  *
  **********************************************************************/
-int hb_dvd_read( hb_dvd_t * d, hb_buffer_t * b )
+static int hb_dvdread_read( hb_dvd_t * e, hb_buffer_t * b )
 {
+    hb_dvdread_t *d = &(e->dvdread);
  top:
     if( !d->pack_len )
     {
@@ -1012,7 +1028,7 @@ int hb_dvd_read( hb_dvd_t * d, hb_buffer_t * b )
 
                 if( d->cell_overlap )
                 {
-                    b->new_chap = hb_dvd_is_break( d );
+                    b->new_chap = hb_dvdread_is_break( d );
                     d->cell_overlap = 0;
                 }
             }
@@ -1056,13 +1072,14 @@ int hb_dvd_read( hb_dvd_t * d, hb_buffer_t * b )
 }
 
 /***********************************************************************
- * hb_dvd_chapter
+ * hb_dvdread_chapter
  ***********************************************************************
  * Returns in which chapter the next block to be read is.
  * Chapter numbers start at 1.
  **********************************************************************/
-int hb_dvd_chapter( hb_dvd_t * d )
+static int hb_dvdread_chapter( hb_dvd_t * e )
 {
+    hb_dvdread_t *d = &(e->dvdread);
     int     i;
     int     pgc_id, pgn;
     int     nr_of_ptts = d->ifo->vts_ptt_srpt->title[d->ttn-1].nr_of_ptts;
@@ -1090,15 +1107,15 @@ int hb_dvd_chapter( hb_dvd_t * d )
 }
 
 /***********************************************************************
- * hb_dvd_is_break
+ * hb_dvdread_is_break
  ***********************************************************************
  * Returns chapter number if the current block is a new chapter start
  **********************************************************************/
-int hb_dvd_is_break( hb_dvd_t * d )
+static int hb_dvdread_is_break( hb_dvdread_t * d )
 {
     int     i;
     int     pgc_id, pgn;
-       int     nr_of_ptts = d->ifo->vts_ptt_srpt->title[d->ttn-1].nr_of_ptts;
+    int     nr_of_ptts = d->ifo->vts_ptt_srpt->title[d->ttn-1].nr_of_ptts;
     pgc_t * pgc;
     int     cell;
 
@@ -1126,13 +1143,13 @@ int hb_dvd_is_break( hb_dvd_t * d )
 }
 
 /***********************************************************************
- * hb_dvd_close
+ * hb_dvdread_close
  ***********************************************************************
  * Closes and frees everything
  **********************************************************************/
-void hb_dvd_close( hb_dvd_t ** _d )
+static void hb_dvdread_close( hb_dvd_t ** _d )
 {
-    hb_dvd_t * d = *_d;
+    hb_dvdread_t * d = &((*_d)->dvdread);
 
     if( d->vmg )
     {
@@ -1148,12 +1165,32 @@ void hb_dvd_close( hb_dvd_t ** _d )
 }
 
 /***********************************************************************
+ * hb_dvdread_angle_count
+ ***********************************************************************
+ * Returns the number of angles supported.  We do not support angles
+ * with dvdread
+ **********************************************************************/
+static int hb_dvdread_angle_count( hb_dvd_t * d )
+{
+    return 1;
+}
+
+/***********************************************************************
+ * hb_dvdread_set_angle
+ ***********************************************************************
+ * Sets the angle to read.  Not supported with dvdread
+ **********************************************************************/
+static void hb_dvdread_set_angle( hb_dvd_t * d, int angle )
+{
+}
+
+/***********************************************************************
  * FindNextCell
  ***********************************************************************
  * Assumes pgc and cell_cur are correctly set, and sets cell_next to the
  * cell to be read when we will be done with cell_cur.
  **********************************************************************/
-static void FindNextCell( hb_dvd_t * d )
+static void FindNextCell( hb_dvdread_t * d )
 {
     int i = 0;
 
@@ -1199,3 +1236,74 @@ static int dvdtime2msec(dvd_time_t * dt)
 
     return ms;
 }
+
+char * hb_dvd_name( char * path )
+{
+    return dvd_methods->name(path);
+}
+
+hb_dvd_t * hb_dvd_init( char * path )
+{
+    return dvd_methods->init(path);
+}
+
+int hb_dvd_title_count( hb_dvd_t * d )
+{
+    return dvd_methods->title_count(d);
+}
+
+hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
+{
+    return dvd_methods->title_scan(d, t);
+}
+
+int hb_dvd_start( hb_dvd_t * d, int title, int chapter )
+{
+    return dvd_methods->start(d, title, chapter);
+}
+
+void hb_dvd_stop( hb_dvd_t * d )
+{
+    dvd_methods->stop(d);
+}
+
+int hb_dvd_seek( hb_dvd_t * d, float f )
+{
+    return dvd_methods->seek(d, f);
+}
+
+int hb_dvd_read( hb_dvd_t * d, hb_buffer_t * b )
+{
+    return dvd_methods->read(d, b);
+}
+
+int hb_dvd_chapter( hb_dvd_t * d )
+{
+    return dvd_methods->chapter(d);
+}
+
+void hb_dvd_close( hb_dvd_t ** _d )
+{
+    dvd_methods->close(_d);
+}
+
+int hb_dvd_angle_count( hb_dvd_t * d )
+{
+    return dvd_methods->angle_count(d);
+}
+
+void hb_dvd_set_angle( hb_dvd_t * d, int angle )
+{
+    dvd_methods->set_angle(d, angle);
+}
+
+// hb_dvd_set_dvdnav must only be called when no dvd source is open
+// it rips the rug out from under things so be careful
+void hb_dvd_set_dvdnav( int enable )
+{
+    if (enable)
+        dvd_methods = hb_dvdnav_methods();
+    else
+        dvd_methods = hb_dvdread_methods();
+}
+
diff --git a/libhb/dvd.h b/libhb/dvd.h
new file mode 100644 (file)
index 0000000..8f89a82
--- /dev/null
@@ -0,0 +1,88 @@
+/* $Id: dvd.h,v 1.1 2004/08/02 07:19:05 stebbins Exp $
+
+   This file is part of the HandBrake source code.
+   Homepage: <http://handbrake.fr/>.
+   It may be used under the terms of the GNU General Public License. */
+
+#ifndef HB_DVD_H
+#define HB_DVD_H
+
+#include "dvdnav/dvdnav.h"
+#include "dvdread/ifo_read.h"
+#include "dvdread/nav_read.h"
+
+struct hb_dvdread_s
+{
+    char         * path;
+
+    dvd_reader_t * reader;
+    ifo_handle_t * vmg;
+
+    int            vts;
+    int            ttn;
+    ifo_handle_t * ifo;
+    dvd_file_t   * file;
+
+    pgc_t        * pgc;
+    int            cell_start;
+    int            cell_end;
+    int            title_start;
+    int            title_end;
+    int            title_block_count;
+    int            cell_cur;
+    int            cell_next;
+    int            cell_overlap;
+    int            block;
+    int            pack_len;
+    int            next_vobu;
+    int            in_cell;
+    int            in_sync;
+    uint16_t       cur_vob_id;
+    uint8_t        cur_cell_id;
+};
+
+struct hb_dvdnav_s
+{
+    char         * path;
+
+    dvdnav_t     * dvdnav;
+    dvd_reader_t * reader;
+    ifo_handle_t * vmg;
+    int            title;
+       int            title_block_count;
+    int            chapter;
+};
+
+typedef struct hb_dvdnav_s hb_dvdnav_t;
+typedef struct hb_dvdread_s hb_dvdread_t;
+
+union hb_dvd_s
+{
+       hb_dvdread_t dvdread;
+       hb_dvdnav_t  dvdnav;
+};
+
+
+struct hb_dvd_func_s
+{
+       hb_dvd_t *    (* init)        ( char * );
+       void          (* close)       ( hb_dvd_t ** );
+       char        * (* name)        ( char * );
+       int           (* title_count) ( hb_dvd_t * );
+       hb_title_t  * (* title_scan)  ( hb_dvd_t *, int );
+       int           (* start)       ( hb_dvd_t *, int, int );
+       void          (* stop)        ( hb_dvd_t * );
+       int           (* seek)        ( hb_dvd_t *, float );
+       int           (* read)        ( hb_dvd_t *, hb_buffer_t * );
+       int           (* chapter)     ( hb_dvd_t * );
+       int           (* angle_count) ( hb_dvd_t * );
+       void          (* set_angle)   ( hb_dvd_t *, int );
+};
+typedef struct hb_dvd_func_s hb_dvd_func_t;
+
+hb_dvd_func_t * hb_dvdnav_methods( void );
+hb_dvd_func_t * hb_dvdread_methods( void );
+
+#endif // HB_DVD_H
+
+
diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c
new file mode 100644 (file)
index 0000000..c46d7fa
--- /dev/null
@@ -0,0 +1,1097 @@
+/* $Id: dvd.c,v 1.12 2005/11/25 15:05:25 titer Exp $
+
+   This file is part of the HandBrake source code.
+   Homepage: <http://handbrake.fr/>.
+   It may be used under the terms of the GNU General Public License. */
+
+#include "hb.h"
+#include "lang.h"
+#include "dvd.h"
+
+#include "dvdnav/dvdnav.h"
+#include "dvdread/ifo_read.h"
+#include "dvdread/nav_read.h"
+
+#define DVD_READ_CACHE 1
+
+static char        * hb_dvdnav_name( char * path );
+static hb_dvd_t    * hb_dvdnav_init( char * path );
+static int           hb_dvdnav_title_count( hb_dvd_t * d );
+static hb_title_t  * hb_dvdnav_title_scan( hb_dvd_t * d, int t );
+static int           hb_dvdnav_start( hb_dvd_t * d, int title, int chapter );
+static void          hb_dvdnav_stop( hb_dvd_t * d );
+static int           hb_dvdnav_seek( hb_dvd_t * d, float f );
+static int           hb_dvdnav_read( hb_dvd_t * d, hb_buffer_t * b );
+static int           hb_dvdnav_chapter( hb_dvd_t * d );
+static void          hb_dvdnav_close( hb_dvd_t ** _d );
+static int           hb_dvdnav_angle_count( hb_dvd_t * d );
+static void          hb_dvdnav_set_angle( hb_dvd_t * e, int angle );
+
+hb_dvd_func_t hb_dvdnav_func =
+{
+    hb_dvdnav_init,
+    hb_dvdnav_close,
+    hb_dvdnav_name,
+    hb_dvdnav_title_count,
+    hb_dvdnav_title_scan,
+    hb_dvdnav_start,
+    hb_dvdnav_stop,
+    hb_dvdnav_seek,
+    hb_dvdnav_read,
+    hb_dvdnav_chapter,
+    hb_dvdnav_angle_count,
+    hb_dvdnav_set_angle
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static int FindNextCell( pgc_t *pgc, int cell_cur );
+static int dvdtime2msec( dvd_time_t * );
+//static int hb_dvdnav_is_break( hb_dvdnav_t * d );
+
+hb_dvd_func_t * hb_dvdnav_methods( void )
+{
+    return &hb_dvdnav_func;
+}
+
+static char * hb_dvdnav_name( char * path )
+{
+    static char name[1024];
+    unsigned char unused[1024];
+    dvd_reader_t * reader;
+
+    reader = DVDOpen( path );
+    if( !reader )
+    {
+        return NULL;
+    }
+
+    if( DVDUDFVolumeInfo( reader, name, sizeof( name ),
+                          unused, sizeof( unused ) ) )
+    {
+        DVDClose( reader );
+        return NULL;
+    }
+
+    DVDClose( reader );
+    return name;
+}
+
+/***********************************************************************
+ * hb_dvdnav_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+static hb_dvd_t * hb_dvdnav_init( char * path )
+{
+    hb_dvd_t * e;
+    hb_dvdnav_t * d;
+
+    e = calloc( sizeof( hb_dvd_t ), 1 );
+    d = &(e->dvdnav);
+
+    /* Open device */
+    if( dvdnav_open(&d->dvdnav, path) != DVDNAV_STATUS_OK )
+    {
+        /*
+         * Not an error, may be a stream - which we'll try in a moment.
+         */
+        hb_log( "dvd: not a dvd - trying as a stream/file instead" );
+        goto fail;
+    }
+
+    if (dvdnav_set_readahead_flag(d->dvdnav, DVD_READ_CACHE) !=
+        DVDNAV_STATUS_OK)
+    {
+        hb_error("Error: dvdnav_set_readahead_flag: %s\n",
+                 dvdnav_err_to_string(d->dvdnav));
+        goto fail;
+    }
+
+    /*
+     ** set the PGC positioning flag to have position information
+     ** relatively to the whole feature instead of just relatively to the
+     ** current chapter 
+     **/
+    if (dvdnav_set_PGC_positioning_flag(d->dvdnav, 1) != DVDNAV_STATUS_OK)
+    {
+        hb_error("Error: dvdnav_set_PGC_positioning_flag: %s\n",
+                 dvdnav_err_to_string(d->dvdnav));
+        goto fail;
+    }
+
+    /* Open device */
+    if( !( d->reader = DVDOpen( path ) ) )
+    {
+        /*
+         * Not an error, may be a stream - which we'll try in a moment.
+         */
+        hb_log( "dvd: not a dvd - trying as a stream/file instead" );
+        goto fail;
+    }
+
+    /* Open main IFO */
+    if( !( d->vmg = ifoOpen( d->reader, 0 ) ) )
+    {
+        hb_error( "dvd: ifoOpen failed" );
+        goto fail;
+    }
+
+    d->path = strdup( path );
+
+    return e;
+
+fail:
+    if( d->dvdnav ) dvdnav_close( d->dvdnav );
+    if( d->vmg )    ifoClose( d->vmg );
+    if( d->reader ) DVDClose( d->reader );
+    free( e );
+    return NULL;
+}
+
+/***********************************************************************
+ * hb_dvdnav_title_count
+ **********************************************************************/
+static int hb_dvdnav_title_count( hb_dvd_t * e )
+{
+    int titles = 0;
+    hb_dvdnav_t * d = &(e->dvdnav);
+
+    dvdnav_get_number_of_titles(d->dvdnav, &titles);
+    return titles;
+}
+
+/***********************************************************************
+ * hb_dvdnav_title_scan
+ **********************************************************************/
+static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t )
+{
+
+    hb_dvdnav_t * d = &(e->dvdnav);
+    hb_title_t   * title;
+    ifo_handle_t * vts = NULL;
+    int            pgc_id, pgn, i;
+    pgc_t        * pgc;
+    int            cell_cur;
+    hb_chapter_t * chapter;
+    int            c;
+    uint64_t       duration;
+    float          duration_correction;
+    const char   * name;
+
+    hb_log( "scan: scanning title %d", t );
+
+    title = hb_title_init( d->path, t );
+    if (dvdnav_get_title_string(d->dvdnav, &name) == DVDNAV_STATUS_OK)
+    {
+        strncpy( title->name, name, sizeof( title->name ) );
+    }
+    else
+    {
+        char * p_cur, * p_last = d->path;
+        for( p_cur = d->path; *p_cur; p_cur++ )
+        {
+            if( p_cur[0] == '/' && p_cur[1] )
+            {
+                p_last = &p_cur[1];
+            }
+        }
+        snprintf( title->name, sizeof( title->name ), "%s", p_last );
+    }
+
+    /* VTS which our title is in */
+    title->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
+
+    if ( !title->vts )
+    {
+        /* A VTS of 0 means the title wasn't found in the title set */
+        hb_error("Invalid VTS (title set) number: %i", title->vts);
+        goto fail;
+    }
+
+    hb_log( "scan: opening IFO for VTS %d", title->vts );
+    if( !( vts = ifoOpen( d->reader, title->vts ) ) )
+    {
+        hb_error( "scan: ifoOpen failed" );
+        goto fail;
+    }
+
+    /* ignore titles with bogus cell addresses so we don't abort later
+     ** in libdvdread. */
+    for ( i = 0; i < vts->vts_c_adt->nr_of_vobs; ++i)
+    {
+        if( (vts->vts_c_adt->cell_adr_table[i].start_sector & 0xffffff ) ==
+            0xffffff )
+        {
+            hb_error( "scan: cell_adr_table[%d].start_sector invalid (0x%x) "
+                      "- skipping title", i,
+                      vts->vts_c_adt->cell_adr_table[i].start_sector );
+            goto fail;
+        }
+        if( (vts->vts_c_adt->cell_adr_table[i].last_sector & 0xffffff ) ==
+            0xffffff )
+        {
+            hb_error( "scan: cell_adr_table[%d].last_sector invalid (0x%x) "
+                      "- skipping title", i,
+                      vts->vts_c_adt->cell_adr_table[i].last_sector );
+            goto fail;
+        }
+        if( vts->vts_c_adt->cell_adr_table[i].start_sector >=
+            vts->vts_c_adt->cell_adr_table[i].last_sector )
+        {
+            hb_error( "scan: cell_adr_table[%d].start_sector (0x%x) "
+                      "is not before last_sector (0x%x) - skipping title", i,
+                      vts->vts_c_adt->cell_adr_table[i].start_sector,
+                      vts->vts_c_adt->cell_adr_table[i].last_sector );
+            goto fail;
+        }
+    }
+
+    if( global_verbosity_level == 3 )
+    {
+        ifo_print( d->reader, title->vts );
+    }
+
+    /* Position of the title in the VTS */
+    title->ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
+    if ( title->ttn < 1 || title->ttn > vts->vts_ptt_srpt->nr_of_srpts )
+    {
+        hb_error( "invalid VTS PTT offset %d for title %d, skipping", title->ttn, t );
+        goto fail;
+    }
+
+
+    /* Get pgc */
+    pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgcn;
+    if ( pgc_id < 1 || pgc_id > vts->vts_pgcit->nr_of_pgci_srp )
+    {
+        hb_error( "invalid PGC ID %d for title %d, skipping", pgc_id, t );
+        goto fail;
+    }
+    pgn    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgn;
+    pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+
+    hb_log("pgc_id: %d, pgn: %d: pgc: 0x%x", pgc_id, pgn, pgc);
+
+    if( !pgc )
+    {
+        hb_error( "scan: pgc not valid, skipping" );
+        goto fail;
+    }
+
+    if( pgn <= 0 || pgn > 99 )
+    {
+        hb_error( "scan: pgn %d not valid, skipping", pgn );
+        goto fail;
+    }
+
+    /* Start cell */
+    title->cell_start  = pgc->program_map[pgn-1] - 1;
+    title->block_start = pgc->cell_playback[title->cell_start].first_sector;
+
+    /* End cell */
+    title->cell_end  = pgc->nr_of_cells - 1;
+    title->block_end = pgc->cell_playback[title->cell_end].last_sector;
+
+    /* Block count */
+    title->block_count = 0;
+    cell_cur = title->cell_start;
+    while( cell_cur <= title->cell_end )
+    {
+#define cp pgc->cell_playback[cell_cur]
+        title->block_count += cp.last_sector + 1 - cp.first_sector;
+#undef cp
+        cell_cur = FindNextCell( pgc, cell_cur );
+    }
+
+    hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%d->%d, "
+            "%d blocks", title->vts, title->ttn, title->cell_start,
+            title->cell_end, title->block_start, title->block_end,
+            title->block_count );
+
+    /* Get duration */
+    title->duration = 90LL * dvdtime2msec( &pgc->playback_time );
+    title->hours    = title->duration / 90000 / 3600;
+    title->minutes  = ( ( title->duration / 90000 ) % 3600 ) / 60;
+    title->seconds  = ( title->duration / 90000 ) % 60;
+    hb_log( "scan: duration is %02d:%02d:%02d (%lld ms)",
+            title->hours, title->minutes, title->seconds,
+            title->duration / 90 );
+
+    /* ignore titles under 10 seconds because they're often stills or
+     * clips with no audio & our preview code doesn't currently handle
+     * either of these. */
+    if( title->duration < 900000LL )
+    {
+        hb_log( "scan: ignoring title (too short)" );
+        goto fail;
+    }
+
+    /* Detect languages */
+    for( i = 0; i < vts->vtsi_mat->nr_of_vts_audio_streams; i++ )
+    {
+        hb_audio_t * audio, * audio_tmp;
+        int          audio_format, lang_code, audio_control,
+                     position, j;
+        iso639_lang_t * lang;
+        int lang_extension = 0;
+
+        hb_log( "scan: checking audio %d", i + 1 );
+
+        audio = calloc( sizeof( hb_audio_t ), 1 );
+
+        audio_format  = vts->vtsi_mat->vts_audio_attr[i].audio_format;
+        lang_code     = vts->vtsi_mat->vts_audio_attr[i].lang_code;
+        lang_extension = vts->vtsi_mat->vts_audio_attr[i].code_extension;
+        audio_control =
+            vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i];
+
+        if( !( audio_control & 0x8000 ) )
+        {
+            hb_log( "scan: audio channel is not active" );
+            free( audio );
+            continue;
+        }
+
+        position = ( audio_control & 0x7F00 ) >> 8;
+
+        switch( audio_format )
+        {
+            case 0x00:
+                audio->id    = ( ( 0x80 + position ) << 8 ) | 0xbd;
+                audio->config.in.codec = HB_ACODEC_AC3;
+                break;
+
+            case 0x02:
+            case 0x03:
+                audio->id    = 0xc0 + position;
+                audio->config.in.codec = HB_ACODEC_MPGA;
+                break;
+
+            case 0x04:
+                audio->id    = ( ( 0xa0 + position ) << 8 ) | 0xbd;
+                audio->config.in.codec = HB_ACODEC_LPCM;
+                break;
+
+            case 0x06:
+                audio->id    = ( ( 0x88 + position ) << 8 ) | 0xbd;
+                audio->config.in.codec = HB_ACODEC_DCA;
+                break;
+
+            default:
+                audio->id    = 0;
+                audio->config.in.codec = 0;
+                hb_log( "scan: unknown audio codec (%x)",
+                        audio_format );
+                break;
+        }
+        if( !audio->id )
+        {
+            continue;
+        }
+
+        /* Check for duplicate tracks */
+        audio_tmp = NULL;
+        for( j = 0; j < hb_list_count( title->list_audio ); j++ )
+        {
+            audio_tmp = hb_list_item( title->list_audio, j );
+            if( audio->id == audio_tmp->id )
+            {
+                break;
+            }
+            audio_tmp = NULL;
+        }
+        if( audio_tmp )
+        {
+            hb_log( "scan: duplicate audio track" );
+            free( audio );
+            continue;
+        }
+
+        audio->config.lang.type = lang_extension;
+
+        lang = lang_for_code( vts->vtsi_mat->vts_audio_attr[i].lang_code );
+
+        snprintf( audio->config.lang.description, sizeof( audio->config.lang.description ), "%s (%s)",
+            strlen(lang->native_name) ? lang->native_name : lang->eng_name,
+            audio->config.in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->config.in.codec ==
+                HB_ACODEC_DCA ? "DTS" : ( audio->config.in.codec ==
+                HB_ACODEC_MPGA ? "MPEG" : "LPCM" ) ) );
+        snprintf( audio->config.lang.simple, sizeof( audio->config.lang.simple ), "%s",
+                  strlen(lang->native_name) ? lang->native_name : lang->eng_name );
+        snprintf( audio->config.lang.iso639_2, sizeof( audio->config.lang.iso639_2 ), "%s",
+                  lang->iso639_2);
+
+        switch( lang_extension )
+        {
+        case 0:
+        case 1:
+            break;
+        case 2:
+            strcat( audio->config.lang.description, " (Visually Impaired)" );
+            break;
+        case 3:
+            strcat( audio->config.lang.description, " (Director's Commentary 1)" );
+            break;
+        case 4:
+            strcat( audio->config.lang.description, " (Director's Commentary 2)" );
+            break;
+        default:
+            break;
+        }
+
+        hb_log( "scan: id=%x, lang=%s, 3cc=%s ext=%i", audio->id,
+                audio->config.lang.description, audio->config.lang.iso639_2,
+                lang_extension );
+
+        audio->config.in.track = i;
+        hb_list_add( title->list_audio, audio );
+    }
+
+    if( !hb_list_count( title->list_audio ) )
+    {
+        hb_log( "scan: ignoring title (no audio track)" );
+        goto fail;
+    }
+
+    memcpy( title->palette,
+            vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->palette,
+            16 * sizeof( uint32_t ) );
+
+    /* Check for subtitles */
+    for( i = 0; i < vts->vtsi_mat->nr_of_vts_subp_streams; i++ )
+    {
+        hb_subtitle_t * subtitle;
+        int spu_control;
+        int position;
+        iso639_lang_t * lang;
+        int lang_extension = 0;
+
+        hb_log( "scan: checking subtitle %d", i + 1 );
+
+        spu_control =
+            vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->subp_control[i];
+
+        if( !( spu_control & 0x80000000 ) )
+        {
+            hb_log( "scan: subtitle channel is not active" );
+            continue;
+        }
+
+        if( vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
+        {
+            switch( vts->vtsi_mat->vts_video_attr.permitted_df )
+            {
+                case 1:
+                    position = spu_control & 0xFF;
+                    break;
+                case 2:
+                    position = ( spu_control >> 8 ) & 0xFF;
+                    break;
+                default:
+                    position = ( spu_control >> 16 ) & 0xFF;
+            }
+        }
+        else
+        {
+            position = ( spu_control >> 24 ) & 0x7F;
+        }
+
+        lang_extension = vts->vtsi_mat->vts_subp_attr[i].code_extension;
+
+        lang = lang_for_code( vts->vtsi_mat->vts_subp_attr[i].lang_code );
+
+        subtitle = calloc( sizeof( hb_subtitle_t ), 1 );
+        subtitle->id = ( ( 0x20 + position ) << 8 ) | 0xbd;
+        snprintf( subtitle->lang, sizeof( subtitle->lang ), "%s",
+             strlen(lang->native_name) ? lang->native_name : lang->eng_name);
+        snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "%s",
+                  lang->iso639_2);
+
+        subtitle->type = lang_extension;
+
+        switch( lang_extension )
+        {  
+        case 0:
+            break;
+        case 1:
+            break;
+        case 2:
+            strcat( subtitle->lang, " (Caption with bigger size character)");
+            break;
+        case 3: 
+            strcat( subtitle->lang, " (Caption for Children)");
+            break;
+        case 4:
+            break;
+        case 5:
+            strcat( subtitle->lang, " (Closed Caption)");
+            break;
+        case 6:
+            strcat( subtitle->lang, " (Closed Caption with bigger size character)");
+            break;
+        case 7:
+            strcat( subtitle->lang, " (Closed Caption for Children)");
+            break;
+        case 8:
+            break;
+        case 9:
+            strcat( subtitle->lang, " (Forced Caption)");
+            break;
+        case 10:
+            break;
+        case 11:
+            break;
+        case 12:
+            break;
+        case 13:
+            strcat( subtitle->lang, " (Director's Commentary)");
+            break;
+        case 14:
+            strcat( subtitle->lang, " (Director's Commentary with bigger size character)");
+            break;
+        case 15:
+            strcat( subtitle->lang, " (Director's Commentary for Children)");
+        default:
+            break;
+        }
+
+        hb_log( "scan: id=%x, lang=%s, 3cc=%s", subtitle->id,
+                subtitle->lang, subtitle->iso639_2 );
+
+        hb_list_add( title->list_subtitle, subtitle );
+    }
+
+    /* Chapters */
+    hb_log( "scan: title %d has %d chapters", t,
+            vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts );
+    for( i = 0, c = 1;
+         i < vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts; i++ )
+    {
+        int pgc_id_next, pgn_next;
+        pgc_t * pgc_next;
+
+        chapter = calloc( sizeof( hb_chapter_t ), 1 );
+        /* remember the on-disc chapter number */
+        chapter->index = i + 1;
+
+        pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgcn;
+        pgn    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgn;
+        pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+
+        /* Start cell */
+        chapter->cell_start  = pgc->program_map[pgn-1] - 1;
+        chapter->block_start =
+            pgc->cell_playback[chapter->cell_start].first_sector;
+
+        /* End cell */
+        if( i != vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts - 1 )
+        {
+            /* The cell before the starting cell of the next chapter,
+               or... */
+            pgc_id_next = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i+1].pgcn;
+            pgn_next    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i+1].pgn;
+            pgc_next    = vts->vts_pgcit->pgci_srp[pgc_id_next-1].pgc;
+            chapter->cell_end = pgc_next->program_map[pgn_next-1] - 2;
+            if( chapter->cell_end < 0 )
+            {
+                /* Huh? */
+                free( chapter );
+                continue;
+            }
+        }
+        else
+        {
+            /* ... the last cell of the title */
+            chapter->cell_end = title->cell_end;
+        }
+        chapter->block_end =
+            pgc->cell_playback[chapter->cell_end].last_sector;
+
+        /* Block count, duration */
+        pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgcn;
+        pgn    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgn;
+        pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+        chapter->block_count = 0;
+        chapter->duration = 0;
+
+        cell_cur = chapter->cell_start;
+        while( cell_cur <= chapter->cell_end )
+        {
+#define cp pgc->cell_playback[cell_cur]
+            chapter->block_count += cp.last_sector + 1 - cp.first_sector;
+            chapter->duration += 90LL * dvdtime2msec( &cp.playback_time );
+#undef cp
+            cell_cur = FindNextCell( pgc, cell_cur );
+        }
+        hb_list_add( title->list_chapter, chapter );
+        c++;
+    }
+
+    /* The durations we get for chapters aren't precise. Scale them so
+       the total matches the title duration */
+    duration = 0;
+    for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
+    {
+        chapter = hb_list_item( title->list_chapter, i );
+        duration += chapter->duration;
+    }
+    duration_correction = (float) title->duration / (float) duration;
+    for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
+    {
+        int seconds;
+        chapter            = hb_list_item( title->list_chapter, i );
+        chapter->duration  = duration_correction * chapter->duration;
+        seconds            = ( chapter->duration + 45000 ) / 90000;
+        chapter->hours     = seconds / 3600;
+        chapter->minutes   = ( seconds % 3600 ) / 60;
+        chapter->seconds   = seconds % 60;
+
+        hb_log( "scan: chap %d c=%d->%d, b=%d->%d (%d), %lld ms",
+                chapter->index, chapter->cell_start, chapter->cell_end,
+                chapter->block_start, chapter->block_end,
+                chapter->block_count, chapter->duration / 90 );
+    }
+
+    /* Get aspect. We don't get width/height/rate infos here as
+       they tend to be wrong */
+    switch( vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
+    {
+        case 0:
+            title->container_aspect = 4. / 3.;
+            break;
+        case 3:
+            title->container_aspect = 16. / 9.;
+            break;
+        default:
+            hb_log( "scan: unknown aspect" );
+            goto fail;
+    }
+
+    hb_log( "scan: aspect = %g", title->aspect );
+
+    /* This title is ok so far */
+    goto cleanup;
+
+fail:
+    hb_list_close( &title->list_audio );
+    free( title );
+    title = NULL;
+
+cleanup:
+    if( vts ) ifoClose( vts );
+
+    return title;
+}
+
+/***********************************************************************
+ * hb_dvdnav_start
+ ***********************************************************************
+ * Title and chapter start at 1
+ **********************************************************************/
+static int hb_dvdnav_start( hb_dvd_t * e, int title, int chapter )
+{
+    hb_dvdnav_t * d = &(e->dvdnav);
+    ifo_handle_t *ifo;
+    int ii;
+    int vts, ttn, pgc_id, pgn;
+    pgc_t *pgc;
+    int cell_start, cell_end, title_start, title_end;
+
+    vts = d->vmg->tt_srpt->title[title-1].title_set_nr;
+    ttn = d->vmg->tt_srpt->title[title-1].vts_ttn;
+    if( !( ifo = ifoOpen( d->reader, vts ) ) )
+    {
+        hb_error( "dvd: ifoOpen failed for VTS %d", vts );
+        return 0;
+    }
+
+    /* Get title first and last blocks */
+    pgc_id         = ifo->vts_ptt_srpt->title[ttn-1].ptt[0].pgcn;
+    pgn            = ifo->vts_ptt_srpt->title[ttn-1].ptt[0].pgn;
+    pgc         = ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+    cell_start  = pgc->program_map[pgn - 1] - 1;
+    cell_end    = pgc->nr_of_cells - 1;
+    title_start = pgc->cell_playback[cell_start].first_sector;
+    title_end   = pgc->cell_playback[cell_end].last_sector;
+
+    /* Block count */
+    d->title_block_count = 0;
+    for( ii = cell_start; ii <= cell_end; ii++ )
+    {
+        d->title_block_count += pgc->cell_playback[ii].last_sector + 1 -
+            pgc->cell_playback[ii].first_sector;
+    }
+    ifoClose(ifo);
+
+    if ( dvdnav_part_play(d->dvdnav, title, chapter) != DVDNAV_STATUS_OK )
+    {
+        hb_error( "dvd: dvdnav_title_play failed - %s", 
+                  dvdnav_err_to_string(d->dvdnav) );
+        return 0;
+    }
+    d->title = title;
+    return 1;
+}
+
+/***********************************************************************
+ * hb_dvdnav_stop
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void hb_dvdnav_stop( hb_dvd_t * e )
+{
+}
+
+/***********************************************************************
+ * hb_dvdnav_seek
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int hb_dvdnav_seek( hb_dvd_t * e, float f )
+{
+    hb_dvdnav_t * d = &(e->dvdnav);
+    uint64_t sector;
+    int result, event, len;
+    uint8_t buf[HB_DVD_READ_BUFFER_SIZE];
+    int done = 0, ii;
+
+    // dvdnav will not let you seek or poll current position
+    // till it reaches a certain point in parsing.  so we
+    // have to get blocks until we reach a cell
+    // Put an arbitrary limit of 100 blocks on how long we search
+    for (ii = 0; ii < 100 && !done; ii++)
+    {
+        result = dvdnav_get_next_block( d->dvdnav, buf, &event, &len );
+        if ( result == DVDNAV_STATUS_ERR )
+        {
+            hb_log("dvdnav: Read Error, %s", dvdnav_err_to_string(d->dvdnav));
+            return 0;
+        }
+        switch ( event )
+        {
+        case DVDNAV_BLOCK_OK:
+        case DVDNAV_CELL_CHANGE:
+            done = 1;
+
+        case DVDNAV_STILL_FRAME:
+            dvdnav_still_skip( d->dvdnav );
+            break;
+
+        case DVDNAV_WAIT:
+            dvdnav_wait_skip( d->dvdnav );
+            break;
+
+        case DVDNAV_STOP:
+            return 0;
+
+        case DVDNAV_HOP_CHANNEL:
+        case DVDNAV_NAV_PACKET:
+        case DVDNAV_VTS_CHANGE:
+        case DVDNAV_HIGHLIGHT:
+        case DVDNAV_AUDIO_STREAM_CHANGE:
+        case DVDNAV_SPU_STREAM_CHANGE:
+        case DVDNAV_SPU_CLUT_CHANGE:
+        case DVDNAV_NOP:
+        default:
+            break;
+        }
+    } while (!(event == DVDNAV_CELL_CHANGE || event == DVDNAV_BLOCK_OK));
+
+    sector = f * d->title_block_count;
+    if (dvdnav_sector_search(d->dvdnav, sector, SEEK_SET) != DVDNAV_STATUS_OK)
+    {
+        hb_error( "dvd: dvdnav_sector_search failed - %s", 
+                  dvdnav_err_to_string(d->dvdnav) );
+        return 0;
+    }
+    return 1;
+}
+
+/***********************************************************************
+ * hb_dvdnav_read
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int hb_dvdnav_read( hb_dvd_t * e, hb_buffer_t * b )
+{
+    hb_dvdnav_t * d = &(e->dvdnav);
+    int result, event, len;
+    int chapter = 0;
+
+    while ( 1 )
+    {
+        result = dvdnav_get_next_block( d->dvdnav, b->data, &event, &len );
+        if ( result == DVDNAV_STATUS_ERR )
+        {
+            hb_log("dvdnav: Read Error, %s", dvdnav_err_to_string(d->dvdnav));
+            return 0;
+        }
+        switch ( event )
+        {
+        case DVDNAV_BLOCK_OK:
+            // We have received a regular block of the currently playing
+            // MPEG stream.
+
+            // The muxers expect to only get chapter 2 and above
+            // They write chapter 1 when chapter 2 is detected.
+            if (chapter > 1)
+                b->new_chap = chapter;
+            chapter = 0;
+            return 1;
+
+        case DVDNAV_NOP:
+            /*
+            * Nothing to do here. 
+            */
+            break;
+
+        case DVDNAV_STILL_FRAME:
+            /*
+            * We have reached a still frame. A real player application
+            * would wait the amount of time specified by the still's
+            * length while still handling user input to make menus and
+            * other interactive stills work. A length of 0xff means an
+            * indefinite still which has to be skipped indirectly by some 
+            * user interaction. 
+            */
+            dvdnav_still_skip( d->dvdnav );
+            break;
+
+        case DVDNAV_WAIT:
+            /*
+            * We have reached a point in DVD playback, where timing is
+            * critical. Player application with internal fifos can
+            * introduce state inconsistencies, because libdvdnav is
+            * always the fifo's length ahead in the stream compared to
+            * what the application sees. Such applications should wait
+            * until their fifos are empty when they receive this type of
+            * event. 
+            */
+            dvdnav_wait_skip( d->dvdnav );
+            break;
+
+        case DVDNAV_SPU_CLUT_CHANGE:
+            /*
+            * Player applications should pass the new colour lookup table 
+            * to their SPU decoder 
+            */
+            break;
+
+        case DVDNAV_SPU_STREAM_CHANGE:
+            /*
+            * Player applications should inform their SPU decoder to
+            * switch channels 
+            */
+            break;
+
+        case DVDNAV_AUDIO_STREAM_CHANGE:
+            /*
+            * Player applications should inform their audio decoder to
+            * switch channels 
+            */
+            break;
+
+        case DVDNAV_HIGHLIGHT:
+            /*
+            * Player applications should inform their overlay engine to
+            * highlight the given button 
+            */
+            break;
+
+        case DVDNAV_VTS_CHANGE:
+            /*
+            * Some status information like video aspect and video scale
+            * permissions do not change inside a VTS. Therefore this
+            * event can be used to query such information only when
+            * necessary and update the decoding/displaying accordingly. 
+            */
+            break;
+
+        case DVDNAV_CELL_CHANGE:
+            /*
+            * Some status information like the current Title and Part
+            * numbers do not change inside a cell. Therefore this event
+            * can be used to query such information only when necessary
+            * and update the decoding/displaying accordingly. 
+            */
+            {
+                int tt = 0, ptt = 0;
+
+                dvdnav_current_title_info(d->dvdnav, &tt, &ptt);
+                if (tt != d->title)
+                {
+                    // Transition to another title signals that we are done.
+                    return 0;
+                }
+                if (ptt > d->chapter)
+                    chapter = d->chapter = ptt;
+            }
+            break;
+
+        case DVDNAV_NAV_PACKET:
+            /*
+            * A NAV packet provides PTS discontinuity information, angle
+            * linking information and button definitions for DVD menus.
+            * Angles are handled completely inside libdvdnav. For the
+            * menus to work, the NAV packet information has to be passed
+            * to the overlay engine of the player so that it knows the
+            * dimensions of the button areas. 
+            */
+
+            // mpegdemux expects to get these.  I don't think it does
+            // anything useful with them however.
+
+            // The muxers expect to only get chapter 2 and above
+            // They write chapter 1 when chapter 2 is detected.
+            if (chapter > 1)
+                b->new_chap = chapter;
+            chapter = 0;
+            return 1;
+
+            break;
+
+        case DVDNAV_HOP_CHANNEL:
+            /*
+            * This event is issued whenever a non-seamless operation has
+            * been executed. Applications with fifos should drop the
+            * fifos content to speed up responsiveness. 
+            */
+            break;
+
+        case DVDNAV_STOP:
+            /*
+            * Playback should end here. 
+            */
+            return 0;
+
+        default:
+            break;
+        }
+    }
+    return 0;
+}
+
+/***********************************************************************
+ * hb_dvdnav_chapter
+ ***********************************************************************
+ * Returns in which chapter the next block to be read is.
+ * Chapter numbers start at 1.
+ **********************************************************************/
+static int hb_dvdnav_chapter( hb_dvd_t * e )
+{
+    hb_dvdnav_t * d = &(e->dvdnav);
+    int32_t t, c;
+
+    if (dvdnav_current_title_info(d->dvdnav, &t, &c) != DVDNAV_STATUS_OK)
+    {
+        return -1;
+    }
+    return c;
+}
+
+/***********************************************************************
+ * hb_dvdnav_close
+ ***********************************************************************
+ * Closes and frees everything
+ **********************************************************************/
+static void hb_dvdnav_close( hb_dvd_t ** _d )
+{
+    hb_dvdnav_t * d = &((*_d)->dvdnav);
+
+    if( d->dvdnav ) dvdnav_close( d->dvdnav );
+    if( d->vmg ) ifoClose( d->vmg );
+    if( d->reader ) DVDClose( d->reader );
+
+    free( d );
+    *_d = NULL;
+}
+
+/***********************************************************************
+ * hb_dvdnav_angle_count
+ ***********************************************************************
+ * Returns the number of angles supported.
+ **********************************************************************/
+static int hb_dvdnav_angle_count( hb_dvd_t * e )
+{
+    hb_dvdnav_t * d = &(e->dvdnav);
+    int current, angle_count;
+
+    if (dvdnav_get_angle_info( d->dvdnav, &current, &angle_count) != DVDNAV_STATUS_OK)
+    {
+        hb_log("dvdnav_get_angle_info %s", dvdnav_err_to_string(d->dvdnav));
+        angle_count = 1;
+    }
+    return angle_count;
+}
+
+/***********************************************************************
+ * hb_dvdnav_set_angle
+ ***********************************************************************
+ * Sets the angle to read
+ **********************************************************************/
+static void hb_dvdnav_set_angle( hb_dvd_t * e, int angle )
+{
+    hb_dvdnav_t * d = &(e->dvdnav);
+
+    if (dvdnav_angle_change( d->dvdnav, angle) != DVDNAV_STATUS_OK)
+    {
+        hb_log("dvdnav_angle_change %s", dvdnav_err_to_string(d->dvdnav));
+    }
+}
+
+/***********************************************************************
+ * FindNextCell
+ ***********************************************************************
+ * Assumes pgc and cell_cur are correctly set, and sets cell_next to the
+ * cell to be read when we will be done with cell_cur.
+ **********************************************************************/
+static int FindNextCell( pgc_t *pgc, int cell_cur )
+{
+    int i = 0;
+    int cell_next;
+
+    if( pgc->cell_playback[cell_cur].block_type ==
+            BLOCK_TYPE_ANGLE_BLOCK )
+    {
+
+        while( pgc->cell_playback[cell_cur+i].block_mode !=
+                   BLOCK_MODE_LAST_CELL )
+        {
+             i++;
+        }
+        cell_next = cell_cur + i + 1;
+        hb_log( "dvd: Skipping multi-angle cells %d-%d",
+                cell_cur,
+                cell_next - 1 );
+    }
+    else
+    {
+        cell_next = cell_cur + 1;
+    }
+    return cell_next;
+}
+
+/***********************************************************************
+ * dvdtime2msec
+ ***********************************************************************
+ * From lsdvd
+ **********************************************************************/
+static int dvdtime2msec(dvd_time_t * dt)
+{
+    double frames_per_s[4] = {-1.0, 25.00, -1.0, 29.97};
+    double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6];
+    long   ms;
+    ms  = (((dt->hour &   0xf0) >> 3) * 5 + (dt->hour   & 0x0f)) * 3600000;
+    ms += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60000;
+    ms += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1000;
+
+    if( fps > 0 )
+    {
+        ms += ((dt->frame_u & 0x30) >> 3) * 5 +
+              (dt->frame_u & 0x0f) * 1000.0 / fps;
+    }
+
+    return ms;
+}
index 5d517d3..0c96656 100644 (file)
@@ -72,6 +72,7 @@ int           hb_check_update( hb_handle_t * h, char ** version );
 void          hb_set_cpu_count( hb_handle_t *, int );
 
 char *        hb_dvd_name( char * path );
+void          hb_dvd_set_dvdnav( int enable );
 
 /* hb_scan()
    Scan the specified path. Can be a DVD device, a VIDEO_TS folder or
index fa3fe86..8d92750 100644 (file)
@@ -168,7 +168,7 @@ extern void decmetadata( hb_title_t *title );
 /***********************************************************************
  * dvd.c
  **********************************************************************/
-typedef struct hb_dvd_s hb_dvd_t;
+typedef union  hb_dvd_s hb_dvd_t;
 typedef struct hb_stream_s hb_stream_t;
 
 hb_dvd_t *   hb_dvd_init( char * path );
@@ -181,6 +181,8 @@ int          hb_dvd_read( hb_dvd_t *, hb_buffer_t * );
 int          hb_dvd_chapter( hb_dvd_t * );
 int          hb_dvd_is_break( hb_dvd_t * d );
 void         hb_dvd_close( hb_dvd_t ** );
+int          hb_dvd_angle_count( hb_dvd_t * d );
+void         hb_dvd_set_angle( hb_dvd_t * d, int angle );
 
 hb_stream_t * hb_stream_open( char * path, hb_title_t *title );
 void            hb_stream_close( hb_stream_t ** );
index dc2fb1a..725ebc1 100644 (file)
@@ -1,5 +1,5 @@
 __deps__ := A52DEC BZIP2 FAAC FAAD2 FFMPEG LAME LIBDCA \
-    LIBDVDREAD LIBMKV LIBMP4V2 LIBOGG LIBSAMPLERATE LIBTHEORA \
+    LIBDVDREAD LIBDVDNAV LIBMKV LIBMP4V2 LIBOGG LIBSAMPLERATE LIBTHEORA \
     LIBVORBIS MPEG2DEC PTHREADW32 X264 XVIDCORE ZLIB
 
 $(eval $(call import.MODULE.defs,LIBHB,libhb,$(__deps__)))
@@ -87,7 +87,7 @@ LIBHB.dll = $(LIBHB.build/)hb.dll
 LIBHB.lib = $(LIBHB.build/)hb.lib
 
 LIBHB.dll.libs = $(foreach n, \
-        a52 bz2 avcodec avformat avutil dca dvdread faac faad mkv mpeg2 mp3lame mp4v2 \
+        a52 bz2 avcodec avformat avutil dca dvdnav dvdread faac faad mkv mpeg2 mp3lame mp4v2 \
         ogg pthreadGC2 samplerate swscale theora vorbis vorbisenc x264 xvidcore z, \
         $(CONTRIB.build/)lib/lib$(n).a )
 
index 8c5ecdd..78f24a4 100644 (file)
@@ -225,6 +225,10 @@ static void ReaderFunc( void * _r )
             hb_dvd_close( &r->dvd );
             return;
         }
+        if (r->job->angle)
+        {
+            hb_dvd_set_angle( r->dvd, r->job->angle );
+        }
 
         if ( r->job->start_at_preview )
         {
index 2088883..db179ef 100644 (file)
@@ -406,7 +406,11 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
     hb_log( "scan: decoding previews for title %d", title->index );
 
     if (data->dvd)
+    {
       hb_dvd_start( data->dvd, title->index, 1 );
+      title->angle_count = hb_dvd_angle_count( data->dvd );
+      hb_log( "scan: title angle(s) %d", title->angle_count );
+    }
 
     for( i = 0; i < data->preview_count; i++ )
     {
index 619fb88..6a8e587 100644 (file)
@@ -42,6 +42,7 @@ BOOL                        fIsDragging;
     IBOutlet NSTextField          * fScanSrcTitleNumField;
     IBOutlet NSButton             * fScanSrcTitleCancelButton;
     IBOutlet NSButton             * fScanSrcTitleOpenButton;
+
     
     /* Picture Settings */
     PictureController            * fPictureController;
@@ -68,6 +69,11 @@ BOOL                        fIsDragging;
     IBOutlet NSTextField         * fSrcDVD2Field;
     IBOutlet NSTextField         * fSrcTitleField;
     IBOutlet NSPopUpButton       * fSrcTitlePopUp;
+    
+    /* Angle selection popup (only used for libdvdnav */
+    IBOutlet NSTextField         * fSrcAngleLabel;
+    IBOutlet NSPopUpButton       * fSrcAnglePopUp;
+    
     IBOutlet NSTextField         * fSrcChapterField;
     IBOutlet NSPopUpButton       * fSrcChapterStartPopUp;
     IBOutlet NSTextField         * fSrcChapterToField;
index 642a15f..b836368 100644 (file)
@@ -83,6 +83,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     /* Init libhb with check for updates libhb style set to "0" so its ignored and lets sparkle take care of it */
     int loggingLevel = [[[NSUserDefaults standardUserDefaults] objectForKey:@"LoggingLevel"] intValue];
     fHandle = hb_init(loggingLevel, 0);
+    /* Optional dvd nav UseDvdNav*/
+    hb_dvd_set_dvdnav([[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue]);
     /* Init a separate instance of libhb for user scanning and setting up jobs */
     fQueueEncodeLibhb = hb_init(loggingLevel, 0);
     
@@ -359,6 +361,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                [fPresetDrawer open];
        }
     
+    /* Initially set the dvd angle widgets to hidden (dvdnav only) */
+    [fSrcAngleLabel setHidden:YES];
+    [fSrcAnglePopUp setHidden:YES];
+    
     /* Destination box*/
     NSMenuItem *menuItem;
     [fDstFormatPopUp removeAllItems];
@@ -487,7 +493,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         fAudTrack1BitratePopUp, fAudTrack2BitratePopUp, fAudTrack3BitratePopUp, fAudTrack4BitratePopUp,
         fAudDrcLabel, fAudTrack1DrcSlider, fAudTrack1DrcField, fAudTrack2DrcSlider,
         fAudTrack2DrcField, fAudTrack3DrcSlider, fAudTrack3DrcField, fAudTrack4DrcSlider,fAudTrack4DrcField,
-        fQueueStatus,fPresetsAdd,fPresetsDelete,
+        fQueueStatus,fPresetsAdd,fPresetsDelete,fSrcAngleLabel,fSrcAnglePopUp,
                fCreateChapterMarkers,fVidTurboPassCheck,fDstMp4LargeFileCheck,fSubForcedCheck,fPresetsOutlineView,
     fAudDrcLabel,fDstMp4HttpOptFileCheck,fDstMp4iPodFileCheck,fVidQualityRFField,fVidQualityRFLabel};
     
@@ -1903,6 +1909,7 @@ fWorkingCount = 0;
     [queueFileJob setObject:[NSString stringWithUTF8String: title->dvd] forKey:@"SourcePath"];
     [queueFileJob setObject:[fSrcDVD2Field stringValue] forKey:@"SourceName"];
     [queueFileJob setObject:[NSNumber numberWithInt:title->index] forKey:@"TitleNumber"];
+    [queueFileJob setObject:[NSNumber numberWithInt:[fSrcAnglePopUp indexOfSelectedItem] + 1] forKey:@"TitleAngle"];
     [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterStartPopUp indexOfSelectedItem] + 1] forKey:@"ChapterStart"];
     
     [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterEndPopUp indexOfSelectedItem] + 1] forKey:@"ChapterEnd"];
@@ -2676,7 +2683,8 @@ fWorkingCount = 0;
             [fSrcTitlePopUp indexOfSelectedItem] );
     hb_job_t * job = title->job;
     hb_audio_config_t * audio;
-
+    /* set job->angle for libdvdnav */
+    job->angle = [fSrcAnglePopUp indexOfSelectedItem] + 1;
     /* Chapter selection */
     job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
     job->chapter_end   = [fSrcChapterEndPopUp   indexOfSelectedItem] + 1;
@@ -2967,6 +2975,8 @@ fWorkingCount = 0;
     hb_title_t * title = (hb_title_t *) hb_list_item( list,0 ); // is always zero since now its a single title scan
     hb_job_t * job = title->job;
     hb_audio_config_t * audio;
+    /* Title Angle for dvdnav */
+    job->angle = [[queueToApply objectForKey:@"TitleAngle"] intValue];
     /* Chapter selection */
     job->chapter_start = [[queueToApply objectForKey:@"JobChapterStart"] intValue];
     job->chapter_end   = [[queueToApply objectForKey:@"JobChapterEnd"] intValue];
@@ -3692,7 +3702,26 @@ fWorkingCount = 0;
     [fSrcChapterEndPopUp   selectItemAtIndex:
         hb_list_count( title->list_chapter ) - 1];
     [self chapterPopUpChanged:nil];
-
+    
+    /* if using dvd nav, show the angle widget */
+    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue])
+    {
+        [fSrcAngleLabel setHidden:NO];
+        [fSrcAnglePopUp setHidden:NO];
+        
+        [fSrcAnglePopUp removeAllItems];
+        for( int i = 0; i < title->angle_count; i++ )
+        {
+            [fSrcAnglePopUp addItemWithTitle: [NSString stringWithFormat: @"%d", i + 1]];
+        }
+        [fSrcAnglePopUp selectItemAtIndex: 0];
+    }
+    else
+    {
+        [fSrcAngleLabel setHidden:YES];
+        [fSrcAnglePopUp setHidden:YES];
+    }
+    
     /* Start Get and set the initial pic size for display */
        hb_job_t * job = title->job;
        fTitle = title;
index b998ddd..da8f6db 100644 (file)
@@ -8,6 +8,7 @@
                <string key="IBDocument.HIToolboxVersion">353.00</string>
                <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
                        <bool key="EncodedWithXMLCoder">YES</bool>
+                       <integer value="2"/>
                </object>
                <object class="NSArray" key="IBDocument.PluginDependencies">
                        <bool key="EncodedWithXMLCoder">YES</bool>
@@ -48,7 +49,7 @@
                                <string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
                                <string key="NSWindowContentMinSize">{213, 107}</string>
                                <object class="NSView" key="NSWindowView" id="168918359">
-                                       <nil key="NSNextResponder"/>
+                                       <reference key="NSNextResponder"/>
                                        <int key="NSvFlags">256</int>
                                        <object class="NSMutableArray" key="NSSubviews">
                                                <bool key="EncodedWithXMLCoder">YES</bool>
                                                <object class="NSPopUpButton" id="766125203">
                                                        <reference key="NSNextResponder" ref="168918359"/>
                                                        <int key="NSvFlags">264</int>
-                                                       <string key="NSFrame">{{76, 490}, {177, 22}}</string>
+                                                       <string key="NSFrame">{{76, 490}, {165, 22}}</string>
                                                        <reference key="NSSuperview" ref="168918359"/>
                                                        <bool key="NSEnabled">YES</bool>
                                                        <object class="NSPopUpButtonCell" key="NSCell" id="821198683">
                                                <object class="NSTextField" id="1053010160">
                                                        <reference key="NSNextResponder" ref="168918359"/>
                                                        <int key="NSvFlags">264</int>
-                                                       <string key="NSFrame">{{321, 495}, {65, 14}}</string>
+                                                       <string key="NSFrame">{{346, 495}, {65, 14}}</string>
                                                        <reference key="NSSuperview" ref="168918359"/>
                                                        <bool key="NSEnabled">YES</bool>
                                                        <object class="NSTextFieldCell" key="NSCell" id="17369297">
                                                <object class="NSPopUpButton" id="971754180">
                                                        <reference key="NSNextResponder" ref="168918359"/>
                                                        <int key="NSvFlags">264</int>
-                                                       <string key="NSFrame">{{388, 490}, {65, 22}}</string>
+                                                       <string key="NSFrame">{{413, 490}, {65, 22}}</string>
                                                        <reference key="NSSuperview" ref="168918359"/>
                                                        <bool key="NSEnabled">YES</bool>
                                                        <object class="NSPopUpButtonCell" key="NSCell" id="286887304">
                                                                <int key="NSArrowPosition">1</int>
                                                        </object>
                                                </object>
+                                               <object class="NSTextField" id="303369850">
+                                                       <reference key="NSNextResponder" ref="168918359"/>
+                                                       <int key="NSvFlags">264</int>
+                                                       <string key="NSFrame">{{241, 492}, {46, 17}}</string>
+                                                       <reference key="NSSuperview" ref="168918359"/>
+                                                       <bool key="NSEnabled">YES</bool>
+                                                       <object class="NSTextFieldCell" key="NSCell" id="677126774">
+                                                               <int key="NSCellFlags">67239424</int>
+                                                               <int key="NSCellFlags2">71303168</int>
+                                                               <string key="NSContents">Angle:</string>
+                                                               <reference key="NSSupport" ref="26"/>
+                                                               <reference key="NSControlView" ref="303369850"/>
+                                                               <reference key="NSBackgroundColor" ref="242973447"/>
+                                                               <reference key="NSTextColor" ref="701609070"/>
+                                                       </object>
+                                               </object>
+                                               <object class="NSPopUpButton" id="460320725">
+                                                       <reference key="NSNextResponder" ref="168918359"/>
+                                                       <int key="NSvFlags">264</int>
+                                                       <string key="NSFrame">{{286, 490}, {57, 22}}</string>
+                                                       <reference key="NSSuperview" ref="168918359"/>
+                                                       <bool key="NSEnabled">YES</bool>
+                                                       <object class="NSPopUpButtonCell" key="NSCell" id="567459641">
+                                                               <int key="NSCellFlags">-2076049856</int>
+                                                               <int key="NSCellFlags2">132096</int>
+                                                               <reference key="NSSupport" ref="26"/>
+                                                               <reference key="NSControlView" ref="460320725"/>
+                                                               <int key="NSButtonFlags">109199615</int>
+                                                               <int key="NSButtonFlags2">1</int>
+                                                               <reference key="NSAlternateImage" ref="26"/>
+                                                               <string key="NSAlternateContents"/>
+                                                               <object class="NSMutableString" key="NSKeyEquivalent">
+                                                                       <characters key="NS.bytes"/>
+                                                               </object>
+                                                               <int key="NSPeriodicDelay">400</int>
+                                                               <int key="NSPeriodicInterval">75</int>
+                                                               <object class="NSMenuItem" key="NSMenuItem" id="62890346">
+                                                                       <reference key="NSMenu" ref="651682595"/>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <int key="NSState">1</int>
+                                                                       <reference key="NSOnImage" ref="447995298"/>
+                                                                       <reference key="NSMixedImage" ref="760317610"/>
+                                                                       <string key="NSAction">_popUpItemAction:</string>
+                                                                       <reference key="NSTarget" ref="567459641"/>
+                                                               </object>
+                                                               <bool key="NSMenuItemRespectAlignment">YES</bool>
+                                                               <object class="NSMenu" key="NSMenu" id="651682595">
+                                                                       <object class="NSMutableString" key="NSTitle">
+                                                                               <characters key="NS.bytes">OtherViews</characters>
+                                                                       </object>
+                                                                       <object class="NSMutableArray" key="NSMenuItems">
+                                                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                                                               <reference ref="62890346"/>
+                                                                       </object>
+                                                               </object>
+                                                               <int key="NSPreferredEdge">3</int>
+                                                               <bool key="NSUsesItemFromMenu">YES</bool>
+                                                               <bool key="NSAltersState">YES</bool>
+                                                               <int key="NSArrowPosition">1</int>
+                                                       </object>
+                                               </object>
                                                <object class="NSPopUpButton" id="453345136">
                                                        <reference key="NSNextResponder" ref="168918359"/>
                                                        <int key="NSvFlags">264</int>
-                                                       <string key="NSFrame">{{510, 490}, {65, 22}}</string>
+                                                       <string key="NSFrame">{{532, 490}, {65, 22}}</string>
                                                        <reference key="NSSuperview" ref="168918359"/>
                                                        <bool key="NSEnabled">YES</bool>
                                                        <object class="NSPopUpButtonCell" key="NSCell" id="564669343">
                                                <object class="NSTextField" id="200266929">
                                                        <reference key="NSNextResponder" ref="168918359"/>
                                                        <int key="NSvFlags">264</int>
-                                                       <string key="NSFrame">{{455, 494}, {51, 15}}</string>
+                                                       <string key="NSFrame">{{479, 494}, {51, 15}}</string>
                                                        <reference key="NSSuperview" ref="168918359"/>
                                                        <bool key="NSEnabled">YES</bool>
                                                        <object class="NSTextFieldCell" key="NSCell" id="904849236">
                                                </object>
                                        </object>
                                        <string key="NSFrameSize">{760, 550}</string>
+                                       <reference key="NSSuperview"/>
                                </object>
                                <string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
                                <string key="NSMinSize">{213, 129}</string>
                                        </object>
                                        <int key="connectionID">5179</int>
                                </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">fSrcAngleLabel</string>
+                                               <reference key="source" ref="2258723"/>
+                                               <reference key="destination" ref="303369850"/>
+                                       </object>
+                                       <int key="connectionID">5186</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">fSrcAnglePopUp</string>
+                                               <reference key="source" ref="2258723"/>
+                                               <reference key="destination" ref="460320725"/>
+                                       </object>
+                                       <int key="connectionID">5187</int>
+                               </object>
                        </object>
                        <object class="IBMutableOrderedSet" key="objectRecords">
                                <object class="NSArray" key="orderedObjects">
                                                        <reference ref="581806074"/>
                                                        <reference ref="553453876"/>
                                                        <reference ref="921877174"/>
+                                                       <reference ref="303369850"/>
+                                                       <reference ref="460320725"/>
                                                </object>
                                                <reference key="parent" ref="192660081"/>
                                        </object>
                                                <reference key="object" ref="936221726"/>
                                                <reference key="parent" ref="323705695"/>
                                        </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5180</int>
+                                               <reference key="object" ref="303369850"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="677126774"/>
+                                               </object>
+                                               <reference key="parent" ref="168918359"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5181</int>
+                                               <reference key="object" ref="460320725"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="567459641"/>
+                                               </object>
+                                               <reference key="parent" ref="168918359"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5182</int>
+                                               <reference key="object" ref="567459641"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="651682595"/>
+                                               </object>
+                                               <reference key="parent" ref="460320725"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5183</int>
+                                               <reference key="object" ref="651682595"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="62890346"/>
+                                               </object>
+                                               <reference key="parent" ref="567459641"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5184</int>
+                                               <reference key="object" ref="62890346"/>
+                                               <reference key="parent" ref="651682595"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5185</int>
+                                               <reference key="object" ref="677126774"/>
+                                               <reference key="parent" ref="303369850"/>
+                                       </object>
                                </object>
                        </object>
                        <object class="NSMutableDictionary" key="flattenedProperties">
                                        <string>5177.IBPluginDependency</string>
                                        <string>5177.ImportedFromIB2</string>
                                        <string>5178.IBPluginDependency</string>
+                                       <string>5180.IBPluginDependency</string>
+                                       <string>5180.ImportedFromIB2</string>
+                                       <string>5181.IBPluginDependency</string>
+                                       <string>5181.ImportedFromIB2</string>
+                                       <string>5182.IBPluginDependency</string>
+                                       <string>5183.IBPluginDependency</string>
+                                       <string>5183.ImportedFromIB2</string>
+                                       <string>5184.IBPluginDependency</string>
+                                       <string>5184.ImportedFromIB2</string>
+                                       <string>5185.IBPluginDependency</string>
                                        <string>56.IBPluginDependency</string>
                                        <string>56.ImportedFromIB2</string>
                                        <string>57.IBPluginDependency</string>
                                        <reference ref="9"/>
                                        <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
                                        <reference ref="9"/>
+                                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+                                       <reference ref="9"/>
+                                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+                                       <reference ref="9"/>
+                                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+                                       <reference ref="9"/>
+                                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+                                       <reference ref="9"/>
                                        <string>{{75, 683}, {235, 153}}</string>
                                        <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
                                        <reference ref="9"/>
                                </object>
                        </object>
                        <nil key="sourceID"/>
-                       <int key="maxID">5179</int>
+                       <int key="maxID">5187</int>
                </object>
                <object class="IBClassDescriber" key="IBDocument.Classes">
                        <object class="NSMutableArray" key="referencedPartialClassDescriptions">
                                                        <string>setEnabledStateOfAudioMixdownControls:</string>
                                                        <string>showAddPresetPanel:</string>
                                                        <string>showDebugOutputPanel:</string>
-                                                       <string>showFiltersPanel:</string>
                                                        <string>showNewScan:</string>
                                                        <string>showPicturePanel:</string>
                                                        <string>showPreferencesWindow:</string>
                                                        <string>id</string>
                                                        <string>id</string>
                                                        <string>id</string>
-                                                       <string>id</string>
                                                </object>
                                        </object>
                                        <object class="NSMutableDictionary" key="outlets">
                                                        <string>fScanSrcTitleOpenButton</string>
                                                        <string>fScanSrcTitlePanel</string>
                                                        <string>fScanSrcTitlePathField</string>
+                                                       <string>fSrcAngleLabel</string>
+                                                       <string>fSrcAnglePopUp</string>
                                                        <string>fSrcChapterEndPopUp</string>
                                                        <string>fSrcChapterField</string>
                                                        <string>fSrcChapterStartPopUp</string>
                                                        <string>NSButton</string>
                                                        <string>NSPanel</string>
                                                        <string>NSTextField</string>
+                                                       <string>NSTextField</string>
+                                                       <string>NSPopUpButton</string>
                                                        <string>NSPopUpButton</string>
                                                        <string>NSTextField</string>
                                                        <string>NSPopUpButton</string>
index f58db42..0ef8e59 100644 (file)
@@ -8,7 +8,8 @@
                <string key="IBDocument.HIToolboxVersion">353.00</string>
                <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
                        <bool key="EncodedWithXMLCoder">YES</bool>
-                       <integer value="5"/>
+                       <integer value="233"/>
+                       <integer value="236"/>
                </object>
                <object class="NSArray" key="IBDocument.PluginDependencies">
                        <bool key="EncodedWithXMLCoder">YES</bool>
                                <string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
                                <string key="NSWindowContentMinSize">{213, 107}</string>
                                <object class="NSView" key="NSWindowView" id="496214002">
-                                       <reference key="NSNextResponder"/>
+                                       <nil key="NSNextResponder"/>
                                        <int key="NSvFlags">256</int>
                                        <string key="NSFrameSize">{500, 200}</string>
-                                       <reference key="NSSuperview"/>
                                </object>
                                <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
                                <string key="NSMinSize">{213, 129}</string>
                                <string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
                        </object>
                        <object class="NSUserDefaultsController" id="580534391">
+                               <object class="NSMutableArray" key="NSDeclaredKeys">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <string>UseDvdNav</string>
+                               </object>
                                <bool key="NSSharedInstance">YES</bool>
                        </object>
                        <object class="NSCustomView" id="1048779201">
-                               <nil key="NSNextResponder"/>
+                               <reference key="NSNextResponder"/>
                                <int key="NSvFlags">256</int>
                                <object class="NSMutableArray" key="NSSubviews">
                                        <bool key="EncodedWithXMLCoder">YES</bool>
                                        </object>
                                </object>
                                <string key="NSFrameSize">{492, 231}</string>
+                               <reference key="NSSuperview"/>
                                <string key="NSClassName">NSView</string>
                                <string key="NSExtension">NSControl</string>
                        </object>
                                <string key="NSExtension">NSResponder</string>
                        </object>
                        <object class="NSCustomView" id="23728330">
-                               <nil key="NSNextResponder"/>
+                               <reference key="NSNextResponder"/>
                                <int key="NSvFlags">256</int>
                                <object class="NSMutableArray" key="NSSubviews">
                                        <bool key="EncodedWithXMLCoder">YES</bool>
                                        <object class="NSButton" id="882188042">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">256</int>
-                                               <string key="NSFrame">{{84, 156}, {367, 18}}</string>
+                                               <string key="NSFrame">{{84, 201}, {367, 18}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="197383193">
                                        <object class="NSTextField" id="759266151">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">256</int>
-                                               <string key="NSFrame">{{40, 157}, {41, 17}}</string>
+                                               <string key="NSFrame">{{40, 202}, {41, 17}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSTextFieldCell" key="NSCell" id="488653412">
                                        <object class="NSTextField" id="226601760">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">256</int>
-                                               <string key="NSFrame">{{83, 134}, {301, 17}}</string>
+                                               <string key="NSFrame">{{83, 179}, {301, 17}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSTextFieldCell" key="NSCell" id="1064438472">
                                        <object class="NSTextField" id="701867067">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">256</int>
-                                               <string key="NSFrame">{{37, 101}, {239, 17}}</string>
+                                               <string key="NSFrame">{{37, 140}, {239, 17}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSTextFieldCell" key="NSCell" id="978611587">
                                        <object class="NSTextField" id="173328305">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">256</int>
-                                               <string key="NSFrame">{{71, 41}, {184, 17}}</string>
+                                               <string key="NSFrame">{{71, 39}, {184, 17}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSTextFieldCell" key="NSCell" id="271531935">
                                        <object class="NSTextField" id="899831697">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">256</int>
-                                               <string key="NSFrame">{{37, 65}, {32, 17}}</string>
+                                               <string key="NSFrame">{{40, 63}, {32, 17}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSTextFieldCell" key="NSCell" id="483848741">
                                        <object class="NSButton" id="907177043">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">256</int>
-                                               <string key="NSFrame">{{72, 63}, {367, 18}}</string>
+                                               <string key="NSFrame">{{75, 61}, {367, 18}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="869757541">
                                                        <int key="NSPeriodicInterval">25</int>
                                                </object>
                                        </object>
+                                       <object class="NSButton" id="745324926">
+                                               <reference key="NSNextResponder" ref="23728330"/>
+                                               <int key="NSvFlags">256</int>
+                                               <string key="NSFrame">{{41, 105}, {367, 18}}</string>
+                                               <reference key="NSSuperview" ref="23728330"/>
+                                               <bool key="NSEnabled">YES</bool>
+                                               <object class="NSButtonCell" key="NSCell" id="884409108">
+                                                       <int key="NSCellFlags">67239424</int>
+                                                       <int key="NSCellFlags2">0</int>
+                                                       <string type="base64-UTF8" key="NSContents">VXNlIGxpYmR2ZG5hdiAoaW5zdGVhZCBvZiBsaWJkdmRyZWFkKSBmb3IgZHZkJ3M</string>
+                                                       <reference key="NSSupport" ref="964910696"/>
+                                                       <reference key="NSControlView" ref="745324926"/>
+                                                       <int key="NSButtonFlags">1211912703</int>
+                                                       <int key="NSButtonFlags2">2</int>
+                                                       <reference key="NSAlternateImage" ref="1056213191"/>
+                                                       <string key="NSAlternateContents"/>
+                                                       <string key="NSKeyEquivalent"/>
+                                                       <int key="NSPeriodicDelay">200</int>
+                                                       <int key="NSPeriodicInterval">25</int>
+                                               </object>
+                                       </object>
                                        <object class="NSPopUpButton" id="772611942">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">268</int>
-                                               <string key="NSFrame">{{276, 96}, {66, 22}}</string>
+                                               <string key="NSFrame">{{276, 135}, {66, 22}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSPopUpButtonCell" key="NSCell" id="413609467">
                                        <object class="NSPopUpButton" id="822080053">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">268</int>
-                                               <string key="NSFrame">{{386, 129}, {66, 22}}</string>
+                                               <string key="NSFrame">{{386, 174}, {66, 22}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSPopUpButtonCell" key="NSCell" id="434430620">
                                        <object class="NSPopUpButton" id="895206300">
                                                <reference key="NSNextResponder" ref="23728330"/>
                                                <int key="NSvFlags">268</int>
-                                               <string key="NSFrame">{{255, 36}, {66, 22}}</string>
+                                               <string key="NSFrame">{{255, 34}, {66, 22}}</string>
                                                <reference key="NSSuperview" ref="23728330"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSPopUpButtonCell" key="NSCell" id="290473288">
                                                </object>
                                        </object>
                                </object>
-                               <string key="NSFrameSize">{481, 194}</string>
+                               <string key="NSFrameSize">{480, 239}</string>
+                               <reference key="NSSuperview"/>
                                <object class="NSMutableString" key="NSClassName">
                                        <characters key="NS.bytes">NSView</characters>
                                </object>
                                        </object>
                                        <int key="connectionID">397</int>
                                </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBBindingConnection" key="connection">
+                                               <string key="label">value: values.UseDvdNav</string>
+                                               <reference key="source" ref="745324926"/>
+                                               <reference key="destination" ref="580534391"/>
+                                               <object class="NSNibBindingConnector" key="connector">
+                                                       <reference key="NSSource" ref="745324926"/>
+                                                       <reference key="NSDestination" ref="580534391"/>
+                                                       <string key="NSLabel">value: values.UseDvdNav</string>
+                                                       <string key="NSBinding">value</string>
+                                                       <string key="NSKeyPath">values.UseDvdNav</string>
+                                                       <int key="NSNibBindingConnectorVersion">2</int>
+                                               </object>
+                                       </object>
+                                       <int key="connectionID">400</int>
+                               </object>
                        </object>
                        <object class="IBMutableOrderedSet" key="objectRecords">
                                <object class="NSArray" key="orderedObjects">
                                                        <reference ref="907177043"/>
                                                        <reference ref="822080053"/>
                                                        <reference ref="226601760"/>
+                                                       <reference ref="745324926"/>
                                                </object>
                                                <reference key="parent" ref="510204080"/>
                                                <string key="objectName">Advanced</string>
                                                <reference key="object" ref="1064438472"/>
                                                <reference key="parent" ref="226601760"/>
                                        </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">398</int>
+                                               <reference key="object" ref="745324926"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="884409108"/>
+                                               </object>
+                                               <reference key="parent" ref="23728330"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">399</int>
+                                               <reference key="object" ref="884409108"/>
+                                               <reference key="parent" ref="745324926"/>
+                                       </object>
                                </object>
                        </object>
                        <object class="NSMutableDictionary" key="flattenedProperties">
                                        <string>395.IBPluginDependency</string>
                                        <string>395.ImportedFromIB2</string>
                                        <string>396.IBPluginDependency</string>
+                                       <string>398.IBPluginDependency</string>
+                                       <string>398.ImportedFromIB2</string>
+                                       <string>399.IBPluginDependency</string>
                                        <string>5.IBEditorWindowLastContentRect</string>
                                        <string>5.IBWindowTemplateEditedContentRect</string>
                                        <string>5.ImportedFromIB2</string>
                                        <string>{{73, 774}, {500, 82}}</string>
                                        <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
                                        <reference ref="9"/>
-                                       <string>{{404, 579}, {481, 194}}</string>
+                                       <string>{{404, 534}, {480, 239}}</string>
                                        <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
                                        <reference ref="9"/>
                                        <string>{{0, 650}, {500, 184}}</string>
                                        <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
                                        <reference ref="9"/>
                                        <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+                                       <reference ref="9"/>
+                                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
                                        <string>{{69, 656}, {500, 200}}</string>
                                        <string>{{69, 656}, {500, 200}}</string>
                                        <reference ref="9"/>
                                </object>
                        </object>
                        <nil key="sourceID"/>
-                       <int key="maxID">397</int>
+                       <int key="maxID">400</int>
                </object>
                <object class="IBClassDescriber" key="IBDocument.Classes">
                        <object class="NSMutableArray" key="referencedPartialClassDescriptions">
index e82bfd0..7f947e1 100644 (file)
@@ -47,6 +47,7 @@
         @"English",         @"DefaultLanguage",
         @"NO",              @"DefaultMpegName",
         @"YES",             @"DefaultCrf",
+        @"NO",              @"UseDvdNav",
         @"",                @"DefAdvancedx264Flags",
         @"YES",             @"DefaultPresetsDrawerShow",
         desktopDirectory,   @"LastDestinationDirectory",
index bfd7d53..6738659 100644 (file)
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdca.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libdvdnav.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
index a1bafbb..3d6d737 100644 (file)
@@ -20,6 +20,7 @@ MODULES += contrib/ffmpeg
 MODULES += contrib/lame
 MODULES += contrib/libdca
 MODULES += contrib/libdvdread
+MODULES += contrib/libdvdnav
 MODULES += contrib/libmkv
 MODULES += contrib/libmp4v2
 MODULES += contrib/libogg
index 0859dde..0140823 100644 (file)
@@ -10,7 +10,7 @@ TEST.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%.o,$(TEST.c))
 TEST.exe = $(BUILD/)$(call TARGET.exe,$(HB.name)CLI)
 
 TEST.libs = $(LIBHB.a) $(foreach n, \
-        a52 avcodec avformat avutil dca dvdread faac faad mkv mpeg2 mp3lame mp4v2 \
+        a52 avcodec avformat avutil dca dvdnav dvdread faac faad mkv mpeg2 mp3lame mp4v2 \
         ogg samplerate swscale theora vorbis vorbisenc x264 xvidcore, \
         $(CONTRIB.build/)lib/lib$(n).a )
 
index 06aa028..36fac4e 100644 (file)
@@ -24,6 +24,7 @@
 /* Options */
 static int    debug       = HB_DEBUG_NONE;
 static int    update      = 0;
+static int    dvdnav      = 0;
 static char * input       = NULL;
 static char * output      = NULL;
 static char * format      = NULL;
@@ -75,6 +76,7 @@ static int    loosePixelratio = 0;
 static int    modulus       = 0;
 static int    par_height    = 0;
 static int    par_width     = 0;
+static int    angle = 0;
 static int    chapter_start = 0;
 static int    chapter_end   = 0;
 static int    chapter_markers = 0;
@@ -164,6 +166,7 @@ int main( int argc, char ** argv )
 
     /* Init libhb */
     h = hb_init( debug, update );
+    hb_dvd_set_dvdnav( dvdnav );
 
     /* Show version */
     fprintf( stderr, "%s - %s - %s\n",
@@ -332,6 +335,8 @@ static void PrintTitleInfo( hb_title_t * title )
     fprintf( stderr, "  + vts %d, ttn %d, cells %d->%d (%d blocks)\n",
              title->vts, title->ttn, title->cell_start, title->cell_end,
              title->block_count );
+    if (dvdnav)
+        fprintf( stderr, "  + angle(s) %d\n", title->angle_count );
     fprintf( stderr, "  + duration: %02d:%02d:%02d\n",
              title->hours, title->minutes, title->seconds );
     fprintf( stderr, "  + size: %dx%d, aspect: %.2f, %.3f fps\n",
@@ -492,6 +497,11 @@ static int HandleEvents( hb_handle_t * h )
                                           job->chapter_end );
             }
 
+            if ( angle )
+            {
+                job->angle = angle;
+            }
+
             if (preset)
             {
                 fprintf( stderr, "+ Using preset: %s", preset_name);
@@ -1902,6 +1912,7 @@ static void ShowHelp()
     "                            if the preset name has spaces, surround it with\n"
     "                            double quotation marks\n"
     "    -z, --preset-list       See a list of available built-in presets\n"
+    "        --dvdnav            Use dvdnav (Experimental)\n"
     "\n"
 
     "### Source Options-----------------------------------------------------------\n\n"
@@ -1912,6 +1923,7 @@ static void ShowHelp()
     "    -c, --chapters <string> Select chapters (e.g. \"1-3\" for chapters\n"
     "                            1 to 3, or \"3\" for chapter 3 only,\n"
     "                            default: all chapters)\n"
+    "        --angle <number>    Select the DVD angle\n"
     "        --previews <#:B>    Select how many preview images are generated (max 30),\n"
     "                            and whether or not they're stored to disk (0 or 1).\n"
     "                            (default: 10:0)\n"
@@ -2122,6 +2134,8 @@ static int ParseOptions( int argc, char ** argv )
     #define PREVIEWS 257
     #define START_AT_PREVIEW 258
     #define STOP_AT 259
+    #define ANGLE 260
+    #define DVDNAV 261
     
     for( ;; )
     {
@@ -2131,6 +2145,7 @@ static int ParseOptions( int argc, char ** argv )
             { "update",      no_argument,       NULL,    'u' },
             { "verbose",     optional_argument, NULL,    'v' },
             { "cpu",         required_argument, NULL,    'C' },
+            { "dvdnav",      no_argument,       NULL,    DVDNAV },
 
             { "format",      required_argument, NULL,    'f' },
             { "input",       required_argument, NULL,    'i' },
@@ -2142,6 +2157,7 @@ static int ParseOptions( int argc, char ** argv )
             { "title",       required_argument, NULL,    't' },
             { "longest",     no_argument,       NULL,    'L' },
             { "chapters",    required_argument, NULL,    'c' },
+            { "angle",       required_argument, NULL,    ANGLE },
             { "markers",     optional_argument, NULL,    'm' },
             { "audio",       required_argument, NULL,    'a' },
             { "mixdown",     required_argument, NULL,    '6' },
@@ -2229,6 +2245,9 @@ static int ParseOptions( int argc, char ** argv )
             case 'z':
                 ShowPresets();
                 exit ( 0 );
+            case DVDNAV:
+                dvdnav = 1;
+                break;
 
             case 'f':
                 format = strdup( optarg );
@@ -2289,6 +2308,9 @@ static int ParseOptions( int argc, char ** argv )
                 }
                 break;
             }
+            case ANGLE:
+                angle = atoi( optarg );
+                break;
             case 'm':
                 if( optarg != NULL )
                 {