diff --git a/Makefile.am b/Makefile.am index 04365fd..ff15527 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,15 @@ include $(top_srcdir)/doxygen-include.am ACLOCAL_AMFLAGS = -I m4 +DISTCHECK_CONFIGURE_FLAGS = --enable-bdjava --enable-udf MOSTLYCLEANFILES = $(DX_CLEANFILES) +if ENABLE_UDF POSIX_C_SOURCE=200809L +else +POSIX_C_SOURCE=200112L +endif EXTRA_DIST = \ bootstrap \ @@ -35,7 +40,7 @@ libbluray_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ -I$(top_builddir)/src/libbluray \ $(BDJAVA_CFLAGS) \ - -I${top_srcdir}/contrib/libudfread/src/ \ + $(UDF_CFLAGS) \ $(LIBXML2_CFLAGS) \ $(FT2_CFLAGS) \ $(FONTCONFIG_CFLAGS) @@ -166,6 +171,7 @@ libbluray_la_SOURCES += \ src/libbluray/bdj/native/util.c # libudfread +if ENABLE_UDF libbluray_la_SOURCES += \ src/libbluray/disc/udf_fs.h \ src/libbluray/disc/udf_fs.c\ @@ -177,6 +183,7 @@ libbluray_la_SOURCES += \ contrib/libudfread/src/ecma167.c \ contrib/libudfread/src/udfread.h \ contrib/libudfread/src/udfread.c +endif if HAVE_DARWIN libbluray_la_SOURCES+= \ @@ -223,7 +230,7 @@ pkginclude_HEADERS = \ src/libbluray/decoders/overlay.h \ src/util/log_control.h - +if USING_BDJAVA if USING_BDJAVA_BUILD_JAR jardir=$(datadir)/java/ jar_DATA=$(top_builddir)/.libs/libbluray-$(BDJ_TYPE)-$(VERSION).jar @@ -245,6 +252,7 @@ clean-local: -Dversion='$(BDJ_TYPE)-$(VERSION)' \ clean endif +endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = src/libbluray.pc @@ -257,7 +265,6 @@ pkgconfig_DATA = src/libbluray.pc if USING_EXAMPLES noinst_PROGRAMS = \ - bdj_test \ bdjo_dump \ bdsplice \ clpi_dump \ @@ -269,6 +276,11 @@ noinst_PROGRAMS = \ mpls_dump \ sound_dump +if USING_BDJAVA +noinst_PROGRAMS += \ + bdj_test +endif + bin_PROGRAMS = \ bd_info diff --git a/configure.ac b/configure.ac index 5fd3c8d..15f53ca 100644 --- a/configure.ac +++ b/configure.ac @@ -81,6 +81,16 @@ AC_ARG_ENABLE([examples], [use_examples=$enableval], [use_examples=yes]) +AC_ARG_ENABLE([bdjava], + [AS_HELP_STRING([--disable-bdjava], [disable BD-Java support @<:@default=enabled@:>@])], + [use_bdjava=$enableval], + [use_bdjava=yes]) + +AC_ARG_ENABLE([udf], + [AS_HELP_STRING([--disable-udf], [disable UDF support @<:@default=enabled@:>@])], + [enable_udf=$enableval], + [enable_udf=yes]) + AC_ARG_ENABLE([bdjava-jar], [AS_HELP_STRING([--disable-bdjava-jar], [disable building of BD-Java JAR file @<:@default=enabled@:>@])], @@ -196,23 +206,24 @@ dnl use examples AM_CONDITIONAL([USING_EXAMPLES], [ test $use_examples = "yes" ]) dnl use bdjava -case $host_cpu in - x86_64) java_arch=amd64 ;; - i?86) java_arch=i386 ;; - arm*) java_arch=arm ;; - *) java_arch=$host_cpu ;; -esac -case $host_os in - linux*) java_os=linux ;; - win*) java_os=win32 ;; - mingw*) java_os=win32 ;; - freebsd*) java_os=freebsd ;; - solaris*) java_os=solaris ;; - darwin*) java_os=darwin ;; - *) java_os=$host_os ;; -esac - -AS_IF([test "x${JDK_HOME}" != "x"], [ +if [[ $use_bdjava = "yes" ]]; then + case $host_cpu in + x86_64) java_arch=amd64 ;; + i?86) java_arch=i386 ;; + arm*) java_arch=arm ;; + *) java_arch=$host_cpu ;; + esac + case $host_os in + linux*) java_os=linux ;; + win*) java_os=win32 ;; + mingw*) java_os=win32 ;; + freebsd*) java_os=freebsd ;; + solaris*) java_os=solaris ;; + darwin*) java_os=darwin ;; + *) java_os=$host_os ;; + esac + + AS_IF([test "x${JDK_HOME}" != "x"], [ BDJAVA_CFLAGS="-I${JDK_HOME}/include -I${JDK_HOME}/include/$java_os" temp_CPPFLAGS="$CPPFLAGS" @@ -223,13 +234,16 @@ AS_IF([test "x${JDK_HOME}" != "x"], [ BDJAVA_CFLAGS='-I${abs_top_srcdir}/jni -I${abs_top_srcdir}/jni/'"${java_os}" ]) -AC_CHECK_PROG(HAVE_ANT, [ant], yes, no) -if test "x$use_bdjava_jar" = "xyes" && test "x$HAVE_ANT" = "xno"; then - AC_MSG_ERROR([BD-J requires ANT, but ant was not found. Please install it.]) -fi + AC_CHECK_PROG(HAVE_ANT, [ant], yes, no) + if test "x$use_bdjava_jar" = "xyes" && test "x$HAVE_ANT" = "xno"; then + AC_MSG_ERROR([BD-J requires ANT, but ant was not found. Please install it.]) + fi -AC_DEFINE_UNQUOTED([JAVA_ARCH], ["$java_arch"], ["Defines the architecture of the java vm."]) -AC_DEFINE_UNQUOTED([JDK_HOME], ["$JDK_HOME"], [""]) + AC_DEFINE([USING_BDJAVA], [1], ["Define to 1 if using BD-Java"]) + AC_DEFINE_UNQUOTED([JAVA_ARCH], ["$java_arch"], ["Defines the architecture of the java vm."]) + AC_DEFINE_UNQUOTED([JDK_HOME], ["$JDK_HOME"], [""]) +fi +AM_CONDITIONAL([USING_BDJAVA], [ test $use_bdjava = "yes" ]) AM_CONDITIONAL([USING_BDJAVA_BUILD_JAR], [ test $use_bdjava_jar = "yes" ]) dnl BD-J type @@ -243,13 +257,22 @@ dnl bootclasspath AC_SUBST(BDJ_BOOTCLASSPATH) dnl udf support (using git submodule) -if test ! -f "${srcdir}/contrib/libudfread/src/udfread.h"; then - AC_MSG_ERROR("libudfread source tree not found") -fi -AC_CHECK_HEADERS([unistd.h fcntl.h]) -AS_IF([test "${SYS}" != "mingw32"], [ - AC_CHECK_FUNC([pread],, [AC_DEFINE([NEED_PREAD_IMPL], [1], [Define to 1 to use inefficient pread() replacement])]) -]) +AS_IF([test "x$enable_udf" = "xyes"], [ + if test ! -f "${srcdir}/contrib/libudfread/src/udfread.h"; then + AC_MSG_ERROR("libudfread source tree not found") + fi + AC_CHECK_HEADERS([unistd.h fcntl.h]) + AS_IF([test "${SYS}" != "mingw32"], [ + AC_CHECK_FUNC([pread],, [AC_MSG_ERROR("Function pread not found. Try with --disable-udf.")]) + ]) + + AC_DEFINE([ENABLE_UDF], [1], [Define to 1 if libudfread is to be used for disc image access]) + UDF_CFLAGS='-I${srcdir}/contrib/libudfread/src/' + AC_SUBST(UDF_CFLAGS) + ], + [enable_udf=no]) + +AM_CONDITIONAL([ENABLE_UDF], [test $enable_udf = "yes" ]) dnl generate documentation DX_INIT_DOXYGEN(libbluray, doc/doxygen-config, [doc/doxygen]) @@ -279,19 +302,25 @@ dnl --------------------------------------------- echo " Summary:" echo " --------" +echo " BD-J support: $use_bdjava" +if [[ $use_bdjava = "yes" ]]; then echo " BD-J type: $BDJ_TYPE" echo " build JAR: $use_bdjava_jar" if test x"$BDJ_BOOTCLASSPATH" != x""; then echo " BD-J bootclasspath: $BDJ_BOOTCLASSPATH" fi +fi echo " Font support (freetype2): $with_freetype" if [[ $with_freetype = "yes" ]]; then +if [[ $use_bdjava = "yes" ]]; then if test "${SYS}" != "mingw32"; then echo " Use system fonts (fontconfig): $with_fontconfig" else echo " Use system fonts: yes" fi fi +fi echo " Metadata support (libxml2): $with_libxml2" +echo " UDF filesystem support: $enable_udf" echo " Build examples: $use_examples" diff --git a/includes/inttypes.h b/includes/inttypes.h new file mode 100644 index 0000000..ead903f --- /dev/null +++ b/includes/inttypes.h @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/libbluray.def b/libbluray.def new file mode 100644 index 0000000..d4c93cb --- /dev/null +++ b/libbluray.def @@ -0,0 +1,63 @@ +; libbluray.def ; declares the exports + +LIBRARY "libbluray.dll" + +EXPORTS + ; bluray.h + bd_get_version + bd_get_titles + bd_get_title_info + bd_get_playlist_info + bd_free_title_info + bd_open + bd_close + bd_seek + bd_seek_time + bd_find_seek_point + bd_read + bd_read_skip_still + bd_seek_chapter + bd_chapter_pos + bd_get_current_chapter + bd_seek_mark + bd_seek_playitem + bd_select_playlist + bd_select_title + bd_select_angle + bd_seamless_angle_change + bd_get_title_size + bd_get_current_title + bd_get_current_angle + bd_tell + bd_tell_time + bd_get_disc_info + bd_set_player_setting + bd_set_player_setting_str + bd_start_bdj + bd_stop_bdj + bd_get_event + bd_play + bd_read_ext + bd_play_title + bd_menu_call + bd_register_overlay_proc + bd_register_argb_overlay_proc + bd_set_scr + bd_user_input + bd_mouse_select + bd_get_sound_effect + bd_get_meta + bd_get_clpi + bd_read_clpi + bd_free_clpi + bd_read_mpls + bd_free_mpls + bd_read_mobj + bd_free_mobj + bd_get_clip_infos + bd_get_title_mpls + + ; additional functions + bd_set_debug_handler + bd_set_debug_mask + bd_get_debug_mask diff --git a/libbluray.vcxproj b/libbluray.vcxproj new file mode 100644 index 0000000..6de7ad2 --- /dev/null +++ b/libbluray.vcxproj @@ -0,0 +1,241 @@ + + + + + DebugRelease + Win32 + + + DebugRelease + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {E1DA1B95-71F1-4C21-A271-121176925062} + Win32Proj + libbluray + + + + v120 + + + v140 + 8.1 + + + v141 + 8.1 + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + true + $(SolutionDir)bin_$(PlatformName)d\ + $(SolutionDir)bin_$(PlatformName)d\$(ProjectName)\ + + + false + $(SolutionDir)bin_$(PlatformName)\$(ProjectName)\ + $(SolutionDir)bin_$(PlatformName)\$(ProjectName)\ + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBBLURAY_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + __STDC_FORMAT_MACROS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)includes;$(ProjectDir)src;$(ProjectDir)src\libbluray;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + CompileAsCpp + + + Windows + true + libbluray.def + + + xcopy /I /Y "$(OutDir)$(TargetName).lib" "$(OutDir)lib\" + Copy .lib into library path + + + + + MultiThreadedDebug + + + + + Level3 + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBBLURAY_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + __STDC_FORMAT_MACROS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)includes;$(ProjectDir)src;$(ProjectDir)src\libbluray;%(AdditionalIncludeDirectories) + MultiThreaded + StreamingSIMDExtensions + CompileAsCpp + + + Windows + true + true + true + libbluray.def + true + + + xcopy /I /Y "$(TargetDir)$(TargetName)$(TargetExt)" "$(OutDir)..\" +xcopy /I /Y "$(TargetDir)$(TargetName).lib" "$(OutDir)..\lib\" + Copy .dll/.lib into library path + + + + + + \ No newline at end of file diff --git a/libbluray.vcxproj.filters b/libbluray.vcxproj.filters new file mode 100644 index 0000000..02a4161 --- /dev/null +++ b/libbluray.vcxproj.filters @@ -0,0 +1,377 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {1ab0e905-7c04-4090-b385-6363dd1c961c} + + + {b8fa3348-a089-461f-9ef5-3d9df997b8e5} + + + {125333e9-0b5e-45f9-a444-f0aaaf547d9b} + + + {a743058f-f07a-4d0f-bab6-02dc57defda9} + + + {7dacc7c4-ef59-452b-9e5b-392c9df07c98} + + + {c7895c81-c186-4d5e-a8ff-645c6d55a731} + + + {c8619466-211b-4c85-9d30-d1b1a822d32e} + + + {8afb6919-994f-4d1f-9638-ce4a06d0b473} + + + {0e9086a7-eebf-4b8e-a4fe-b1724d148877} + + + {fc5e776b-0f32-493a-b823-240288288502} + + + {96d2d786-cd45-4856-937d-9e6f85ced241} + + + {9f4ea4ae-217a-4d97-a5f3-e561ce1e49cd} + + + {09e1b1b8-3aa3-4918-b157-3dfc0554ccbb} + + + {1e02e503-752e-4765-9dfb-8cc67a7b79f8} + + + + + Header Files\util + + + Header Files\util + + + Header Files\util + + + Header Files\util + + + Header Files\util + + + Header Files\util + + + Header Files\util + + + Header Files\file + + + Header Files\file + + + Header Files\file + + + Header Files\libbluray + + + Header Files\libbluray + + + Header Files\libbluray + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\hdmv + + + Header Files\libbluray\hdmv + + + Header Files\libbluray\hdmv + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\libbluray\decoders + + + Header Files\util + + + Header Files\util + + + Header Files\libbluray + + + Header Files\libbluray\decoders + + + Header Files\file + + + Header Files\libbluray + + + Header Files\util + + + Header Files\libbluray\disc + + + Header Files\libbluray\disc + + + Header Files\libbluray\disc + + + Header Files\libbluray\disc + + + Header Files\libbluray\disc + + + Header Files\file + + + Header Files\util + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\bdnav + + + Header Files\libbluray\disc + + + + + Source Files\util + + + Source Files\util + + + Source Files\file + + + Source Files\libbluray + + + Source Files\libbluray + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\decoders + + + Source Files\libbluray\decoders + + + Source Files\libbluray\decoders + + + Source Files\libbluray\decoders + + + Source Files\libbluray\decoders + + + Source Files\libbluray\decoders + + + Source Files\libbluray\hdmv + + + Source Files\libbluray\hdmv + + + Source Files\libbluray\hdmv + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\bdnav + + + Source Files\util + + + Source Files\file + + + Source Files\file + + + Source Files\file + + + Source Files\libbluray\decoders + + + Source Files\libbluray\decoders + + + Source Files\util + + + Source Files\libbluray\decoders + + + Source Files\libbluray\decoders + + + Source Files\file + + + Source Files\file + + + Source Files\util + + + Source Files\util + + + Source Files\libbluray\disc + + + Source Files\libbluray\disc + + + Source Files\libbluray\disc + + + Source Files\libbluray\disc + + + Source Files\util + + + Source Files\file + + + Source Files\util + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\bdnav + + + Source Files\libbluray\disc + + + + + Source Files + + + \ No newline at end of file diff --git a/src/file/dir_win32.c b/src/file/dir_win32.c index 5cbc3c8..4030896 100644 --- a/src/file/dir_win32.c +++ b/src/file/dir_win32.c @@ -76,7 +76,7 @@ static dir_data_t *_open_impl(const char *dirname) { dir_data_t *priv; char *filespec; - wchar_t wfilespec[MAX_PATH]; + wchar_t wfilespec[4096 + 1]; int result; filespec = str_printf("%s" DIR_SEP "*", dirname); @@ -84,7 +84,7 @@ static dir_data_t *_open_impl(const char *dirname) return NULL; } - result = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filespec, -1, wfilespec, MAX_PATH); + result = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filespec, -1, wfilespec, 4096); X_FREE(filespec); if (!result) { return NULL; diff --git a/src/file/dirs_win32.c b/src/file/dirs_win32.c index e165fea..3d07251 100644 --- a/src/file/dirs_win32.c +++ b/src/file/dirs_win32.c @@ -36,7 +36,7 @@ char *win32_get_font_dir(const char *font_file) { - wchar_t wdir[MAX_PATH]; + wchar_t wdir[MAX_PATH+1] = {0}; if (S_OK != SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, wdir)) { int lenght = GetWindowsDirectoryW(wdir, MAX_PATH); if (lenght == 0 || lenght > (MAX_PATH - 8)) { @@ -67,7 +67,7 @@ char *file_get_config_home(void) char *file_get_data_home(void) { - wchar_t wdir[MAX_PATH]; + wchar_t wdir[MAX_PATH+1] = {0}; /* Get the "Application Data" folder for the user */ if (S_OK == SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, @@ -92,7 +92,7 @@ char *file_get_cache_home(void) const char *file_get_config_system(const char *dir) { static char *appdir = NULL; - wchar_t wdir[MAX_PATH]; + wchar_t wdir[MAX_PATH+1] = {0}; if (!dir) { // first call diff --git a/src/file/dl_win32.c b/src/file/dl_win32.c index 6155ad6..c7e3eee 100644 --- a/src/file/dl_win32.c +++ b/src/file/dl_win32.c @@ -57,7 +57,7 @@ void *dl_dlopen(const char *path, const char *version) { (void)version; - wchar_t wname[MAX_PATH]; + wchar_t wname[MAX_PATH+1] = {0}; char *name; void *result; int iresult; @@ -125,7 +125,7 @@ const char *dl_get_path(void) if (!initialized) { initialized = 1; - static char path[MAX_PATH]; + static char path[MAX_PATH + 1]; HMODULE hModule; wchar_t wpath[MAX_PATH]; diff --git a/src/file/file_win32.c b/src/file/file_win32.c index 11aaf82..f551863 100644 --- a/src/file/file_win32.c +++ b/src/file/file_win32.c @@ -107,9 +107,9 @@ static BD_FILE_H *_file_open(const char* filename, const char *mode) { BD_FILE_H *file; FILE *fp; - wchar_t wfilename[MAX_PATH], wmode[8]; + wchar_t wfilename[4096 + 1] = {0}, wmode[8] = {0}; - if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename, -1, wfilename, MAX_PATH) || + if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename, -1, wfilename, 4096) || !MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, mode, -1, wmode, 8)) { BD_DEBUG(DBG_FILE, "Error opening file %s\n", filename); @@ -122,6 +122,9 @@ static BD_FILE_H *_file_open(const char* filename, const char *mode) return NULL; } + // Set file buffer + setvbuf(fp, NULL, _IOFBF, 6144 * 10); + file = calloc(1, sizeof(BD_FILE_H)); if (!file) { BD_DEBUG(DBG_FILE | DBG_CRIT, "Error opening file %s (out of memory)\n", filename); diff --git a/src/libbluray/bdnav/bdmv_parse.c b/src/libbluray/bdnav/bdmv_parse.c index e298ca3..2c310aa 100644 --- a/src/libbluray/bdnav/bdmv_parse.c +++ b/src/libbluray/bdnav/bdmv_parse.c @@ -59,6 +59,7 @@ int bdmv_parse_header(BITSTREAM *bs, uint32_t type, uint32_t *version) switch (ver) { case BDMV_VERSION_0100: case BDMV_VERSION_0200: + case BDMV_VERSION_0240: case BDMV_VERSION_0300: break; default: diff --git a/src/libbluray/bdnav/bdmv_parse.h b/src/libbluray/bdnav/bdmv_parse.h index 8f953a3..9dbbed5 100644 --- a/src/libbluray/bdnav/bdmv_parse.h +++ b/src/libbluray/bdnav/bdmv_parse.h @@ -27,6 +27,7 @@ #define BDMV_VERSION_0100 ('0' << 24 | '1' << 16 | '0' << 8 | '0') #define BDMV_VERSION_0200 ('0' << 24 | '2' << 16 | '0' << 8 | '0') +#define BDMV_VERSION_0240 ('0' << 24 | '2' << 16 | '4' << 8 | '0') #define BDMV_VERSION_0300 ('0' << 24 | '3' << 16 | '0' << 8 | '0') BD_PRIVATE int bdmv_parse_header(BITSTREAM *bs, uint32_t type, uint32_t *version); diff --git a/src/libbluray/bdnav/index_parse.c b/src/libbluray/bdnav/index_parse.c index 0deb617..300a1bf 100644 --- a/src/libbluray/bdnav/index_parse.c +++ b/src/libbluray/bdnav/index_parse.c @@ -105,12 +105,11 @@ static int _parse_index(BITSTREAM *bs, INDX_ROOT *index) index->num_titles = bs_read(bs, 16); if (!index->num_titles) { - BD_DEBUG(DBG_CRIT, "empty index\n"); - return 0; + BD_DEBUG(DBG_NAV, "empty index\n"); } index->titles = calloc(index->num_titles, sizeof(INDX_TITLE)); - if (!index->titles) { + if (index->num_titles && !index->titles) { BD_DEBUG(DBG_CRIT, "out of memory\n"); return 0; } diff --git a/src/libbluray/bdnav/mpls_data.h b/src/libbluray/bdnav/mpls_data.h index 2ceac92..d23d40e 100644 --- a/src/libbluray/bdnav/mpls_data.h +++ b/src/libbluray/bdnav/mpls_data.h @@ -47,6 +47,7 @@ typedef struct uint8_t sv_num_pip_pg_ref; uint8_t *sv_secondary_audio_ref; uint8_t *sv_pip_pg_ref; + uint8_t ss_offset_sequence_id; } MPLS_STREAM; typedef struct @@ -107,6 +108,7 @@ typedef struct uint8_t random_access_flag; uint8_t audio_mix_flag; uint8_t lossless_bypass_flag; + uint8_t mvc_base_view_r_flag; } MPLS_AI; typedef struct diff --git a/src/libbluray/bdnav/mpls_parse.c b/src/libbluray/bdnav/mpls_parse.c index 358b634..569c015 100644 --- a/src/libbluray/bdnav/mpls_parse.c +++ b/src/libbluray/bdnav/mpls_parse.c @@ -77,9 +77,10 @@ _parse_appinfo(BITSTREAM *bits, MPLS_AI *ai) ai->random_access_flag = bs_read(bits, 1); ai->audio_mix_flag = bs_read(bits, 1); ai->lossless_bypass_flag = bs_read(bits, 1); + ai->mvc_base_view_r_flag = bs_read(bits, 1); #if 0 // Reserved - bs_skip(bits, 13); + bs_skip(bits, 12); bs_seek_byte(bits, pos + len); #endif return 1; @@ -194,6 +195,7 @@ _parse_stream(BITSTREAM *bits, MPLS_STREAM *s) break; }; s->lang[3] = '\0'; + s->ss_offset_sequence_id = 0xFF; if (bs_seek_byte(bits, pos + len) < 0) { return 0; @@ -958,6 +960,99 @@ _parse_subpath_extension(BITSTREAM *bits, MPLS_PL *pl) return 0; } +static int +_parse_stn_ss_extension(BITSTREAM *bits, MPLS_PL *pl) +{ + int ii, s; + int64_t pos; + + for (ii = 0; ii < pl->list_count; ii++) { + uint32_t len = bs_read(bits, 16); + pos = bs_pos(bits) >> 3; + int Fixed_offset_during_PopUp_flag = bs_read(bits, 1); + bs_skip(bits, 15); // reserved + + for (s = 0; s < pl->play_item[ii].stn.num_video; s++) { + // stream_entry + uint32_t slen = bs_read(bits, 8); + bs_skip(bits, slen * 8); + + // stream_attributes_ss + slen = bs_read(bits, 8); + bs_skip(bits, slen * 8); + + bs_skip(bits, 10); // reserved + bs_skip(bits, 6); // number_of_offset_sequences + } + + for (s = 0; s < pl->play_item[ii].stn.num_pg; s++) { + pl->play_item[ii].stn.pg[s].ss_offset_sequence_id = bs_read(bits, 8); + + bs_skip(bits, 4); // reserved + bs_skip(bits, 1); // dialog_region_offset_valid_flag + int is_SS_PG = bs_read(bits, 1); + int is_top_AS_PG_textST = bs_read(bits, 1); + int is_bottom_AS_PG_textST = bs_read(bits, 1); + if (is_SS_PG) { + // stream_entry left eye + uint32_t slen = bs_read(bits, 8); + bs_skip(bits, slen * 8); + + // stream_entry right eye + slen = bs_read(bits, 8); + bs_skip(bits, slen * 8); + + bs_skip(bits, 8); // reserved + bs_skip(bits, 8); // PG offset + } + if (is_top_AS_PG_textST) { + // stream_entry + uint32_t slen = bs_read(bits, 8); + bs_skip(bits, slen * 8); + + bs_skip(bits, 8); // reserved + bs_skip(bits, 8); // PG offset + } + if (is_bottom_AS_PG_textST) { + // stream_entry + uint32_t slen = bs_read(bits, 8); + bs_skip(bits, slen * 8); + + bs_skip(bits, 8); // reserved + bs_skip(bits, 8); // PG offset + } + } + + for (s = 0; s < pl->play_item[ii].stn.num_ig; s++) { + if (Fixed_offset_during_PopUp_flag) + bs_skip(bits, 8); + else + pl->play_item[ii].stn.ig[s].ss_offset_sequence_id = bs_read(bits, 8); + + bs_skip(bits, 16); // IG_Plane_offset_during_BB_video + bs_skip(bits, 7); // reserved + int is_SS_IG = bs_read(bits, 1); + if (is_SS_IG) { + // stream_entry left eye + uint32_t slen = bs_read(bits, 8); + bs_skip(bits, slen * 8); + + // stream_entry right eye + slen = bs_read(bits, 8); + bs_skip(bits, slen * 8); + + bs_skip(bits, 8); // reserved + bs_skip(bits, 8); // PG offset + } + } + + // Skip to next play item + bs_seek_byte(bits, pos + len); + } + + return 0; +} + static int _parse_mpls_extension(BITSTREAM *bits, int id1, int id2, void *handle) { @@ -972,7 +1067,7 @@ _parse_mpls_extension(BITSTREAM *bits, int id1, int id2, void *handle) if (id1 == 2) { if (id2 == 1) { - return 0; + return _parse_stn_ss_extension(bits, pl); } if (id2 == 2) { // SubPath entries extension diff --git a/src/libbluray/bluray.c b/src/libbluray/bluray.c index 883b35c..8220787 100644 --- a/src/libbluray/bluray.c +++ b/src/libbluray/bluray.c @@ -51,8 +51,10 @@ #include "disc/disc.h" #include "disc/enc_info.h" #include "file/file.h" +#ifdef USING_BDJAVA #include "bdj/bdj.h" #include "bdj/bdjo_parse.h" +#endif #include // SEEK_ #include @@ -150,9 +152,11 @@ struct bluray { uint8_t hdmv_suspended; /* BD-J */ +#ifdef USING_BDJAVA BDJAVA *bdjava; BDJ_STORAGE bdjstorage; uint8_t bdj_wait_start; /* BD-J has selected playlist (prefetch) but not yet started playback */ +#endif /* HDMV graphics */ GRAPHICS_CONTROLLER *graphics_controller; @@ -166,10 +170,12 @@ struct bluray { uint64_t gc_wakeup_pos; /* stream position of gc_wakeup_time */ /* ARGB overlay output */ +#ifdef USING_BDJAVA void *argb_overlay_proc_handle; bd_argb_overlay_proc_f argb_overlay_proc; BD_ARGB_BUFFER *argb_buffer; BD_MUTEX argb_buffer_mutex; +#endif }; /* Stream Packet Number = byte offset / 192. Avoid 64-bit division. */ @@ -532,6 +538,16 @@ static void _update_uo_mask(BLURAY *bd) bd->uo_mask = new_mask; } +#ifdef USING_BDJAVA +void bd_set_bdj_uo_mask(BLURAY *bd, unsigned mask) +{ + bd->title_uo_mask.title_search = !!(mask & BDJ_TITLE_SEARCH_MASK); + bd->title_uo_mask.menu_call = !!(mask & BDJ_MENU_CALL_MASK); + + _update_uo_mask(bd); +} +#endif + static void _update_hdmv_uo_mask(BLURAY *bd) { uint32_t mask = hdmv_vm_get_uo_mask(bd->hdmv_vm); @@ -899,6 +915,7 @@ static int _run_gc(BLURAY *bd, gc_ctrl_e msg, uint32_t param) static void _check_bdj(BLURAY *bd) { +#ifdef USING_BDJAVA if (!bd->disc_info.bdj_handled) { if (!bd->disc || bd->disc_info.bdj_detected) { @@ -911,6 +928,7 @@ static void _check_bdj(BLURAY *bd) } } } +#endif /* USING_BDJAVA */ } static void _fill_disc_info(BLURAY *bd, BD_ENC_INFO *enc_info) @@ -940,7 +958,7 @@ static void _fill_disc_info(BLURAY *bd, BD_ENC_INFO *enc_info) bd->disc_info.num_unsupported_titles = 0; bd->disc_info.bdj_detected = 0; - bd->disc_info.bdj_supported = 1; + bd->disc_info.bdj_supported = 0; bd->disc_info.num_titles = 0; bd->disc_info.titles = NULL; @@ -1104,22 +1122,17 @@ const BLURAY_DISC_INFO *bd_get_disc_info(BLURAY *bd) } /* - * bdj callbacks + * bdj */ -void bd_set_bdj_uo_mask(BLURAY *bd, unsigned mask) -{ - bd->title_uo_mask.title_search = !!(mask & BDJ_TITLE_SEARCH_MASK); - bd->title_uo_mask.menu_call = !!(mask & BDJ_MENU_CALL_MASK); - - _update_uo_mask(bd); -} - +#ifdef USING_BDJAVA const uint8_t *bd_get_aacs_data(BLURAY *bd, int type) { return disc_get_data(bd->disc, type); } +#endif +#ifdef USING_BDJAVA uint64_t bd_get_uo_mask(BLURAY *bd) { /* internal function. Used by BD-J. */ @@ -1134,25 +1147,16 @@ uint64_t bd_get_uo_mask(BLURAY *bd) return mask.u64; } +#endif +#ifdef USING_BDJAVA void bd_set_bdj_kit(BLURAY *bd, int mask) { _queue_event(bd, BD_EVENT_KEY_INTEREST_TABLE, mask); } +#endif -int bd_bdj_sound_effect(BLURAY *bd, int id) -{ - if (bd->sound_effects && id >= bd->sound_effects->num_sounds) { - return -1; - } - if (id < 0 || id > 0xff) { - return -1; - } - - _queue_event(bd, BD_EVENT_SOUND_EFFECT, id); - return 0; -} - +#ifdef USING_BDJAVA void bd_select_rate(BLURAY *bd, float rate, int reason) { if (reason == BDJ_PLAYBACK_STOP) { @@ -1171,26 +1175,9 @@ void bd_select_rate(BLURAY *bd, float rate, int reason) _queue_event(bd, BD_EVENT_STILL, 0); } } +#endif -int bd_bdj_seek(BLURAY *bd, int playitem, int playmark, int64_t time) -{ - bd_mutex_lock(&bd->mutex); - - if (playitem > 0) { - bd_seek_playitem(bd, playitem); - } - if (playmark >= 0) { - bd_seek_mark(bd, playmark); - } - if (time >= 0) { - bd_seek_time(bd, time); - } - - bd_mutex_unlock(&bd->mutex); - - return 1; -} - +#ifdef USING_BDJAVA int bd_set_virtual_package(BLURAY *bd, const char *vp_path, int psr_init_backup) { bd_mutex_lock(&bd->mutex); @@ -1216,12 +1203,16 @@ int bd_set_virtual_package(BLURAY *bd, const char *vp_path, int psr_init_backup) return 0; } +#endif +#ifdef USING_BDJAVA BD_DISC *bd_get_disc(BLURAY *bd) { return bd ? bd->disc : NULL; } +#endif +#ifdef USING_BDJAVA uint32_t bd_reg_read(BLURAY *bd, int psr, int reg) { if (psr) { @@ -1230,7 +1221,9 @@ uint32_t bd_reg_read(BLURAY *bd, int psr, int reg) return bd_gpr_read(bd->regs, reg); } } +#endif +#ifdef USING_BDJAVA int bd_reg_write(BLURAY *bd, int psr, int reg, uint32_t value, uint32_t psr_value_mask) { if (psr) { @@ -1247,7 +1240,9 @@ int bd_reg_write(BLURAY *bd, int psr, int reg, uint32_t value, uint32_t psr_valu return bd_gpr_write(bd->regs, reg, value); } } +#endif +#ifdef USING_BDJAVA BD_ARGB_BUFFER *bd_lock_osd_buffer(BLURAY *bd) { bd_mutex_lock(&bd->argb_buffer_mutex); @@ -1333,13 +1328,11 @@ void bd_bdj_osd_cb(BLURAY *bd, const unsigned *img, int w, int h, bd->argb_buffer->dirty[BD_OVERLAY_IG].y1 = 0; } } - -/* - * BD-J - */ +#endif static int _start_bdj(BLURAY *bd, unsigned title) { +#ifdef USING_BDJAVA if (bd->bdjava == NULL) { const char *root = disc_root(bd->disc); bd->bdjava = bdj_open(root, bd, bd->disc_info.bdj_disc_id, &bd->bdjstorage); @@ -1349,8 +1342,14 @@ static int _start_bdj(BLURAY *bd, unsigned title) } return !bdj_process_event(bd->bdjava, BDJ_EVENT_START, title); +#else + (void)bd; + BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Title %d: BD-J not compiled in\n", title); + return 0; +#endif } +#ifdef USING_BDJAVA static int _bdj_event(BLURAY *bd, unsigned ev, unsigned param) { if (bd->bdjava != NULL) { @@ -1358,7 +1357,11 @@ static int _bdj_event(BLURAY *bd, unsigned ev, unsigned param) } return -1; } +#else +#define _bdj_event(bd, ev, param) do{}while(0) +#endif +#ifdef USING_BDJAVA static void _stop_bdj(BLURAY *bd) { if (bd->bdjava != NULL) { @@ -1367,7 +1370,11 @@ static void _stop_bdj(BLURAY *bd) _queue_event(bd, BD_EVENT_KEY_INTEREST_TABLE, 0); } } +#else +#define _stop_bdj(bd) do{}while(0) +#endif +#ifdef USING_BDJAVA static void _close_bdj(BLURAY *bd) { if (bd->bdjava != NULL) { @@ -1375,6 +1382,20 @@ static void _close_bdj(BLURAY *bd) bd->bdjava = NULL; } } +#else +#define _close_bdj(bd) do{}while(0) +#endif + +#ifdef USING_BDJAVA +static void _storage_free(BLURAY *bd) +{ + X_FREE(bd->bdjstorage.cache_root); + X_FREE(bd->bdjstorage.persistent_root); + X_FREE(bd->bdjstorage.classpath); +} +#else +#define _storage_free(bd) do{}while(0) +#endif /* * open / close @@ -1401,6 +1422,7 @@ BLURAY *bd_init(void) } bd_mutex_init(&bd->mutex); +#ifdef USING_BDJAVA bd_mutex_init(&bd->argb_buffer_mutex); env = getenv("LIBBLURAY_PERSISTENT_STORAGE"); @@ -1408,6 +1430,7 @@ BLURAY *bd_init(void) int v = (!strcmp(env, "yes")) ? 1 : (!strcmp(env, "no")) ? 0 : atoi(env); bd->bdjstorage.no_persistent_storage = !v; } +#endif BD_DEBUG(DBG_BLURAY, "BLURAY initialized!\n"); @@ -1522,7 +1545,9 @@ void bd_close(BLURAY *bd) disc_close(&bd->disc); bd_mutex_destroy(&bd->mutex); +#ifdef USING_BDJAVA bd_mutex_destroy(&bd->argb_buffer_mutex); +#endif BD_DEBUG(DBG_BLURAY, "BLURAY destroyed!\n"); @@ -1654,6 +1679,25 @@ int64_t bd_seek_time(BLURAY *bd, uint64_t tick) return bd->s_pos; } +int64_t bd_find_seek_point(BLURAY *bd, uint64_t tick) +{ + uint32_t clip_pkt, out_pkt; + NAV_CLIP *clip; + + tick /= 2; + + if (bd->title && + tick < bd->title->duration) { + + // Find the closest access unit to the requested position + clip = nav_time_search(bd->title, (uint32_t)tick, &clip_pkt, &out_pkt); + + return (int64_t)out_pkt * 192; + } + + return bd->s_pos; +} + uint64_t bd_tell_time(BLURAY *bd) { uint32_t clip_pkt = 0, out_pkt = 0, out_time = 0; @@ -2394,7 +2438,26 @@ int bd_select_playlist(BLURAY *bd, uint32_t playlist) return result; } -/* BD-J callback */ +#ifdef USING_BDJAVA +int bd_bdj_seek(BLURAY *bd, int playitem, int playmark, int64_t time) +{ + bd_mutex_lock(&bd->mutex); + + if (playitem > 0) { + bd_seek_playitem(bd, playitem); + } + if (playmark >= 0) { + bd_seek_mark(bd, playmark); + } + if (time >= 0) { + bd_seek_time(bd, time); + } + + bd_mutex_unlock(&bd->mutex); + + return 1; +} + static int _play_playlist_at(BLURAY *bd, int playlist, int playitem, int playmark, int64_t time) { if (playlist < 0) { @@ -2406,14 +2469,15 @@ static int _play_playlist_at(BLURAY *bd, int playlist, int playitem, int playmar return 0; } +#ifdef USING_BDJAVA bd->bdj_wait_start = 1; /* playback is triggered by bd_select_rate() */ +#endif bd_bdj_seek(bd, playitem, playmark, time); return 1; } -/* BD-J callback */ int bd_play_playlist_at(BLURAY *bd, int playlist, int playitem, int playmark, int64_t time) { int result; @@ -2426,6 +2490,21 @@ int bd_play_playlist_at(BLURAY *bd, int playlist, int playitem, int playmark, in return result; } +int bd_bdj_sound_effect(BLURAY *bd, int id) +{ + if (bd->sound_effects && id >= bd->sound_effects->num_sounds) { + return -1; + } + if (id < 0 || id > 0xff) { + return -1; + } + + _queue_event(bd, BD_EVENT_SOUND_EFFECT, id); + return 0; +} + +#endif /* USING_BDJAVA */ + // Select a title for playback // The title index is an index into the list // established by bd_get_titles() @@ -2651,6 +2730,7 @@ static BLURAY_TITLE_INFO* _fill_title_info(NAV_TITLE* title, uint32_t title_idx, NAV_CLIP *nc = &title->clip_list.clip[ii]; memcpy(ci->clip_id, pi->clip->clip_id, sizeof(ci->clip_id)); + ci->idx = nc->clip_id; ci->pkt_count = nc->end_pkt - nc->start_pkt; ci->start_time = (uint64_t)nc->title_time * 2; ci->in_time = (uint64_t)pi->in_time * 2; @@ -2675,6 +2755,8 @@ static BLURAY_TITLE_INFO* _fill_title_info(NAV_TITLE* title, uint32_t title_idx, } } + title_info->mvc_base_view_r_flag = title->pl->app_info.mvc_base_view_r_flag; + return title_info; error: @@ -2802,7 +2884,7 @@ int bd_set_player_setting(BLURAY *bd, uint32_t idx, uint32_t value) bd_mutex_unlock(&bd->mutex); return result; } - +#ifdef USING_BDJAVA if (idx == BLURAY_PLAYER_SETTING_PERSISTENT_STORAGE) { if (bd->title_type != title_undef) { BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Can't disable persistent storage during playback\n"); @@ -2811,6 +2893,7 @@ int bd_set_player_setting(BLURAY *bd, uint32_t idx, uint32_t value) bd->bdjstorage.no_persistent_storage = !value; return 1; } +#endif for (i = 0; i < sizeof(map) / sizeof(map[0]); i++) { if (idx == map[i].idx) { @@ -2835,6 +2918,7 @@ int bd_set_player_setting_str(BLURAY *bd, uint32_t idx, const char *s) case BLURAY_PLAYER_SETTING_COUNTRY_CODE: return bd_set_player_setting(bd, idx, str_to_uint32(s, 2)); +#ifdef USING_BDJAVA case BLURAY_PLAYER_CACHE_ROOT: bd_mutex_lock(&bd->mutex); X_FREE(bd->bdjstorage.cache_root); @@ -2850,6 +2934,7 @@ int bd_set_player_setting_str(BLURAY *bd, uint32_t idx, const char *s) bd_mutex_unlock(&bd->mutex); BD_DEBUG(DBG_BDJ, "Persistent root dir set to %s\n", bd->bdjstorage.persistent_root); return 1; +#endif /* USING_BDJAVA */ default: return 0; @@ -3265,7 +3350,7 @@ static int _play_title(BLURAY *bd, unsigned title) return 0; } -/* BD-J callback */ +#ifdef USING_BDJAVA int bd_play_title_internal(BLURAY *bd, unsigned title) { /* used by BD-J. Like bd_play_title() but bypasses UO mask checks. */ @@ -3275,6 +3360,7 @@ int bd_play_title_internal(BLURAY *bd, unsigned title) bd_mutex_unlock(&bd->mutex); return ret; } +#endif int bd_play(BLURAY *bd) { @@ -3505,6 +3591,7 @@ static int _read_ext(BLURAY *bd, unsigned char *buf, int len, BD_EVENT *event) return 0; } +#ifdef USING_BDJAVA if (bd->title_type == title_bdj) { if (bd->end_of_playlist == 1) { _bdj_event(bd, BDJ_EVENT_END_OF_PLAYLIST, bd_psr_read(bd->regs, PSR_PLAYLIST)); @@ -3523,6 +3610,7 @@ static int _read_ext(BLURAY *bd, unsigned char *buf, int len, BD_EVENT *event) return 0; } } +#endif int bytes = _bd_read(bd, buf, len); @@ -3584,9 +3672,11 @@ static int _set_rate(BLURAY *bd, uint32_t rate) return -1; } +#ifdef USING_BDJAVA if (bd->title_type == title_bdj) { return _bdj_event(bd, BDJ_EVENT_RATE, rate); } +#endif return 0; } @@ -3613,8 +3703,10 @@ int bd_mouse_select(BLURAY *bd, int64_t pts, uint16_t x, uint16_t y) if (bd->title_type == title_hdmv) { result = _run_gc(bd, GC_CTRL_MOUSE_MOVE, param); +#ifdef USING_BDJAVA } else if (bd->title_type == title_bdj) { result = _bdj_event(bd, BDJ_EVENT_MOUSE, param); +#endif } bd_mutex_unlock(&bd->mutex); @@ -3636,8 +3728,10 @@ int bd_user_input(BLURAY *bd, int64_t pts, uint32_t key) if (bd->title_type == title_hdmv) { result = _run_gc(bd, GC_CTRL_VK_KEY, key); +#ifdef USING_BDJAVA } else if (bd->title_type == title_bdj) { result = _bdj_event(bd, BDJ_EVENT_VK_KEY, key); +#endif } bd_mutex_unlock(&bd->mutex); @@ -3664,6 +3758,7 @@ void bd_register_overlay_proc(BLURAY *bd, void *handle, bd_overlay_proc_f func) void bd_register_argb_overlay_proc(BLURAY *bd, void *handle, bd_argb_overlay_proc_f func, BD_ARGB_BUFFER *buf) { +#ifdef USING_BDJAVA if (!bd) { return; } @@ -3675,6 +3770,12 @@ void bd_register_argb_overlay_proc(BLURAY *bd, void *handle, bd_argb_overlay_pro bd->argb_buffer = buf; bd_mutex_unlock(&bd->argb_buffer_mutex); +#else + (void)bd; + (void)handle; + (void)func; + (void)buf; +#endif } int bd_get_sound_effect(BLURAY *bd, unsigned sound_id, BLURAY_SOUND_EFFECT *effect) @@ -3825,10 +3926,44 @@ void bd_free_mobj(struct mobj_objects *obj) struct bdjo_data *bd_read_bdjo(const char *bdjo_file) { +#ifdef USING_BDJAVA return bdjo_parse(bdjo_file); +#else + (void)bdjo_file; + return NULL; +#endif } void bd_free_bdjo(struct bdjo_data *obj) { +#ifdef USING_BDJAVA bdjo_free(&obj); +#else + (void)obj; +#endif +} + +int bd_get_clip_infos(BLURAY *bd, unsigned clip, uint64_t *clip_start_time, uint64_t *stream_start_time, uint64_t *pos, uint64_t *duration) +{ + if (bd && bd->title && bd->title->clip_list.count > clip) { + if (clip_start_time) + *clip_start_time = (uint64_t)bd->title->clip_list.clip[clip].title_time << 1; + if (stream_start_time) + *stream_start_time = (uint64_t)bd->title->clip_list.clip[clip].in_time << 1; + if (pos) + *pos = (uint64_t)bd->title->clip_list.clip[clip].title_pkt * 192; + if (duration) + *duration = (uint64_t)bd->title->clip_list.clip[clip].duration << 1; + + return 1; + } + return 0; +} + +struct mpls_pl* bd_get_title_mpls(BLURAY * bd) +{ + if (bd && bd->title) { + return bd->title->pl; + } + return NULL; } diff --git a/src/libbluray/bluray.h b/src/libbluray/bluray.h index 70e6a84..0cd6047 100644 --- a/src/libbluray/bluray.h +++ b/src/libbluray/bluray.h @@ -32,6 +32,7 @@ extern "C" { */ #include +#include "bdnav/clpi_data.h" #define TITLES_ALL 0 /**< all titles. */ #define TITLES_FILTER_DUP_TITLE 0x01 /**< remove duplicate titles. */ @@ -90,7 +91,7 @@ typedef struct { /* BD-J info (valid only if disc uses BD-J) */ uint8_t bdj_detected; /* 1 if disc uses BD-J */ - uint8_t bdj_supported; /* (deprecated) */ + uint8_t bdj_supported; /* 1 if BD-J support was compiled in */ uint8_t libjvm_detected; /* 1 if usable Java VM was found */ uint8_t bdj_handled; /* 1 if usable Java VM + libbluray.jar was found */ @@ -224,6 +225,7 @@ typedef struct bd_stream_info { } BLURAY_STREAM_INFO; typedef struct bd_clip { + uint32_t idx; uint32_t pkt_count; uint8_t still_mode; uint16_t still_time; /* seconds */ @@ -274,6 +276,8 @@ typedef struct bd_title_info { BLURAY_CLIP_INFO *clips; BLURAY_TITLE_CHAPTER *chapters; BLURAY_TITLE_MARK *marks; + + uint8_t mvc_base_view_r_flag; } BLURAY_TITLE_INFO; /* @@ -480,6 +484,16 @@ int bd_select_playlist(BLURAY *bd, uint32_t playlist); */ uint32_t bd_get_current_title(BLURAY *bd); +/** + * + * Find the byte position to specific time in 90Khz ticks + * + * @param bd BLURAY ojbect + * @param tick tick count + * @return byte position + */ +int64_t bd_find_seek_point(BLURAY *bd, uint64_t tick); + /** * * Read from currently selected title file, decrypt if possible @@ -1039,7 +1053,6 @@ int bd_mouse_select(BLURAY *bd, int64_t pts, uint16_t x, uint16_t y); /* access to internal information */ -struct clpi_cl; /** * * Get copy of clip information for requested playitem. @@ -1092,6 +1105,28 @@ void bd_stop_bdj(BLURAY *bd); // shutdown BD-J and clean up resources */ int bd_read_file(BLURAY *, const char *path, void **data, int64_t *size); +/** + * + * Get information about the clip + * + * @param bd BLURAY object + * @param clip clip index + * @param clip_start_time start of the clip (in the total title) (in 90khz) + * @param stream_start_time first pts in the clip (in 90khz) + * @param byte position of the clip (absolute) + * @param duration duration of the clip (in 90khz) + */ +int bd_get_clip_infos(BLURAY *bd, unsigned clip, uint64_t *clip_start_time, uint64_t *stream_start_time, uint64_t *pos, uint64_t *duration); + +/** + * Get the MPLS struct of the current title + * + * @param bd BLURAY object + * @return the MPLS struct + * + * Lifetime of the MPLS pointer is limited to the lifetime of the BD title + */ +struct mpls_pl* bd_get_title_mpls(BLURAY * bd); #ifdef __cplusplus } diff --git a/src/libbluray/disc/disc.c b/src/libbluray/disc/disc.c index be6a279..e96539a 100644 --- a/src/libbluray/disc/disc.c +++ b/src/libbluray/disc/disc.c @@ -38,7 +38,9 @@ #include #include +#ifdef ENABLE_UDF #include "udf_fs.h" +#endif struct bd_disc { BD_MUTEX ovl_mutex; /* protect access to overlay root */ @@ -75,7 +77,7 @@ static BD_FILE_H *_bdrom_open_path(void *p, const char *rel_path) return NULL; } - fp = file_open(abs_path, "rb"); + fp = file_open(abs_path, "rbS"); X_FREE(abs_path); return fp; @@ -316,6 +318,7 @@ BD_DISC *disc_open(const char *device_path, _set_paths(p, device_path); /* check if disc root directory can be opened. If not, treat it as device/image file. */ +#ifdef ENABLE_UDF BD_DIR_H *dp_img = device_path ? dir_open(device_path) : NULL; if (!dp_img) { void *udf = udf_image_open(device_path, p_fs ? p_fs->fs_handle : NULL, p_fs ? p_fs->read_blocks : NULL); @@ -336,6 +339,7 @@ BD_DISC *disc_open(const char *device_path, dir_close(dp_img); BD_DEBUG(DBG_FILE, "%s does not seem to be image file or device node\n", device_path); } +#endif struct dec_dev dev = { p->fs_handle, p->pf_file_open_bdrom, p, (file_openFp)disc_open_path, p->disc_root, device_path }; p->dec = dec_init(&dev, enc_info, keyfile_path, regs, psr_read, psr_write);