diff options
author | jstebbins <[email protected]> | 2009-04-27 15:18:05 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2009-04-27 15:18:05 +0000 |
commit | 6b9c017e63f06e9a7b66062d0a8cb460a02ca6b6 (patch) | |
tree | 13479caa23219b5476a4d1e534a970cd6fce29fd | |
parent | 3bb12e29d03f62a303c7728cd6f40c6498f2858e (diff) |
add libdvdnav support
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://svn.handbrake.fr/HandBrake/trunk@2355 b64f7644-9d1e-0410-96f1-a4d463321fa5
38 files changed, 1894 insertions, 333 deletions
diff --git a/contrib/libdvdnav/A00-log-stderr.patch b/contrib/libdvdnav/A00-log-stderr.patch new file mode 100644 index 000000000..36435dce8 --- /dev/null +++ b/contrib/libdvdnav/A00-log-stderr.patch @@ -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 index 000000000..0e0618617 --- /dev/null +++ b/contrib/libdvdnav/P00-mingw-no-examples.patch @@ -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 index 000000000..4134146c7 --- /dev/null +++ b/contrib/libdvdnav/module.defs @@ -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 index 000000000..8d23cca92 --- /dev/null +++ b/contrib/libdvdnav/module.rules @@ -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 index 000000000..af7018e7a --- /dev/null +++ b/contrib/libdvdread/A00-volume-name.patch @@ -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); diff --git a/contrib/libdvdread/P00-darwin-css-vlc-dylib.patch b/contrib/libdvdread/P00-darwin-css-vlc-dylib.patch index cb0181517..d6c5f6d57 100644 --- a/contrib/libdvdread/P00-darwin-css-vlc-dylib.patch +++ b/contrib/libdvdread/P00-darwin-css-vlc-dylib.patch @@ -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 index fbb1f12d3..000000000 --- a/contrib/libdvdread/P01-cygwin.patch +++ /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 index a4dc5eda7..000000000 --- a/contrib/libdvdread/P02-mingw-ssize_t.patch +++ /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 index 515526289..000000000 --- a/contrib/libdvdread/P03-mingw-disable-dlopen.patch +++ /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 index 872b8518d..000000000 --- a/contrib/libdvdread/P04-mingw-endian-macros.patch +++ /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 */ diff --git a/contrib/libdvdread/P05-mingw-large-file.patch b/contrib/libdvdread/P05-mingw-large-file.patch index 7ed9b6540..480d1e955 100644 --- a/contrib/libdvdread/P05-mingw-large-file.patch +++ b/contrib/libdvdread/P05-mingw-large-file.patch @@ -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 index 000000000..b6efc2e52 --- /dev/null +++ b/contrib/libdvdread/P06-darwin.patch @@ -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" */ diff --git a/contrib/libdvdread/module.defs b/contrib/libdvdread/module.defs index 99b70923a..3db333bb8 100644 --- a/contrib/libdvdread/module.defs +++ b/contrib/libdvdread/module.defs @@ -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; diff --git a/gtk/src/Makefile.am b/gtk/src/Makefile.am index 41eb76598..71b3ac363 100644 --- a/gtk/src/Makefile.am +++ b/gtk/src/Makefile.am @@ -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 diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c index f8362a58e..00229f132 100644 --- a/gtk/src/callbacks.c +++ b/gtk/src/callbacks.c @@ -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) diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui index bd9d2bb9a..489ebbb16 100644 --- a/gtk/src/ghb.ui +++ b/gtk/src/ghb.ui @@ -209,6 +209,14 @@ <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> @@ -683,6 +691,50 @@ </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> @@ -723,7 +775,7 @@ </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> diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index 8deac8831..140ce0e72 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -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; } diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h index b4f697707..2b27d532a 100644 --- a/gtk/src/hb-backend.h +++ b/gtk/src/hb-backend.h @@ -74,6 +74,7 @@ typedef struct gint minutes; gint seconds; gint64 duration; + gint angle_count; } ghb_title_info_t; typedef struct diff --git a/gtk/src/internal_defaults.xml b/gtk/src/internal_defaults.xml index 986463e09..f2bc8d336 100644 --- a/gtk/src/internal_defaults.xml +++ b/gtk/src/internal_defaults.xml @@ -4,6 +4,8 @@ <dict> <key>Initialization</key> <dict> + <key>angle</key> + <integer>1</integer> <key>anamorphic</key> <true /> <key>autoscale</key> @@ -118,6 +120,8 @@ <string>1</string> <key>nocheckvquality</key> <false /> + <key>use_dvdnav</key> + <false /> <key>reduce_hd_preview</key> <true /> <key>preview_count</key> diff --git a/gtk/src/widgetdeps.c b/gtk/src/widgetdeps.c index 26bf0fbec..6a6945f1e 100644 --- a/gtk/src/widgetdeps.c +++ b/gtk/src/widgetdeps.c @@ -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}, diff --git a/libhb/common.h b/libhb/common.h index 5a6320a43..73ebfda76 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -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; diff --git a/libhb/dvd.c b/libhb/dvd.c index 479157e8a..8bc61944f 100644 --- a/libhb/dvd.c +++ b/libhb/dvd.c @@ -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 index 000000000..8f89a82cc --- /dev/null +++ b/libhb/dvd.h @@ -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 index 000000000..c46d7faae --- /dev/null +++ b/libhb/dvdnav.c @@ -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, ¤t, &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; +} diff --git a/libhb/hb.h b/libhb/hb.h index 5d517d3d8..0c96656d6 100644 --- a/libhb/hb.h +++ b/libhb/hb.h @@ -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 diff --git a/libhb/internal.h b/libhb/internal.h index fa3fe86f6..8d927501c 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -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 ** ); diff --git a/libhb/module.defs b/libhb/module.defs index dc2fb1ad5..725ebc116 100644 --- a/libhb/module.defs +++ b/libhb/module.defs @@ -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 ) diff --git a/libhb/reader.c b/libhb/reader.c index 8c5ecdd2a..78f24a457 100644 --- a/libhb/reader.c +++ b/libhb/reader.c @@ -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 ) { diff --git a/libhb/scan.c b/libhb/scan.c index 2088883ab..db179ef75 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -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++ ) { diff --git a/macosx/Controller.h b/macosx/Controller.h index 619fb8817..6a8e587ba 100644 --- a/macosx/Controller.h +++ b/macosx/Controller.h @@ -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; diff --git a/macosx/Controller.mm b/macosx/Controller.mm index 642a15fa4..b83636849 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -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; diff --git a/macosx/English.lproj/MainMenu.xib b/macosx/English.lproj/MainMenu.xib index b998ddd58..da8f6db98 100644 --- a/macosx/English.lproj/MainMenu.xib +++ b/macosx/English.lproj/MainMenu.xib @@ -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> @@ -2356,7 +2357,7 @@ <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"> @@ -2404,7 +2405,7 @@ <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"> @@ -2420,7 +2421,7 @@ <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"> @@ -2465,10 +2466,74 @@ <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"> @@ -2516,7 +2581,7 @@ <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"> @@ -2908,6 +2973,7 @@ </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> @@ -6078,6 +6144,22 @@ </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"> @@ -6152,6 +6234,8 @@ <reference ref="581806074"/> <reference ref="553453876"/> <reference ref="921877174"/> + <reference ref="303369850"/> + <reference ref="460320725"/> </object> <reference key="parent" ref="192660081"/> </object> @@ -9202,6 +9286,52 @@ <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"> @@ -9938,6 +10068,16 @@ <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> @@ -10716,6 +10856,16 @@ <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"/> @@ -10747,7 +10897,7 @@ </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"> @@ -10798,7 +10948,6 @@ <string>setEnabledStateOfAudioMixdownControls:</string> <string>showAddPresetPanel:</string> <string>showDebugOutputPanel:</string> - <string>showFiltersPanel:</string> <string>showNewScan:</string> <string>showPicturePanel:</string> <string>showPreferencesWindow:</string> @@ -10865,7 +11014,6 @@ <string>id</string> <string>id</string> <string>id</string> - <string>id</string> </object> </object> <object class="NSMutableDictionary" key="outlets"> @@ -10943,6 +11091,8 @@ <string>fScanSrcTitleOpenButton</string> <string>fScanSrcTitlePanel</string> <string>fScanSrcTitlePathField</string> + <string>fSrcAngleLabel</string> + <string>fSrcAnglePopUp</string> <string>fSrcChapterEndPopUp</string> <string>fSrcChapterField</string> <string>fSrcChapterStartPopUp</string> @@ -11049,6 +11199,8 @@ <string>NSButton</string> <string>NSPanel</string> <string>NSTextField</string> + <string>NSTextField</string> + <string>NSPopUpButton</string> <string>NSPopUpButton</string> <string>NSTextField</string> <string>NSPopUpButton</string> diff --git a/macosx/English.lproj/Preferences.xib b/macosx/English.lproj/Preferences.xib index f58db4289..0ef8e5940 100644 --- a/macosx/English.lproj/Preferences.xib +++ b/macosx/English.lproj/Preferences.xib @@ -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> @@ -47,20 +48,23 @@ <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> @@ -446,6 +450,7 @@ </object> </object> <string key="NSFrameSize">{492, 231}</string> + <reference key="NSSuperview"/> <string key="NSClassName">NSView</string> <string key="NSExtension">NSControl</string> </object> @@ -794,14 +799,14 @@ <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"> @@ -822,7 +827,7 @@ <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"> @@ -838,7 +843,7 @@ <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"> @@ -854,7 +859,7 @@ <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"> @@ -870,7 +875,7 @@ <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"> @@ -886,7 +891,7 @@ <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"> @@ -902,7 +907,7 @@ <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"> @@ -920,10 +925,31 @@ <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"> @@ -1012,7 +1038,7 @@ <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"> @@ -1087,7 +1113,7 @@ <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"> @@ -1151,7 +1177,8 @@ </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> @@ -1433,6 +1460,22 @@ </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"> @@ -1643,6 +1686,7 @@ <reference ref="907177043"/> <reference ref="822080053"/> <reference ref="226601760"/> + <reference ref="745324926"/> </object> <reference key="parent" ref="510204080"/> <string key="objectName">Advanced</string> @@ -2081,6 +2125,20 @@ <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"> @@ -2218,6 +2276,9 @@ <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> @@ -2246,7 +2307,7 @@ <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> @@ -2363,6 +2424,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> <string>{{69, 656}, {500, 200}}</string> <string>{{69, 656}, {500, 200}}</string> <reference ref="9"/> @@ -2396,7 +2460,7 @@ </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"> diff --git a/macosx/HBPreferencesController.m b/macosx/HBPreferencesController.m index e82bfd0ab..7f947e12b 100644 --- a/macosx/HBPreferencesController.m +++ b/macosx/HBPreferencesController.m @@ -47,6 +47,7 @@ @"English", @"DefaultLanguage", @"NO", @"DefaultMpegName", @"YES", @"DefaultCrf", + @"NO", @"UseDvdNav", @"", @"DefAdvancedx264Flags", @"YES", @"DefaultPresetsDrawerShow", desktopDirectory, @"LastDestinationDirectory", diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj index bfd7d539f..67386592d 100644 --- a/macosx/HandBrake.xcodeproj/project.pbxproj +++ b/macosx/HandBrake.xcodeproj/project.pbxproj @@ -690,6 +690,7 @@ "$(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", @@ -720,6 +721,7 @@ "$(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", @@ -786,6 +788,7 @@ "$(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", @@ -822,6 +825,7 @@ "$(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", @@ -909,6 +913,7 @@ "$(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", @@ -945,6 +950,7 @@ "$(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", @@ -1032,6 +1038,7 @@ "$(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", @@ -1068,6 +1075,7 @@ "$(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", @@ -1155,6 +1163,7 @@ "$(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", @@ -1191,6 +1200,7 @@ "$(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", @@ -1281,6 +1291,7 @@ "$(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", @@ -1317,6 +1328,7 @@ "$(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", @@ -1407,6 +1419,7 @@ "$(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", @@ -1443,6 +1456,7 @@ "$(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", @@ -1533,6 +1547,7 @@ "$(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", @@ -1569,6 +1584,7 @@ "$(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", @@ -1659,6 +1675,7 @@ "$(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", @@ -1695,6 +1712,7 @@ "$(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", @@ -1793,6 +1811,7 @@ "$(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", @@ -1834,6 +1853,7 @@ "$(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", diff --git a/make/include/main.defs b/make/include/main.defs index a1bafbb92..3d6d73748 100644 --- a/make/include/main.defs +++ b/make/include/main.defs @@ -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 diff --git a/test/module.defs b/test/module.defs index 0859ddefd..01408234c 100644 --- a/test/module.defs +++ b/test/module.defs @@ -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 ) diff --git a/test/test.c b/test/test.c index 06aa02881..36fac4e9c 100644 --- a/test/test.c +++ b/test/test.c @@ -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 ) { |