diff -Nru libbluray-0.8.0/build-aux/ltmain.sh libbluray-0.8.1/build-aux/ltmain.sh --- libbluray-0.8.0/build-aux/ltmain.sh 2015-04-15 08:40:01.000000000 +0000 +++ libbluray-0.8.1/build-aux/ltmain.sh 2015-05-15 09:42:14.000000000 +0000 @@ -70,7 +70,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.10ubuntu1 +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.11 # automake: $automake_version # autoconf: $autoconf_version # @@ -80,7 +80,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.2 Debian-2.4.2-1.10ubuntu1" +VERSION="2.4.2 Debian-2.4.2-1.11" TIMESTAMP="" package_revision=1.3337 diff -Nru libbluray-0.8.0/ChangeLog libbluray-0.8.1/ChangeLog --- libbluray-0.8.0/ChangeLog 2015-04-15 08:43:49.000000000 +0000 +++ libbluray-0.8.1/ChangeLog 2015-05-15 09:25:06.000000000 +0000 @@ -1,3 +1,12 @@ +2015-05-15: Version 0.8.1 +- Notify application when UO mask changes. +- Improved error resilience. +- Improved BD-J compability. +- Fix crash after bd_open(NULL). +- Fix compability problem with libbdplus. +- Fix memory leak in UDF filesystem parser. +- Fix crash in freetype. + 2015-04-15: Version 0.8.0 - Add security checks to BD-J. - Add support for UDF image files and unmounted discs. @@ -6,7 +15,7 @@ - Add /usr/share/libbluray/lib/ to .jar file search paths. - Add BD_EVENT_PLAYLIST_STOP (playlist playback is interrupted). - Accept directory name (without .jar file name) in LIBBLURAY_CP. -- Improved error resilence. +- Improved error resilience. - Improve BD-J compability. - Fix Java 8u40 compability. - Fix infinite loop with some broken HDMV menus. @@ -51,7 +60,7 @@ - Added disc application info to BLURAY_DISC_INFO. - Added bd_set_rate(). - Added color keys (RED, GREEN, YELLOW, BLUE). -- Improved error resilence. +- Improved error resilience. - Fix build without libxml. 2013-12-21: Version 0.5.0 diff -Nru libbluray-0.8.0/configure libbluray-0.8.1/configure --- libbluray-0.8.0/configure 2015-04-15 08:40:04.000000000 +0000 +++ libbluray-0.8.1/configure 2015-05-15 09:42:17.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libbluray 0.8.0. +# Generated by GNU Autoconf 2.69 for libbluray 0.8.1. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='libbluray' PACKAGE_TARNAME='libbluray' -PACKAGE_VERSION='0.8.0' -PACKAGE_STRING='libbluray 0.8.0' +PACKAGE_VERSION='0.8.1' +PACKAGE_STRING='libbluray 0.8.1' PACKAGE_BUGREPORT='http://www.videolan.org/developers/libbluray.html' PACKAGE_URL='' @@ -1418,7 +1418,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libbluray 0.8.0 to adapt to many kinds of systems. +\`configure' configures libbluray 0.8.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1488,7 +1488,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libbluray 0.8.0:";; + short | recursive ) echo "Configuration of libbluray 0.8.1:";; esac cat <<\_ACEOF @@ -1640,7 +1640,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libbluray configure 0.8.0 +libbluray configure 0.8.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2066,7 +2066,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libbluray $as_me 0.8.0, which was +It was created by libbluray $as_me 0.8.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3001,7 +3001,7 @@ # Define the identity of the package. PACKAGE='libbluray' - VERSION='0.8.0' + VERSION='0.8.1' cat >>confdefs.h <<_ACEOF @@ -15351,10 +15351,10 @@ BLURAY_VERSION_MINOR=8 -BLURAY_VERSION_MICRO=0 +BLURAY_VERSION_MICRO=1 -LT_VERSION_INFO="9:0:8" +LT_VERSION_INFO="9:1:8" @@ -15998,7 +15998,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libbluray $as_me 0.8.0, which was +This file was extended by libbluray $as_me 0.8.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16064,7 +16064,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libbluray config.status 0.8.0 +libbluray config.status 0.8.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru libbluray-0.8.0/configure.ac libbluray-0.8.1/configure.ac --- libbluray-0.8.0/configure.ac 2015-04-10 06:48:23.000000000 +0000 +++ libbluray-0.8.1/configure.ac 2015-05-15 09:25:06.000000000 +0000 @@ -1,7 +1,7 @@ dnl library version number m4_define([bluray_major], 0) m4_define([bluray_minor], 8) -m4_define([bluray_micro], 0) +m4_define([bluray_micro], 1) m4_define([bluray_version],[bluray_major.bluray_minor.bluray_micro]) dnl shared library version (.so version) @@ -13,7 +13,7 @@ dnl Library file name will be libbluray.so.(current-age).age.revision dnl m4_define([lt_current], 9) -m4_define([lt_revision], 0) +m4_define([lt_revision], 1) m4_define([lt_age], 8) dnl initilization diff -Nru libbluray-0.8.0/contrib/libudfread/src/udfread.c libbluray-0.8.1/contrib/libudfread/src/udfread.c --- libbluray-0.8.0/contrib/libudfread/src/udfread.c 2015-04-15 08:32:40.000000000 +0000 +++ libbluray-0.8.1/contrib/libudfread/src/udfread.c 2015-05-15 09:37:59.000000000 +0000 @@ -656,6 +656,8 @@ free(p->files); } + free(p); + *pp = NULL; } } diff -Nru libbluray-0.8.0/debian/changelog libbluray-0.8.1/debian/changelog --- libbluray-0.8.0/debian/changelog 2015-05-15 14:44:34.000000000 +0000 +++ libbluray-0.8.1/debian/changelog 2015-05-24 21:20:37.000000000 +0000 @@ -1,8 +1,16 @@ -libbluray (1:0.8.0-2~ppa1) vivid; urgency=low +libbluray (1:0.8.1-1~ppa1) vivid; urgency=low * Backported from Debian unstable. - -- Nate Muench Fri, 15 May 2015 09:44:19 -0500 + -- Nate Muench Sun, 24 May 2015 16:20:09 -0500 + +libbluray (1:0.8.1-1) unstable; urgency=medium + + * New upstream release. + * debian/patches/05_bd_open-return-NULL-if-disc-root-is-NULL.patch: Removed, + included upstream. + + -- Sebastian Ramacher Sat, 23 May 2015 16:58:44 +0200 libbluray (1:0.8.0-2) unstable; urgency=medium diff -Nru libbluray-0.8.0/debian/patches/05_bd_open-return-NULL-if-disc-root-is-NULL.patch libbluray-0.8.1/debian/patches/05_bd_open-return-NULL-if-disc-root-is-NULL.patch --- libbluray-0.8.0/debian/patches/05_bd_open-return-NULL-if-disc-root-is-NULL.patch 2015-05-13 21:11:26.000000000 +0000 +++ libbluray-0.8.1/debian/patches/05_bd_open-return-NULL-if-disc-root-is-NULL.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -Description: bd_open(): return NULL if disc root is NULL - Fixes crash when disc files are accessed later. -Origin: upstream, - http://git.videolan.org/?p=libbluray.git;a=commit;h=ac97f9c02ab9b939712fae5e8798c40952624580 -Last-Update: 2015-05-13 -Bug-Debian: https://bugs.debian.org/785159 - ---- a/src/libbluray/bluray.c -+++ b/src/libbluray/bluray.c -@@ -1362,7 +1362,10 @@ - return NULL; - } - -- bd_open_disc(bd, device_path, keyfile_path); -+ if (!bd_open_disc(bd, device_path, keyfile_path)) { -+ bd_close(bd); -+ return NULL; -+ } - - return bd; - } diff -Nru libbluray-0.8.0/debian/patches/series libbluray-0.8.1/debian/patches/series --- libbluray-0.8.0/debian/patches/series 2015-05-13 21:09:37.000000000 +0000 +++ libbluray-0.8.1/debian/patches/series 2015-05-23 14:57:04.000000000 +0000 @@ -2,4 +2,3 @@ 02_online-image.patch 03_split-jar-build-for-arch-all.patch 04_kfreebsd-include.patch -05_bd_open-return-NULL-if-disc-root-is-NULL.patch diff -Nru libbluray-0.8.0/debian/watch libbluray-0.8.1/debian/watch --- libbluray-0.8.0/debian/watch 2014-06-12 17:52:24.000000000 +0000 +++ libbluray-0.8.1/debian/watch 2015-05-23 14:55:40.000000000 +0000 @@ -1,4 +1,4 @@ version=3 -opts=dversionmangle=s/\+dfsg\d*$// \ +opts=downloadurlmangle=s/^ftp/http/ \ http://www.videolan.org/developers/libbluray.html \ ftp://ftp.videolan.org/pub/videolan/libbluray/.*/libbluray-(.*)\.tar\.bz2 diff -Nru libbluray-0.8.0/src/examples/bdsplice.c libbluray-0.8.1/src/examples/bdsplice.c --- libbluray-0.8.0/src/examples/bdsplice.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/examples/bdsplice.c 2015-05-15 09:25:06.000000000 +0000 @@ -226,7 +226,7 @@ } break; } - total += PKT_SIZE * wrote; + total += wrote; } if (verbose) { fprintf(stderr, "Wrote %"PRId64" bytes\n", total); diff -Nru libbluray-0.8.0/src/file/dir_posix.c libbluray-0.8.1/src/file/dir_posix.c --- libbluray-0.8.0/src/file/dir_posix.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/file/dir_posix.c 2015-05-15 09:25:06.000000000 +0000 @@ -65,6 +65,10 @@ BD_DIR_H *dir = calloc(1, sizeof(BD_DIR_H)); BD_DEBUG(DBG_DIR, "Opening POSIX dir %s... (%p)\n", dirname, (void*)dir); + if (!dir) { + return NULL; + } + dir->close = _dir_close_posix; dir->read = _dir_read_posix; diff -Nru libbluray-0.8.0/src/file/dirs_darwin.c libbluray-0.8.1/src/file/dirs_darwin.c --- libbluray-0.8.0/src/file/dirs_darwin.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/file/dirs_darwin.c 2015-05-15 09:25:06.000000000 +0000 @@ -73,23 +73,10 @@ const char *file_get_config_system(const char *dir) { - static char *dirs = NULL; // "dir1\0dir2\0...\0dirN\0\0" - - if (!dirs) { - dirs = str_printf("%s%c%c", SYSTEM_CFG_DIR, 0, 0); - } - if (!dir) { // first call - dir = dirs; - } else { - // next call - dir += strlen(dir) + 1; - if (!*dir) { - // end of list - dir = NULL; - } + return SYSTEM_CFG_DIR; } - return dir; + return NULL; } diff -Nru libbluray-0.8.0/src/file/dirs_win32.c libbluray-0.8.1/src/file/dirs_win32.c --- libbluray-0.8.0/src/file/dirs_win32.c 2015-04-13 10:53:10.000000000 +0000 +++ libbluray-0.8.1/src/file/dirs_win32.c 2015-05-15 09:25:06.000000000 +0000 @@ -32,7 +32,6 @@ #include #include #include -#include char *win32_get_font_dir(const char *font_file) @@ -45,9 +44,11 @@ int len = WideCharToMultiByte (CP_UTF8, 0, wdir, -1, NULL, 0, NULL, NULL); char *path = malloc(len + strlen(font_file) + 2); - WideCharToMultiByte(CP_UTF8, 0, wdir, -1, path, len, NULL, NULL); - path[len - 1] = '\\'; - strcpy(path + len, font_file); + if (path) { + WideCharToMultiByte(CP_UTF8, 0, wdir, -1, path, len, NULL, NULL); + path[len - 1] = '\\'; + strcpy(path + len, font_file); + } return path; } @@ -65,7 +66,9 @@ NULL, SHGFP_TYPE_CURRENT, wdir)) { int len = WideCharToMultiByte (CP_UTF8, 0, wdir, -1, NULL, 0, NULL, NULL); char *appdir = malloc(len); - WideCharToMultiByte (CP_UTF8, 0, wdir, -1, appdir, len, NULL, NULL); + if (appdir) { + WideCharToMultiByte (CP_UTF8, 0, wdir, -1, appdir, len, NULL, NULL); + } return appdir; } @@ -94,7 +97,9 @@ NULL, SHGFP_TYPE_CURRENT, wdir)) { int len = WideCharToMultiByte (CP_UTF8, 0, wdir, -1, NULL, 0, NULL, NULL); appdir = malloc(len); - WideCharToMultiByte (CP_UTF8, 0, wdir, -1, appdir, len, NULL, NULL); + if (appdir) { + WideCharToMultiByte (CP_UTF8, 0, wdir, -1, appdir, len, NULL, NULL); + } return appdir; } else { BD_DEBUG(DBG_FILE, "Can't find common configuration directory !\n"); diff -Nru libbluray-0.8.0/src/file/dirs_xdg.c libbluray-0.8.1/src/file/dirs_xdg.c --- libbluray-0.8.0/src/file/dirs_xdg.c 2015-03-20 10:50:37.000000000 +0000 +++ libbluray-0.8.1/src/file/dirs_xdg.c 2015-05-15 09:25:06.000000000 +0000 @@ -44,7 +44,7 @@ { const char *xdg_home = getenv("XDG_CONFIG_HOME"); if (xdg_home && *xdg_home) { - return str_printf("%s", xdg_home); + return str_dup(xdg_home); } const char *user_home = getenv("HOME"); @@ -60,7 +60,7 @@ { const char *xdg_home = getenv("XDG_DATA_HOME"); if (xdg_home && *xdg_home) { - return str_printf("%s", xdg_home); + return str_dup(xdg_home); } const char *user_home = getenv("HOME"); @@ -76,7 +76,7 @@ { const char *xdg_cache = getenv("XDG_CACHE_HOME"); if (xdg_cache && *xdg_cache) { - return str_printf("%s", xdg_cache); + return str_dup(xdg_cache); } const char *user_home = getenv("HOME"); @@ -98,6 +98,9 @@ if (xdg_sys && *xdg_sys) { dirs = calloc(1, strlen(xdg_sys) + 2); + if (!dirs) { + return NULL; + } strcpy(dirs, xdg_sys); char *pt = dirs; diff -Nru libbluray-0.8.0/src/file/dir_win32.c libbluray-0.8.1/src/file/dir_win32.c --- libbluray-0.8.0/src/file/dir_win32.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/file/dir_win32.c 2015-05-15 09:25:06.000000000 +0000 @@ -75,6 +75,9 @@ BD_DIR_H *dir = calloc(1, sizeof(BD_DIR_H)); BD_DEBUG(DBG_DIR, "Opening WIN32 dir %s... (%p)\n", dirname, (void*)dir); + if (!dir) { + return NULL; + } dir->close = _dir_close_win32; dir->read = _dir_read_win32; diff -Nru libbluray-0.8.0/src/file/dl_posix.c libbluray-0.8.1/src/file/dl_posix.c --- libbluray-0.8.0/src/file/dl_posix.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/file/dl_posix.c 2015-05-15 09:25:06.000000000 +0000 @@ -81,6 +81,11 @@ name = str_printf("%s%s%s", search_paths[i], path, ext); } + if (!name) { + BD_DEBUG(DBG_FILE | DBG_CRIT, "out of memory\n"); + continue; + } + BD_DEBUG(DBG_FILE, "Attempting to open %s\n", name); dll = _dl_dlopen (name); diff -Nru libbluray-0.8.0/src/file/dl_win32.c libbluray-0.8.1/src/file/dl_win32.c --- libbluray-0.8.0/src/file/dl_win32.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/file/dl_win32.c 2015-05-15 09:25:06.000000000 +0000 @@ -62,6 +62,11 @@ void *result; name = str_printf("%s.dll", path); + if (!name) { + BD_DEBUG(DBG_FILE | DBG_CRIT, "out of memory\n"); + return NULL; + } + MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_PATH); X_FREE(name); diff -Nru libbluray-0.8.0/src/file/file.h libbluray-0.8.1/src/file/file.h --- libbluray-0.8.0/src/file/file.h 2015-03-04 08:34:15.000000000 +0000 +++ libbluray-0.8.1/src/file/file.h 2015-05-15 09:25:06.000000000 +0000 @@ -25,6 +25,8 @@ #include "util/attributes.h" +#include + #ifdef _WIN32 # define DIR_SEP "\\" # define DIR_SEP_CHAR '\\' @@ -37,9 +39,9 @@ * file access */ -#define file_close(X) X->close(X) +#define file_close(X) X->close(X) #define file_seek(X,Y,Z) X->seek(X,Y,Z) -#define file_tell(X) X->tell(X) +#define file_tell(X) X->tell(X) //#define file_eof(X) X->eof(X) #define file_read(X,Y,Z) (size_t)X->read(X,Y,Z) //#define file_write(X,Y,Z) (size_t)X->write(X,Y,Z) diff -Nru libbluray-0.8.0/src/file/file_posix.c libbluray-0.8.1/src/file/file_posix.c --- libbluray-0.8.0/src/file/file_posix.c 2015-03-20 10:51:10.000000000 +0000 +++ libbluray-0.8.1/src/file/file_posix.c 2015-05-15 09:25:06.000000000 +0000 @@ -2,6 +2,7 @@ * This file is part of libbluray * Copyright (C) 2009-2010 Obliter0n * Copyright (C) 2009-2010 John Stebbins + * Copyright (C) 2010-2015 Petri Hintukainen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,18 +38,18 @@ #include #include -static void file_close_linux(BD_FILE_H *file) +static void _file_close(BD_FILE_H *file) { if (file) { close((int)(intptr_t)file->internal); - BD_DEBUG(DBG_FILE, "Closed LINUX file (%p)\n", (void*)file); + BD_DEBUG(DBG_FILE, "Closed POSIX file (%p)\n", (void*)file); X_FREE(file); } } -static int64_t file_seek_linux(BD_FILE_H *file, int64_t offset, int32_t origin) +static int64_t _file_seek(BD_FILE_H *file, int64_t offset, int32_t origin) { off_t result = lseek((int)(intptr_t)file->internal, offset, origin); if (result == (off_t)-1) { @@ -58,19 +59,19 @@ return (int64_t)result; } -static int64_t file_tell_linux(BD_FILE_H *file) +static int64_t _file_tell(BD_FILE_H *file) { - return file_seek_linux(file, 0, SEEK_CUR); + return _file_seek(file, 0, SEEK_CUR); } #if 0 -static int file_eof_linux(BD_FILE_H *file) +static int _file_eof(BD_FILE_H *file) { return feof((FILE *)file->internal); } #endif -static int64_t file_read_linux(BD_FILE_H *file, uint8_t *buf, int64_t size) +static int64_t _file_read(BD_FILE_H *file, uint8_t *buf, int64_t size) { ssize_t got, result; @@ -95,7 +96,7 @@ return (int64_t)got; } -static int64_t file_write_linux(BD_FILE_H *file, const uint8_t *buf, int64_t size) +static int64_t _file_write(BD_FILE_H *file, const uint8_t *buf, int64_t size) { ssize_t written, result; @@ -117,7 +118,7 @@ return (int64_t)written; } -static BD_FILE_H *file_open_linux(const char* filename, const char *cmode) +static BD_FILE_H *_file_open(const char* filename, const char *cmode) { BD_FILE_H *file; int fd = -1; @@ -150,24 +151,24 @@ return NULL; } - file->close = file_close_linux; - file->seek = file_seek_linux; - file->read = file_read_linux; - file->write = file_write_linux; - file->tell = file_tell_linux; + file->close = _file_close; + file->seek = _file_seek; + file->read = _file_read; + file->write = _file_write; + file->tell = _file_tell; //file->eof = file_eof_linux; file->internal = (void*)(intptr_t)fd; - BD_DEBUG(DBG_FILE, "Opened LINUX file %s (%p)\n", filename, (void*)file); + BD_DEBUG(DBG_FILE, "Opened POSIX file %s (%p)\n", filename, (void*)file); return file; } -BD_FILE_H* (*file_open)(const char* filename, const char *mode) = file_open_linux; +BD_FILE_H* (*file_open)(const char* filename, const char *mode) = _file_open; BD_FILE_OPEN file_open_default(void) { - return file_open_linux; + return _file_open; } int file_unlink(const char *file) @@ -175,9 +176,6 @@ return remove(file); } -#include -#include - int file_path_exists(const char *path) { struct stat s; diff -Nru libbluray-0.8.0/src/file/filesystem.c libbluray-0.8.1/src/file/filesystem.c --- libbluray-0.8.0/src/file/filesystem.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/file/filesystem.c 2015-05-15 09:25:06.000000000 +0000 @@ -26,14 +26,14 @@ BD_FILE_OPEN bd_register_file(BD_FILE_OPEN p) { - BD_FILE_OPEN old = file_open; - file_open = p; - return old; + BD_FILE_OPEN old = file_open; + file_open = p; + return old; } BD_DIR_OPEN bd_register_dir(BD_DIR_OPEN p) { - BD_DIR_OPEN old = dir_open; - dir_open = p; - return old; + BD_DIR_OPEN old = dir_open; + dir_open = p; + return old; } diff -Nru libbluray-0.8.0/src/file/filesystem.h libbluray-0.8.1/src/file/filesystem.h --- libbluray-0.8.0/src/file/filesystem.h 2015-02-18 09:08:54.000000000 +0000 +++ libbluray-0.8.1/src/file/filesystem.h 2015-05-15 09:25:06.000000000 +0000 @@ -35,12 +35,12 @@ struct bd_file_s { void* internal; - void (*close)(BD_FILE_H *file); - int64_t (*seek)(BD_FILE_H *file, int64_t offset, int32_t origin); - int64_t (*tell)(BD_FILE_H *file); - int (*eof)(BD_FILE_H *file); - int64_t (*read)(BD_FILE_H *file, uint8_t *buf, int64_t size); - int64_t (*write)(BD_FILE_H *file, const uint8_t *buf, int64_t size); + void (*close) (BD_FILE_H *file); + int64_t (*seek) (BD_FILE_H *file, int64_t offset, int32_t origin); + int64_t (*tell) (BD_FILE_H *file); + int (*eof) (BD_FILE_H *file); + int64_t (*read) (BD_FILE_H *file, uint8_t *buf, int64_t size); + int64_t (*write) (BD_FILE_H *file, const uint8_t *buf, int64_t size); }; /* diff -Nru libbluray-0.8.0/src/file/file_win32.c libbluray-0.8.1/src/file/file_win32.c --- libbluray-0.8.0/src/file/file_win32.c 2015-03-04 08:34:15.000000000 +0000 +++ libbluray-0.8.1/src/file/file_win32.c 2015-05-15 09:25:06.000000000 +0000 @@ -95,28 +95,40 @@ static BD_FILE_H *_file_open(const char* filename, const char *mode) { - FILE *fp = NULL; - + BD_FILE_H *file; + FILE *fp; wchar_t wfilename[MAX_PATH], wmode[8]; - if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename, -1, wfilename, MAX_PATH) && - MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, mode, -1, wmode, 8) && - (fp = _wfopen(wfilename, wmode))) { - - BD_FILE_H *file = calloc(1, sizeof(BD_FILE_H)); - file->internal = fp; - file->close = _file_close; - file->seek = _file_seek; - file->read = _file_read; - file->write = _file_write; - file->tell = _file_tell; - //file->eof = _file_eof; - BD_DEBUG(DBG_FILE, "Opened WIN32 file %s (%p)\n", filename, (void*)file); - return file; + if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename, -1, wfilename, MAX_PATH) || + !MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, mode, -1, wmode, 8)) { + + BD_DEBUG(DBG_FILE, "Error opening file %s\n", filename); + return NULL; + } + + fp = _wfopen(wfilename, wmode); + if (!fp) { + BD_DEBUG(DBG_FILE, "Error opening file %s\n", filename); + return NULL; } - BD_DEBUG(DBG_FILE, "Error opening file %s\n", filename); - return NULL; + file = calloc(1, sizeof(BD_FILE_H)); + if (!file) { + BD_DEBUG(DBG_FILE | DBG_CRIT, "Error opening file %s (out of memory)\n", filename); + fclose(fp); + return NULL; + } + + file->internal = fp; + file->close = _file_close; + file->seek = _file_seek; + file->read = _file_read; + file->write = _file_write; + file->tell = _file_tell; + //file->eof = _file_eof; + + BD_DEBUG(DBG_FILE, "Opened WIN32 file %s (%p)\n", filename, (void*)file); + return file; } BD_FILE_H* (*file_open)(const char* filename, const char *mode) = _file_open; diff -Nru libbluray-0.8.0/src/file/mount_darwin.c libbluray-0.8.1/src/file/mount_darwin.c --- libbluray-0.8.0/src/file/mount_darwin.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/file/mount_darwin.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "mount.h" #include "util/strutl.h" diff -Nru libbluray-0.8.0/src/libbluray/bdj/bdj.c libbluray-0.8.1/src/libbluray/bdj/bdj.c --- libbluray-0.8.0/src/libbluray/bdj/bdj.c 2015-04-06 16:25:09.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/bdj.c 2015-05-15 09:25:06.000000000 +0000 @@ -617,7 +617,6 @@ "PLAYITEM", "ANGLE", "SUBTITLE", - "PIP", "END_OF_PLAYLIST", "PTS", "VK_KEY", @@ -629,6 +628,9 @@ "STOP", "RATE", + "AUDIO_STREAM", + "SECONDARY_STREAM", + "UO_MASKED", }; JNIEnv* env; diff -Nru libbluray-0.8.0/src/libbluray/bdj/bdj.h libbluray-0.8.1/src/libbluray/bdj/bdj.h --- libbluray-0.8.0/src/libbluray/bdj/bdj.h 2015-04-06 16:25:09.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/bdj.h 2015-05-15 09:25:06.000000000 +0000 @@ -28,7 +28,6 @@ BDJ_EVENT_PLAYITEM, BDJ_EVENT_ANGLE, BDJ_EVENT_SUBTITLE, - BDJ_EVENT_PIP, BDJ_EVENT_END_OF_PLAYLIST, BDJ_EVENT_PTS, BDJ_EVENT_VK_KEY, @@ -40,6 +39,9 @@ BDJ_EVENT_STOP, BDJ_EVENT_RATE, + BDJ_EVENT_AUDIO_STREAM, + BDJ_EVENT_SECONDARY_STREAM, + BDJ_EVENT_UO_MASKED, } BDJ_EVENT; typedef struct { diff -Nru libbluray-0.8.0/src/libbluray/bdj/bdjo_parse.c libbluray-0.8.1/src/libbluray/bdj/bdjo_parse.c --- libbluray-0.8.0/src/libbluray/bdj/bdjo_parse.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/bdjo_parse.c 2015-05-15 09:25:06.000000000 +0000 @@ -18,6 +18,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "bdjo_parse.h" #include "bdjo_data.h" @@ -287,7 +291,7 @@ p->num_param = _count_app_strings(bs, data_length, 0, "params"); if (p->num_param) { - p->param = calloc(p->num_param, sizeof(BDJO_APP_NAME)); + p->param = calloc(p->num_param, sizeof(BDJO_APP_PARAM)); if (!p->param) { BD_DEBUG(DBG_BDJ | DBG_CRIT, "Out of memory\n"); return -1; diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/com/aacsla/bluray/online/ContentAttribute.java libbluray-0.8.1/src/libbluray/bdj/java/com/aacsla/bluray/online/ContentAttribute.java --- libbluray-0.8.0/src/libbluray/bdj/java/com/aacsla/bluray/online/ContentAttribute.java 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/com/aacsla/bluray/online/ContentAttribute.java 2015-05-15 09:25:06.000000000 +0000 @@ -37,14 +37,14 @@ if (is.read(bytes, 0, 6) != 6) return null; return bytes; - } catch (Throwable e) { + } catch (Exception e) { e.printStackTrace(); return null; } finally { if (is != null) { try { is.close(); - } catch (Throwable e) { + } catch (Exception e) { e.printStackTrace(); } } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/com/aacsla/bluray/online/MediaAttribute.java libbluray-0.8.1/src/libbluray/bdj/java/com/aacsla/bluray/online/MediaAttribute.java --- libbluray-0.8.0/src/libbluray/bdj/java/com/aacsla/bluray/online/MediaAttribute.java 2015-02-28 19:23:41.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/com/aacsla/bluray/online/MediaAttribute.java 2015-05-15 09:25:06.000000000 +0000 @@ -30,6 +30,7 @@ byte pmsn[] = Libbluray.getAacsData(Libbluray.AACS_MEDIA_PMSN); if (pmsn == null) { logger.warning("getPMSN() failed"); + return new byte[16]; } return pmsn; } @@ -38,6 +39,7 @@ byte vid[] = Libbluray.getAacsData(Libbluray.AACS_MEDIA_VID); if (vid == null) { logger.warning("getVolumeID() failed"); + return new byte[16]; } return vid; } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/java/awt/BDFontMetrics.java libbluray-0.8.1/src/libbluray/bdj/java/java/awt/BDFontMetrics.java --- libbluray-0.8.0/src/libbluray/bdj/java/java/awt/BDFontMetrics.java 2015-03-20 10:51:10.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/java/awt/BDFontMetrics.java 2015-05-15 09:25:06.000000000 +0000 @@ -282,7 +282,12 @@ * Return the width of the specified string in this Font. */ public synchronized int stringWidth(String string) { - return stringWidthN(ftFace, string); + /* Allow only one call at time. + * (calling this function from multiple threads caused crashes in freetype) + */ + synchronized (BDFontMetrics.class) { + return stringWidthN(ftFace, string); + } } /** diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/java/awt/BDJHelper.java libbluray-0.8.1/src/libbluray/bdj/java/java/awt/BDJHelper.java --- libbluray-0.8.0/src/libbluray/bdj/java/java/awt/BDJHelper.java 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/java/awt/BDJHelper.java 2015-05-15 09:25:06.000000000 +0000 @@ -84,7 +84,7 @@ eq.postEvent(event); return true; } - } catch (Throwable e) { + } catch (Exception e) { org.videolan.Logger.getLogger("BDJHelper").error("postKeyEvent failed: " + e); } } else { diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/java/io/BDFileSystem.java libbluray-0.8.1/src/libbluray/bdj/java/java/io/BDFileSystem.java --- libbluray-0.8.0/src/libbluray/bdj/java/java/io/BDFileSystem.java 2015-04-07 19:56:47.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/java/io/BDFileSystem.java 2015-05-15 09:25:06.000000000 +0000 @@ -90,7 +90,7 @@ } else { filesystem.set(null, new BDFileSystemImpl(fs)); } - } catch (Throwable t) { + } catch (Exception t) { System.err.print("Hooking FileSystem class failed: " + t); } } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/javax/tv/service/SIManagerImpl.java libbluray-0.8.1/src/libbluray/bdj/java/javax/tv/service/SIManagerImpl.java --- libbluray-0.8.0/src/libbluray/bdj/java/javax/tv/service/SIManagerImpl.java 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/javax/tv/service/SIManagerImpl.java 2015-05-15 09:25:06.000000000 +0000 @@ -53,14 +53,14 @@ for (int i = 0; i <= ntitles; i++) { try { list.add(new TitleImpl(i)); - } catch (Throwable t) { + } catch (Exception t) { org.videolan.Logger.getLogger("SIManagerImpl").error("Failed initializing title " + i + ": " + t); } } try { list.add(new TitleImpl(65535)); - } catch (Throwable t) { + } catch (Exception t) { org.videolan.Logger.getLogger("SIManagerImpl").error("Failed initializing title FirstPlay: " + t); } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/bluray/net/BDLocator.java libbluray-0.8.1/src/libbluray/bdj/java/org/bluray/net/BDLocator.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/bluray/net/BDLocator.java 2015-04-07 19:56:47.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/bluray/net/BDLocator.java 2015-05-15 09:25:06.000000000 +0000 @@ -260,11 +260,19 @@ protected String getUrl() { String str = "bd://"; - if (disc != null && disc != "") - str += disc + "."; + if (disc != null && disc != "") { + str += disc; + if (titleNum >= 0) { + str += "."; + } + } - if (titleNum >= 0) - str += Integer.toString(titleNum, 16) + "."; + if (titleNum >= 0) { + str += Integer.toString(titleNum, 16); + if (jar >= 0 || playList >= 0 || sound >= 0) { + str += "."; + } + } if (jar >= 0) { str += "JAR:" + BDJUtil.makeFiveDigitStr(jar); diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/havi/ui/HSceneFactory.java libbluray-0.8.1/src/libbluray/bdj/java/org/havi/ui/HSceneFactory.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/havi/ui/HSceneFactory.java 2015-02-13 11:44:06.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/havi/ui/HSceneFactory.java 2015-05-15 09:25:06.000000000 +0000 @@ -101,7 +101,7 @@ return; } if (defaultHScene == null) { - logger.error("no HScene created"); + //logger.error("no HScene created"); return; } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJActionManager.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJActionManager.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJActionManager.java 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJActionManager.java 2015-05-15 09:25:06.000000000 +0000 @@ -38,7 +38,7 @@ protected static void shutdown() { try { instance.commandQueue.shutdown(); - } catch (Throwable t) { + } catch (Exception t) { } finally { running = false; } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJActionQueue.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJActionQueue.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJActionQueue.java 2015-02-28 16:45:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJActionQueue.java 2015-05-15 09:25:06.000000000 +0000 @@ -50,7 +50,7 @@ watchdog.shutdown(); try { thread.join(); - } catch (Throwable t) { + } catch (InterruptedException t) { logger.error("Error joining thread: " + t); } } @@ -75,6 +75,9 @@ ((BDJAction)action).process(); watchdog.endAction(); + } catch (ThreadDeath d) { + System.err.println("action failed: " + d + "\n"); + throw d; } catch (Throwable e) { System.err.println("action failed: " + e + "\n" + Logger.dumpStack(e)); } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJAppProxy.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJAppProxy.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJAppProxy.java 2015-02-28 16:45:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJAppProxy.java 2015-05-15 09:25:06.000000000 +0000 @@ -78,11 +78,7 @@ } public void start() { - AppCommand cmd = new AppCommand(AppCommand.CMD_START, null); - synchronized(cmds) { - cmds.addLast(cmd); - cmds.notifyAll(); - } + start(null); } public void start(String[] args) { diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJLoader.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJLoader.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJLoader.java 2015-04-06 16:13:39.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJLoader.java 2015-05-15 09:25:06.000000000 +0000 @@ -178,6 +178,7 @@ gui.setVisible(true); Libbluray.setUOMask(terminfo.getMenuCallMask(), terminfo.getTitleSearchMask()); + Libbluray.setKeyInterest(bdjo.getKeyInterestTable()); // initialize appProxys for (int i = 0; i < appTable.length; i++) { diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJXletContext.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJXletContext.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BDJXletContext.java 2015-04-06 15:44:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BDJXletContext.java 2015-05-15 09:25:06.000000000 +0000 @@ -213,14 +213,14 @@ return true; } - public boolean putCallback(BDJAction cb) + protected boolean putCallback(BDJAction cb) { synchronized (this) { return putCallbackImpl(cb, callbackQueue); } } - public boolean putMediaCallback(BDJAction cb) + protected boolean putMediaCallback(BDJAction cb) { synchronized (this) { return putCallbackImpl(cb, mediaQueue); @@ -287,7 +287,7 @@ try { look = defClass.newInstance(); setDefaultLook(key, look); - } catch (Throwable t) { + } catch (Exception t) { logger.error("Error creating default look " + defClass.getName() + " for " + key + ": " + t); } } @@ -347,7 +347,7 @@ return result; } - public static void stopThread(Thread thread, int timeout, String type) { + protected static void stopThread(Thread thread, int timeout, String type) { if (!waitThread(thread, timeout)) { thread.interrupt(); if (!waitThread(thread, 200)) { @@ -357,10 +357,10 @@ } try { thread.join(); - } catch (Throwable t) { } + } catch (InterruptedException e) { } } - protected void stopIxcThreads() { + private void stopIxcThreads() { while (true) { Thread thread; synchronized (ixcThreads) { @@ -391,7 +391,7 @@ } } - public void removeAllFAA() { + private void removeAllFAA() { Object[] faaArray; synchronized (faaList) { faaArray = faaList.toArray(); diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BUMFAsset.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BUMFAsset.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/BUMFAsset.java 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/BUMFAsset.java 2015-05-15 09:25:06.000000000 +0000 @@ -25,11 +25,11 @@ this.budaFile = budaFile; } - String getVpFile() { + public String getVpFile() { return vpFile; } - String getBudaFile() { + public String getBudaFile() { return budaFile; } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/Copy.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/Copy.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/Copy.java 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/Copy.java 2015-05-15 09:25:06.000000000 +0000 @@ -65,10 +65,10 @@ } System.err.println("deepCopy: failed to resolve class " + desc.getName()); throw e; - } catch (Throwable t) { + } catch (Exception t) { System.err.println("deepCopy: failed to resolve class " + desc.getName() + ": " + t); return null; } } } -} \ No newline at end of file +} diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/Libbluray.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/Libbluray.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/Libbluray.java 2015-04-06 16:25:09.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/Libbluray.java 2015-05-15 09:25:06.000000000 +0000 @@ -247,6 +247,10 @@ setUOMaskN(nativePointer, menuCallMask, titleSearchMask); } + protected static void setKeyInterest(int mask) { + setKeyInterestN(nativePointer, mask); + } + protected static int setVirtualPackage(String vpPath, boolean initBackupRegs) { return setVirtualPackageN(nativePointer, vpPath, initBackupRegs); } @@ -358,6 +362,10 @@ return selectAngleN(nativePointer, angle) == 1 ? true : false; } + public static int soundEffect(int id) { + return soundEffectN(nativePointer, id); + } + public static int getCurrentAngle() { return readPSR(PSR_ANGLE_NUMBER); } @@ -466,7 +474,7 @@ } /* called only from native code */ - private static boolean processEvent(int event, int param) { + private static boolean processEventImpl(int event, int param) { boolean result = true; int key = 0; @@ -478,25 +486,17 @@ return stopTitle(false); case BDJ_EVENT_CHAPTER: - PlayerManager.getInstance().onChapterReach(param); - break; case BDJ_EVENT_MARK: - PlayerManager.getInstance().onMarkReach(param); - break; case BDJ_EVENT_PLAYITEM: - PlayerManager.getInstance().onPlayItemReach(param); - break; case BDJ_EVENT_PLAYLIST: - PlayerManager.getInstance().onPlaylistStart(param); - break; case BDJ_EVENT_ANGLE: - PlayerManager.getInstance().onAngleChange(param); - break; case BDJ_EVENT_SUBTITLE: - PlayerManager.getInstance().onSubtitleChange(param); - break; - case BDJ_EVENT_PIP: - PlayerManager.getInstance().onPiPChange(param); + case BDJ_EVENT_AUDIO_STREAM: + case BDJ_EVENT_SECONDARY_STREAM: + case BDJ_EVENT_END_OF_PLAYLIST: + case BDJ_EVENT_PTS: + case BDJ_EVENT_UO_MASKED: + PlayerManager.getInstance().onEvent(event, param); break; case BDJ_EVENT_RATE: float rate = (float)param / 90000.0f; @@ -505,15 +505,11 @@ if (rate > 0.99f && rate < 1.01f) rate = 1.0f; PlayerManager.getInstance().onRateChange(rate); break; - case BDJ_EVENT_END_OF_PLAYLIST: - PlayerManager.getInstance().onPlaylistEnd(param); - break; + case BDJ_EVENT_PSR102: org.bluray.bdplus.Status.getInstance().receive(param); break; - case BDJ_EVENT_PTS: - PlayerManager.getInstance().onPlaylistTime(param); - break; + case BDJ_EVENT_VK_KEY: switch (param) { case 0: key = KeyEvent.VK_0; break; @@ -549,28 +545,40 @@ } break; default: + System.err.println("Unknown event " + event + "." + param); result = false; } return result; } - private static final int BDJ_EVENT_CHAPTER = 1; - private static final int BDJ_EVENT_PLAYITEM = 2; - private static final int BDJ_EVENT_ANGLE = 3; - private static final int BDJ_EVENT_SUBTITLE = 4; - private static final int BDJ_EVENT_PIP = 5; - private static final int BDJ_EVENT_END_OF_PLAYLIST = 6; - private static final int BDJ_EVENT_PTS = 7; - private static final int BDJ_EVENT_VK_KEY = 8; - private static final int BDJ_EVENT_MARK = 9; - private static final int BDJ_EVENT_PSR102 = 10; - private static final int BDJ_EVENT_PLAYLIST = 11; - - private static final int BDJ_EVENT_START = 12; - private static final int BDJ_EVENT_STOP = 13; + private static boolean processEvent(int event, int param) { + try { + return processEventImpl(event, param); + } catch (Throwable e) { + System.err.println("processEvent() failed: " + e + "\n" + Logger.dumpStack(e)); + return false; + } + } - private static final int BDJ_EVENT_RATE = 14; + public static final int BDJ_EVENT_CHAPTER = 1; + public static final int BDJ_EVENT_PLAYITEM = 2; + public static final int BDJ_EVENT_ANGLE = 3; + public static final int BDJ_EVENT_SUBTITLE = 4; + public static final int BDJ_EVENT_END_OF_PLAYLIST = 5; + public static final int BDJ_EVENT_PTS = 6; + private static final int BDJ_EVENT_VK_KEY = 7; + public static final int BDJ_EVENT_MARK = 8; + private static final int BDJ_EVENT_PSR102 = 9; + public static final int BDJ_EVENT_PLAYLIST = 10; + + private static final int BDJ_EVENT_START = 11; + private static final int BDJ_EVENT_STOP = 12; + + public static final int BDJ_EVENT_RATE = 13; + public static final int BDJ_EVENT_AUDIO_STREAM = 14; + public static final int BDJ_EVENT_SECONDARY_STREAM = 15; + public static final int BDJ_EVENT_UO_MASKED = 16; /* TODO: use org/bluray/system/RegisterAccess instead */ public static final int PSR_IG_STREAM_ID = 0; @@ -619,8 +627,10 @@ private static native int selectPlaylistN(long np, int playlist, int playitem, int playmark, long time); private static native int selectTitleN(long np, int title); private static native int selectAngleN(long np, int angle); + private static native int soundEffectN(long np, int id); private static native long getUOMaskN(long np); private static native void setUOMaskN(long np, boolean menuCallMask, boolean titleSearchMask); + private static native void setKeyInterestN(long np, int mask); private static native long tellTimeN(long np); private static native int selectRateN(long np, float rate, int reason); private static native int writeGPRN(long np, int num, int value); diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/BDHandler.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/BDHandler.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/BDHandler.java 2015-04-06 16:25:09.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/BDHandler.java 2015-05-15 09:25:06.000000000 +0000 @@ -60,6 +60,7 @@ import org.videolan.BDJActionQueue; import org.videolan.BDJListeners; import org.videolan.BDJXletContext; +import org.videolan.Libbluray; import org.videolan.Logger; public abstract class BDHandler implements Player, ServiceContentHandler { @@ -330,16 +331,9 @@ * notifications from app */ - protected void timeChanged(int time) { + protected void statusEvent(int event, int param) { if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_TIME_CHANGED, new Integer(time)); - commandQueue.put(action); - } - - protected void playlistEndReached(int playlist) { - if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_END_OF_MEDIA_REACHED, new Integer(playlist)); - commandQueue.put(action); + commandQueue.put(new PlayerAction(this, PlayerAction.ACTION_STATUS, new Integer(event), param)); } protected void rateChanged(float rate) { @@ -348,48 +342,6 @@ commandQueue.put(action); } - protected void playlistStarted(int param) { - if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_PLAYLIST_STARTED, new Integer(param)); - commandQueue.put(action); - } - - protected void chapterReached(int param) { - if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_CHAPTER_REACHED, new Integer(param)); - commandQueue.put(action); - } - - protected void markReached(int param) { - if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_MARK_REACHED, new Integer(param)); - commandQueue.put(action); - } - - protected void playItemReached(int param) { - if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_PLAYITEM_REACHED, new Integer(param)); - commandQueue.put(action); - } - - protected void angleChanged(int param) { - if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_ANGLE_CHANGED, new Integer(param)); - commandQueue.put(action); - } - - protected void subtitleChanged(int param) { - if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_SUBTITLE_CHANGED, new Integer(param)); - commandQueue.put(action); - } - - protected void pipChanged(int param) { - if (isClosed) return; - PlayerAction action = new PlayerAction(this, PlayerAction.ACTION_PIP_CHANGED, new Integer(param)); - commandQueue.put(action); - } - /* * handling of notifications from app */ @@ -428,7 +380,9 @@ protected void doPlayItemReached(int playitem) {}; protected void doAngleChanged(int angle) {}; protected void doSubtitleChanged(int param) {}; - protected void doPiPChanged(int param) {}; + protected void doAudioStreamChanged(int param) {}; + protected void doUOMasked(int position) {}; + protected void doSecondaryStreamChanged(int param) {}; /* * @@ -620,9 +574,13 @@ private class PlayerAction extends BDJAction { private PlayerAction(BDHandler player, int action, Object param) { + this(player, action, param, -1); + } + private PlayerAction(BDHandler player, int action, Object param, int param2) { this.player = player; this.action = action; this.param = param; + this.param2 = param2; } protected void doAction() { @@ -656,35 +614,51 @@ player.doSetRate((Float)param); break; - case ACTION_END_OF_MEDIA_REACHED: - player.doEndOfMediaReached(((Integer)param).intValue()); - break; - case ACTION_TIME_CHANGED: - player.doTimeChanged(((Integer)param).intValue()); - break; case ACTION_RATE_CHANGED: player.doRateChanged(((Float)param).floatValue()); break; - case ACTION_PLAYLIST_STARTED: - player.doPlaylistStarted(((Integer)param).intValue()); - break; - case ACTION_PLAYITEM_REACHED: - player.doPlayItemReached(((Integer)param).intValue()); - break; - case ACTION_CHAPTER_REACHED: - player.doChapterReached(((Integer)param).intValue()); - break; - case ACTION_MARK_REACHED: - player.doMarkReached(((Integer)param).intValue()); - break; - case ACTION_ANGLE_CHANGED: - player.doAngleChanged(((Integer)param).intValue()); - break; - case ACTION_SUBTITLE_CHANGED: - player.doSubtitleChanged(((Integer)param).intValue()); + case ACTION_STATUS: + switch (((Integer)param).intValue()) { + case Libbluray.BDJ_EVENT_CHAPTER: + player.doChapterReached(param2); + break; + case Libbluray.BDJ_EVENT_MARK: + player.doMarkReached(param2); + break; + case Libbluray.BDJ_EVENT_PLAYITEM: + player.doPlayItemReached(param2); + break; + case Libbluray.BDJ_EVENT_PLAYLIST: + player.doPlaylistStarted(param2); + break; + case Libbluray.BDJ_EVENT_ANGLE: + player.doAngleChanged(param2); + break; + case Libbluray.BDJ_EVENT_SUBTITLE: + player.doSubtitleChanged(param2); + break; + case Libbluray.BDJ_EVENT_END_OF_PLAYLIST: + player.doEndOfMediaReached(param2); + break; + case Libbluray.BDJ_EVENT_PTS: + player.doTimeChanged(param2); + break; + case Libbluray.BDJ_EVENT_AUDIO_STREAM: + player.doAudioStreamChanged(param2); + break; + case Libbluray.BDJ_EVENT_SECONDARY_STREAM: + player.doSecondaryStreamChanged(param2); + break; + case Libbluray.BDJ_EVENT_UO_MASKED: + player.doUOMasked(param2); + break; + default: + System.err.println("Unknown ACTION_STATUS: id " + param + ", value " + param2); + break; + } break; - case ACTION_PIP_CHANGED: - player.doPiPChanged(((Integer)param).intValue()); + default: + System.err.println("Unknown action " + action); break; } } @@ -692,6 +666,7 @@ private BDHandler player; private int action; private Object param; + private int param2; public static final int ACTION_INIT = 1; public static final int ACTION_REALIZE = 2; @@ -704,16 +679,8 @@ public static final int ACTION_SEEK_TIME = 8; public static final int ACTION_SET_RATE = 9; - public static final int ACTION_END_OF_MEDIA_REACHED = 10; + public static final int ACTION_STATUS = 10; public static final int ACTION_RATE_CHANGED = 11; - public static final int ACTION_TIME_CHANGED = 12; - public static final int ACTION_PLAYLIST_STARTED = 13; - public static final int ACTION_PLAYITEM_REACHED = 14; - public static final int ACTION_CHAPTER_REACHED = 15; - public static final int ACTION_MARK_REACHED = 16; - public static final int ACTION_ANGLE_CHANGED = 17; - public static final int ACTION_SUBTITLE_CHANGED = 18; - public static final int ACTION_PIP_CHANGED = 19; } protected int state = Unrealized; diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/PlayerManager.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/PlayerManager.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/PlayerManager.java 2015-04-07 19:56:47.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/PlayerManager.java 2015-05-15 09:25:06.000000000 +0000 @@ -134,73 +134,13 @@ * */ - public void onPlaylistEnd(int playlist) { + public void onEvent(int event, int param) { synchronized (stoppingLock) { if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.playlistEndReached(playlist); - } - } - } - - public void onPlaylistTime(int pts) { - synchronized (stoppingLock) { - if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.timeChanged(pts); - } - } - } - - public void onChapterReach(int param) { - synchronized (stoppingLock) { - if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.chapterReached(param); - } - } - } - - public void onMarkReach(int param) { - synchronized (stoppingLock) { - if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.markReached(param); - } - } - } - - public void onPlaylistStart(int param) { - synchronized (stoppingLock) { - if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.playlistStarted(param); - } - } - } - - public void onPlayItemReach(int param) { - synchronized (stoppingLock) { - if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.playItemReached(param); - } - } - } - - public void onAngleChange(int param) { - synchronized (stoppingLock) { - if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.angleChanged(param); - } + synchronized (playlistPlayerLock) { + if (playlistPlayer != null) + playlistPlayer.statusEvent(event, param); + } } } @@ -213,24 +153,4 @@ } } } - - public void onSubtitleChange(int param) { - synchronized (stoppingLock) { - if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.subtitleChanged(param); - } - } - } - - public void onPiPChange(int param) { - synchronized (stoppingLock) { - if (stopping) return; - synchronized (playlistPlayerLock) { - if (playlistPlayer != null) - playlistPlayer.pipChanged(param); - } - } - } } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/playlist/Handler.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/playlist/Handler.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/playlist/Handler.java 2015-04-06 16:25:09.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/playlist/Handler.java 2015-05-15 09:25:06.000000000 +0000 @@ -29,6 +29,7 @@ import javax.media.IncompatibleSourceException; import javax.media.Time; import javax.media.protocol.DataSource; +import javax.tv.locator.Locator; import javax.tv.locator.InvalidLocatorException; import javax.tv.service.selection.ServiceContextFactory; @@ -127,7 +128,8 @@ updateTime(new Time(Libbluray.tellTime() * TO_SECONDS)); - } catch (Throwable e) { + currentLocator = new BDLocator(locator.toExternalForm()); + } catch (Exception e) { return new ConnectionErrorEvent(this); } return super.doPrefetch(); @@ -139,14 +141,14 @@ if (at != null) { try { Libbluray.seekTime((long)(at.getSeconds() * FROM_SECONDS)); - } catch (Throwable e) { + } catch (Exception e) { return new ConnectionErrorEvent(this); } } try { Libbluray.selectRate(rate, true); - } catch (Throwable e) { + } catch (Exception e) { return new ConnectionErrorEvent(this); } @@ -165,7 +167,7 @@ if ((state == Prefetched) || (state == Started)) { try { Libbluray.seekTime((long)(at.getSeconds() * FROM_SECONDS)); - } catch (Throwable e) { + } catch (Exception e) { return; } at = new Time(Libbluray.tellTime() * TO_SECONDS); @@ -179,7 +181,7 @@ if (state == Started) { try { Libbluray.selectRate(factor.floatValue()); - } catch (Throwable e) { + } catch (Exception e) { return; } if (state == Started) { @@ -193,6 +195,10 @@ /* notification from app */ + private void postMediaSelectSucceeded(BDLocator locator) { + ((DVBMediaSelectControlImpl)controls[3]).postMediaSelectSucceededEvent(new Locator[] { locator }); + } + protected void doRateChanged(float rate) { synchronized (this) { if (state == Started) { @@ -206,8 +212,12 @@ protected void doChapterReached(int param) { ((PlaybackControlImpl)controls[9]).onChapterReach(param); } + protected void doMarkReached(int param) { ((PlaybackControlImpl)controls[9]).onMarkReach(param); + + if (currentLocator != null) + currentLocator.setMarkId(param); } protected void doPlaylistStarted(int param) { @@ -217,6 +227,12 @@ ((PlaybackControlImpl)controls[9]).onPlayItemReach(param); ((UOMaskTableControlImpl)controls[16]).onPlayItemReach(param); + + if (currentLocator != null) { + currentLocator.setPlayItemId(param); + postMediaSelectSucceeded(currentLocator); + } + try { ((TitleContextImpl)ServiceContextFactory.getInstance().getServiceContext(null)).presentationChanged(); } catch (Exception e) { @@ -231,16 +247,49 @@ } } + protected void doUOMasked(int position) { + ((UOMaskTableControlImpl)controls[16]).onUOMasked(position); + } + protected void doAngleChanged(int param) { ((AngleControlImpl)controls[0]).onAngleChange(param); } protected void doSubtitleChanged(int param) { ((SubtitlingControlImpl)controls[15]).onSubtitleChange(param); + + if (currentLocator != null) { + currentLocator.setPGTextStreamNumber(param & 0xfff); + postMediaSelectSucceeded(currentLocator); + } + } + + protected void doAudioStreamChanged(int param) { + if (currentLocator != null) { + locator.setPrimaryAudioStreamNumber(param); + postMediaSelectSucceeded(currentLocator); + } + } + + private void doSecondaryVideoChanged(int stream, boolean enable) { + if (currentLocator != null) { + locator.setSecondaryVideoStreamNumber(stream); + postMediaSelectSucceeded(currentLocator); + } + + ((PiPControlImpl)controls[8]).onPiPStatusChange(enable); + } + + private void doSecondaryAudioChanged(int stream, boolean enable) { + if (currentLocator != null) { + locator.setSecondaryAudioStreamNumber(stream); + postMediaSelectSucceeded(currentLocator); + } } - protected void doPiPChanged(int param) { - ((PiPControlImpl)controls[8]).onPiPChange(param); + protected void doSecondaryStreamChanged(int param) { + doSecondaryVideoChanged((param & 0xff00) >> 8, (param & 0x80000000) != 0); + doSecondaryAudioChanged(param & 0xff, (param & 0x40000000) != 0); } protected void doEndOfMediaReached(int playlist) { @@ -350,4 +399,5 @@ } private PlaylistInfo pi = null; + private BDLocator currentLocator = null; } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/playlist/PiPControlImpl.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/playlist/PiPControlImpl.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/playlist/PiPControlImpl.java 2015-04-06 16:25:09.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/playlist/PiPControlImpl.java 2015-05-15 09:25:06.000000000 +0000 @@ -83,8 +83,8 @@ return false; } - protected void onPiPChange(int param) { - listeners.putCallback(new PiPStatusEvent(param > 0, this)); + protected void onPiPStatusChange(boolean enable) { + listeners.putCallback(new PiPStatusEvent(enable, this)); } public void addPiPStatusListener(PiPStatusListener listener) { diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/playlist/UOMaskTableControlImpl.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/playlist/UOMaskTableControlImpl.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/playlist/UOMaskTableControlImpl.java 2015-02-13 11:44:06.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/playlist/UOMaskTableControlImpl.java 2015-05-15 09:25:06.000000000 +0000 @@ -60,7 +60,6 @@ } protected void onUOMasked(int position) { - // TODO: this method is not called listeners.putCallback(new UOMaskedEvent(this, position)); } diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/sound/Handler.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/sound/Handler.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/media/content/sound/Handler.java 2015-04-06 15:44:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/media/content/sound/Handler.java 2015-05-15 09:25:06.000000000 +0000 @@ -44,6 +44,7 @@ import org.videolan.media.content.BDHandler; import org.videolan.BDJListeners; +import org.videolan.Libbluray; public class Handler extends BDHandler { public Handler() { @@ -76,7 +77,23 @@ } protected ControllerErrorEvent doStart(Time at) { - return super.doStart(at); + + ControllerErrorEvent err = super.doStart(at); + if (err != null) { + return err; + } + + if (!locator.isSoundItem()) { + System.err.println("no sound effect in " + locator); + } else { + int id = locator.getSoundId(); + Libbluray.soundEffect(id); + + // Trigger end of media event + // XXX should use some other event name ... + statusEvent(Libbluray.BDJ_EVENT_END_OF_PLAYLIST, id); + } + return null; } protected ControllerErrorEvent doStop() { diff -Nru libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/MountManager.java libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/MountManager.java --- libbluray-0.8.0/src/libbluray/bdj/java/org/videolan/MountManager.java 2015-04-06 15:44:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/java/org/videolan/MountManager.java 2015-05-15 09:25:06.000000000 +0000 @@ -73,7 +73,7 @@ } } - String path = System.getProperty("bluray.vfs.root") + "/BDMV/JAR/" + jarStr + ".jar"; + String path = BDJLoader.getCachedFile(System.getProperty("bluray.vfs.root") + relJarDir + jarStr + ".jar"); JarFile jar = null; try { @@ -232,6 +232,7 @@ return BDJUtil.makeFiveDigitStr(jarId); } + private static final String relJarDir = new String(File.separator + "BDMV" + File.separator + "JAR" + File.separator); private static Map mountPoints = new HashMap(); private static final Logger logger = Logger.getLogger(MountManager.class.getName()); diff -Nru libbluray-0.8.0/src/libbluray/bdj/native/bdjo.c libbluray-0.8.1/src/libbluray/bdj/native/bdjo.c --- libbluray-0.8.0/src/libbluray/bdj/native/bdjo.c 2015-02-18 09:08:30.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/native/bdjo.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "bdjo.h" #include "util.h" diff -Nru libbluray-0.8.0/src/libbluray/bdj/native/org_videolan_Libbluray.c libbluray-0.8.1/src/libbluray/bdj/native/org_videolan_Libbluray.c --- libbluray-0.8.0/src/libbluray/bdj/native/org_videolan_Libbluray.c 2015-02-28 16:45:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/native/org_videolan_Libbluray.c 2015-05-15 09:25:06.000000000 +0000 @@ -194,6 +194,8 @@ BLURAY* bd = (BLURAY*)(intptr_t)np; const uint8_t *data = bd_get_aacs_data(bd, type); + BD_DEBUG(DBG_JNI, "getAacsDataN(%d) -> %p\n", (int)type, (const void *)data); + if (!data) { return NULL; } @@ -205,15 +207,27 @@ JNIEXPORT jlong JNICALL Java_org_videolan_Libbluray_getUOMaskN(JNIEnv * env, jclass cls, jlong np) { BLURAY* bd = (BLURAY*)(intptr_t)np; + + BD_DEBUG(DBG_JNI, "getUOMaskN()\n"); return bd_get_uo_mask(bd); } JNIEXPORT void JNICALL Java_org_videolan_Libbluray_setUOMaskN(JNIEnv * env, jclass cls, jlong np, jboolean menuCallMask, jboolean titleSearchMask) { BLURAY* bd = (BLURAY*)(intptr_t)np; + + BD_DEBUG(DBG_JNI, "setUOMaskN(%d,%d)\n", (int)menuCallMask, (int)titleSearchMask); bd_set_bdj_uo_mask(bd, ((!!menuCallMask) * BDJ_MENU_CALL_MASK) | ((!!titleSearchMask) * BDJ_TITLE_SEARCH_MASK)); } +JNIEXPORT void JNICALL Java_org_videolan_Libbluray_setKeyInterestN(JNIEnv * env, + jclass cls, jlong np, jint mask) { + BLURAY* bd = (BLURAY*)(intptr_t)np; + + BD_DEBUG(DBG_JNI, "setKeyInterestN(0x%x)\n", (int)mask); + bd_set_bdj_kit(bd, mask); +} + JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_setVirtualPackageN(JNIEnv * env, jclass cls, jlong np, jstring vpPath, jboolean psr_init_backup) { BLURAY* bd = (BLURAY*)(intptr_t)np; @@ -273,6 +287,12 @@ return bd_select_angle(bd, angle - 1); } +JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_soundEffectN(JNIEnv * env, + jclass cls, jlong np, jint id) { + BLURAY* bd = (BLURAY*)(intptr_t)np; + return bd_bdj_sound_effect(bd, id); +} + JNIEXPORT jlong JNICALL Java_org_videolan_Libbluray_tellTimeN(JNIEnv * env, jclass cls, jlong np) { BLURAY* bd = (BLURAY*)(intptr_t)np; @@ -609,6 +629,11 @@ VC(Java_org_videolan_Libbluray_setUOMaskN), }, { + CC("setKeyInterestN"), + CC("(JI)V"), + VC(Java_org_videolan_Libbluray_setKeyInterestN), + }, + { CC("getTitleInfosN"), CC("(J)[Lorg/videolan/TitleInfo;"), VC(Java_org_videolan_Libbluray_getTitleInfosN), @@ -644,6 +669,11 @@ VC(Java_org_videolan_Libbluray_selectAngleN), }, { + CC("soundEffectN"), + CC("(JI)I"), + VC(Java_org_videolan_Libbluray_soundEffectN), + }, + { CC("tellTimeN"), CC("(J)J"), VC(Java_org_videolan_Libbluray_tellTimeN), diff -Nru libbluray-0.8.0/src/libbluray/bdj/native/org_videolan_Libbluray.h libbluray-0.8.1/src/libbluray/bdj/native/org_videolan_Libbluray.h --- libbluray-0.8.0/src/libbluray/bdj/native/org_videolan_Libbluray.h 2015-02-28 16:45:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/native/org_videolan_Libbluray.h 2015-05-15 09:25:06.000000000 +0000 @@ -110,7 +110,7 @@ /* * Class: org_videolan_Libbluray - * Method: getUOMask + * Method: setUOMask * Signature: (JZZ)V */ JNIEXPORT void JNICALL Java_org_videolan_Libbluray_setUOMaskN @@ -118,6 +118,14 @@ /* * Class: org_videolan_Libbluray + * Method: setKeyInterestN + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_org_videolan_Libbluray_setKeyInterestN +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_videolan_Libbluray * Method: getTitleInfosN * Signature: (J)[Lorg/videolan/TitleInfo; */ @@ -173,6 +181,14 @@ (JNIEnv *, jclass, jlong, jint); /* + * Class: org_videolan_Libbluray + * Method: soundEffectN + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_soundEffectN + (JNIEnv *, jclass, jlong, jint); + +/* * Class: org_videolan_Libbluray * Method: tellTimeN * Signature: (J)J diff -Nru libbluray-0.8.0/src/libbluray/bdj/native/register_native.c libbluray-0.8.1/src/libbluray/bdj/native/register_native.c --- libbluray-0.8.0/src/libbluray/bdj/native/register_native.c 2015-04-06 15:44:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/native/register_native.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "register_native.h" #include "util/logging.h" diff -Nru libbluray-0.8.0/src/libbluray/bdj/native/util.c libbluray-0.8.1/src/libbluray/bdj/native/util.c --- libbluray-0.8.0/src/libbluray/bdj/native/util.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdj/native/util.c 2015-05-15 09:25:06.000000000 +0000 @@ -18,6 +18,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "util.h" #include "util/logging.h" diff -Nru libbluray-0.8.0/src/libbluray/bdnav/bdid_parse.c libbluray-0.8.1/src/libbluray/bdnav/bdid_parse.c --- libbluray-0.8.0/src/libbluray/bdnav/bdid_parse.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdnav/bdid_parse.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "bdid_parse.h" #include "disc/disc.h" diff -Nru libbluray-0.8.0/src/libbluray/bdnav/clpi_parse.c libbluray-0.8.1/src/libbluray/bdnav/clpi_parse.c --- libbluray-0.8.0/src/libbluray/bdnav/clpi_parse.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdnav/clpi_parse.c 2015-05-15 09:25:06.000000000 +0000 @@ -18,6 +18,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "clpi_parse.h" #include "extdata_parse.h" diff -Nru libbluray-0.8.0/src/libbluray/bdnav/extdata_parse.c libbluray-0.8.1/src/libbluray/bdnav/extdata_parse.c --- libbluray-0.8.0/src/libbluray/bdnav/extdata_parse.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdnav/extdata_parse.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,9 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif #include "util/bits.h" #include "extdata_parse.h" diff -Nru libbluray-0.8.0/src/libbluray/bdnav/index_parse.c libbluray-0.8.1/src/libbluray/bdnav/index_parse.c --- libbluray-0.8.0/src/libbluray/bdnav/index_parse.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdnav/index_parse.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "index_parse.h" #include "disc/disc.h" diff -Nru libbluray-0.8.0/src/libbluray/bdnav/mpls_parse.c libbluray-0.8.1/src/libbluray/bdnav/mpls_parse.c --- libbluray-0.8.0/src/libbluray/bdnav/mpls_parse.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdnav/mpls_parse.c 2015-05-15 09:25:06.000000000 +0000 @@ -18,6 +18,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "mpls_parse.h" #include "extdata_parse.h" @@ -56,6 +60,8 @@ BITBUFFER bb; bb_init(&bb, buf, 8); + memset(uo, 0, sizeof(BD_UO_MASK)); + uo->menu_call = bb_read(&bb, 1); uo->title_search = bb_read(&bb, 1); uo->chapter_search = bb_read(&bb, 1); diff -Nru libbluray-0.8.0/src/libbluray/bdnav/sound_parse.c libbluray-0.8.1/src/libbluray/bdnav/sound_parse.c --- libbluray-0.8.0/src/libbluray/bdnav/sound_parse.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdnav/sound_parse.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "sound_parse.h" #include "disc/disc.h" diff -Nru libbluray-0.8.0/src/libbluray/bdnav/uo_mask_table.h libbluray-0.8.1/src/libbluray/bdnav/uo_mask_table.h --- libbluray-0.8.0/src/libbluray/bdnav/uo_mask_table.h 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bdnav/uo_mask_table.h 2015-05-15 09:25:06.000000000 +0000 @@ -22,6 +22,11 @@ #include +enum { + UO_MASK_MENU_CALL_INDEX = 0, + UO_MASK_TITLE_SEARCH_INDEX = 1, +}; + typedef struct bd_uo_mask_table_s { unsigned int menu_call : 1; @@ -63,9 +68,9 @@ static inline BD_UO_MASK bd_uo_mask_combine(BD_UO_MASK a, BD_UO_MASK b) { union { - BD_UO_MASK mask; uint64_t u64; - } mask_a, mask_b, result; + BD_UO_MASK mask; + } mask_a = {0}, mask_b = {0}, result; mask_a.mask = a; mask_b.mask = b; @@ -78,9 +83,12 @@ static inline BD_UO_MASK bd_empty_uo_mask(void) { - const BD_UO_MASK empty = EMPTY_UO_MASK; - return empty; -} + static const union { + const uint64_t u64; + const BD_UO_MASK mask; + } empty = {0}; + return empty.mask; +} #endif // _BD_UO_MASK_TABLE_H_ diff -Nru libbluray-0.8.0/src/libbluray/bluray.c libbluray-0.8.1/src/libbluray/bluray.c --- libbluray-0.8.0/src/libbluray/bluray.c 2015-04-15 08:30:17.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bluray.c 2015-05-15 09:25:06.000000000 +0000 @@ -83,12 +83,17 @@ /* current aligned unit */ uint16_t int_buf_off; + /* current stream UO mask (combined from playlist and current clip UO masks) */ BD_UO_MASK uo_mask; /* internally handled pids */ uint16_t ig_pid; /* pid of currently selected IG stream */ uint16_t pg_pid; /* pid of currently selected PG stream */ + /* */ + uint8_t eof_hit; + uint8_t encrypted_block_cnt; + M2TS_FILTER *m2ts_filter; } BD_STREAM; @@ -115,8 +120,8 @@ uint64_t s_pos; /* streams */ - BD_STREAM st0; /* main path */ - BD_PRELOAD st_ig; /* preloaded IG stream sub path */ + BD_STREAM st0; /* main path */ + BD_PRELOAD st_ig; /* preloaded IG stream sub path */ BD_PRELOAD st_textst; /* preloaded TextST sub path */ /* buffer for bd_read(): current aligned unit of main stream (st0) */ @@ -133,26 +138,32 @@ int next_mark; /* player state */ - BD_REGISTERS *regs; // player registers - BD_EVENT_QUEUE *event_queue; // navigation mode event queue - BD_TITLE_TYPE title_type; // type of current title (in navigation mode) + BD_REGISTERS *regs; /* player registers */ + BD_EVENT_QUEUE *event_queue; /* navigation mode event queue */ + BD_UO_MASK uo_mask; /* Current UO mask */ + BD_UO_MASK title_uo_mask; /* UO mask from current .bdjo file or Movie Object */ + BD_TITLE_TYPE title_type; /* type of current title (in navigation mode) */ /* Pending action after playlist end * BD-J: delayed sending of BDJ_EVENT_END_OF_PLAYLIST * 1 - message pending. 3 - message sent. */ uint8_t end_of_playlist; /* 1 - reached. 3 - processed . */ + /* HDMV */ HDMV_VM *hdmv_vm; - uint8_t hdmv_suspended; + uint8_t hdmv_suspended; + + /* BD-J */ #ifdef USING_BDJAVA BDJAVA *bdjava; BDJ_STORAGE bdjstorage; -#endif uint8_t bdj_wait_start; /* BD-J has selected playlist (prefetch) but not yet started playback */ +#endif /* HDMV graphics */ GRAPHICS_CONTROLLER *graphics_controller; SOUND_DATA *sound_effects; + BD_UO_MASK gc_uo_mask; /* UO mask from current menu page */ uint32_t gc_status; uint8_t decode_pg; @@ -166,7 +177,6 @@ bd_argb_overlay_proc_f argb_overlay_proc; BD_ARGB_BUFFER *argb_buffer; BD_MUTEX argb_buffer_mutex; - BD_UO_MASK bdj_uo_mask; #endif }; @@ -515,6 +525,48 @@ } /* + * UO mask + */ + +static uint32_t _compressed_mask(BD_UO_MASK mask) +{ + return mask.menu_call | (mask.title_search << 1); +} + +static void _update_uo_mask(BLURAY *bd) +{ + BD_UO_MASK old_mask = bd->uo_mask; + BD_UO_MASK new_mask; + + new_mask = bd_uo_mask_combine(bd->title_uo_mask, bd->st0.uo_mask); + new_mask = bd_uo_mask_combine(bd->gc_uo_mask, new_mask); + if (_compressed_mask(old_mask) != _compressed_mask(new_mask)) { + _queue_event(bd, BD_EVENT_UO_MASK_CHANGED, _compressed_mask(new_mask)); + } + 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); + bd->title_uo_mask.title_search = !!(mask & HDMV_TITLE_SEARCH_MASK); + bd->title_uo_mask.menu_call = !!(mask & HDMV_MENU_CALL_MASK); + + _update_uo_mask(bd); +} + + +/* * clip access (BD_STREAM) */ @@ -526,9 +578,6 @@ } m2ts_filter_close(&st->m2ts_filter); - - /* reset UO mask */ - memset(&st->uo_mask, 0, sizeof(st->uo_mask)); } static int _open_m2ts(BLURAY *bd, BD_STREAM *st) @@ -540,6 +589,8 @@ st->clip_size = 0; st->clip_pos = (uint64_t)st->clip->start_pkt * 192; st->clip_block_pos = (st->clip_pos / 6144) * 6144; + st->eof_hit = 0; + st->encrypted_block_cnt = 0; if (st->fp) { int64_t clip_size = file_size(st->fp); @@ -560,6 +611,7 @@ st->uo_mask = bd_uo_mask_combine(pl->app_info.uo_mask, pl->play_item[st->clip->ref].uo_mask); + _update_uo_mask(bd); st->m2ts_filter = m2ts_filter_init((int64_t)st->clip->in_time << 1, (int64_t)st->clip->out_time << 1, @@ -585,6 +637,61 @@ return 0; } +static int _validate_unit(BLURAY *bd, BD_STREAM *st, uint8_t *buf) +{ + /* Check TP_extra_header Copy_permission_indicator. If != 0, unit may be encrypted. */ + /* Check first sync byte. It should never be encrypted. */ + if (BD_UNLIKELY(buf[0] & 0xc0 || buf[4] != 0x47)) { + + /* Check first sync bytes. If not OK, drop unit. */ + if (buf[4] != 0x47 || buf [4 + 192] != 0x47 || buf[4 + 2*192] != 0x47 || buf[4 + 3*192] != 0x47) { + + /* Some streams have Copy_permission_indicator incorrectly set. */ + /* Check first TS sync byte. If unit is encrypted, first 16 bytes are plain, rest not. */ + /* not 100% accurate (can be random data too). But the unit is broken anyway ... */ + if (buf[4] == 0x47) { + + /* most likely encrypted stream. Check couple of blocks before erroring out. */ + st->encrypted_block_cnt++; + + if (st->encrypted_block_cnt > 10) { + /* error out */ + BD_DEBUG(DBG_BLURAY | DBG_CRIT, "TP header copy permission indicator != 0. Stream seems to be encrypted.\n"); + _queue_event(bd, BD_EVENT_ENCRYPTED, BD_ERROR_AACS); + return -1; + } + } + + /* broken block, ignore it */ + _queue_event(bd, BD_EVENT_READ_ERROR, 1); + return 0; + } + } + + st->eof_hit = 0; + st->encrypted_block_cnt = 0; + return 1; +} + +static int _skip_unit(BLURAY *bd, BD_STREAM *st) +{ + const size_t len = 6144; + + /* skip broken unit */ + st->clip_block_pos += len; + st->clip_pos += len; + + _queue_event(bd, BD_EVENT_READ_ERROR, 0); + + /* seek to next unit start */ + if (file_seek(st->fp, st->clip_block_pos, SEEK_SET) < 0) { + BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Unable to seek clip %s!\n", st->clip->name); + return -1; + } + + return 0; +} + static int _read_block(BLURAY *bd, BD_STREAM *st, uint8_t *buf) { const size_t len = 6144; @@ -596,20 +703,19 @@ size_t read_len; if ((read_len = file_read(st->fp, buf, len))) { + int error; + if (read_len != len) { BD_DEBUG(DBG_STREAM | DBG_CRIT, "Read %d bytes at %"PRIu64" ; requested %d !\n", (int)read_len, st->clip_block_pos, (int)len); + return _skip_unit(bd, st); } st->clip_block_pos += len; - /* Check TP_extra_header Copy_permission_indicator. If != 0, unit is still encrypted. */ - if (buf[0] & 0xc0) { - /* check first TS sync bytes. First 16 bytes are always plain. */ - if (buf[4] == 0x47 && (buf[4+192] != 0x47 || buf[4+2*192] != 0x47)) { - BD_DEBUG(DBG_BLURAY | DBG_CRIT, - "TP header copy permission indicator != 0, unit is still encrypted?\n"); - _queue_event(bd, BD_EVENT_ENCRYPTED, BD_ERROR_AACS); - return -1; - } + if ((error = _validate_unit(bd, st, buf)) <= 0) { + /* skip broken unit */ + BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Skipping broken unit at %"PRId64"\n", st->clip_block_pos - len); + st->clip_pos += len; + return error; } if (st->m2ts_filter) { @@ -632,22 +738,9 @@ BD_DEBUG(DBG_STREAM | DBG_CRIT, "Read unit at %"PRIu64" failed !\n", st->clip_block_pos); - _queue_event(bd, BD_EVENT_READ_ERROR, 0); - - /* skip broken unit */ - st->clip_block_pos += len; - st->clip_pos += len; - - if (file_seek(st->fp, st->clip_block_pos, SEEK_SET) < 0) { - BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Unable to seek clip %s!\n", st->clip->name); - return -1; - } - - return 0; + return _skip_unit(bd, st); } - BD_DEBUG(DBG_STREAM | DBG_CRIT, "Read past EOF !\n"); - /* This is caused by truncated .m2ts file or invalid clip length. * * Increase position to avoid infinite loops. @@ -656,6 +749,11 @@ st->clip_block_pos += len; st->clip_pos += len; + if (!st->eof_hit) { + BD_DEBUG(DBG_STREAM | DBG_CRIT, "Read past EOF !\n"); + st->eof_hit = 1; + } + return 0; } @@ -790,6 +888,9 @@ _queue_event(bd, BD_EVENT_SOUND_EFFECT, cmds.sound_id_ref); } + bd->gc_uo_mask = cmds.page_uo_mask; + _update_uo_mask(bd); + } else { if (bd->gc_status & GC_STATUS_MENU_OPEN) { _queue_event(bd, BD_EVENT_MENU, 0); @@ -1006,14 +1107,6 @@ #endif #ifdef USING_BDJAVA -void bd_set_bdj_uo_mask(BLURAY *bd, unsigned mask) -{ - bd->bdj_uo_mask.title_search = !!(mask & BDJ_TITLE_SEARCH_MASK); - bd->bdj_uo_mask.menu_call = !!(mask & BDJ_MENU_CALL_MASK); -} -#endif - -#ifdef USING_BDJAVA uint64_t bd_get_uo_mask(BLURAY *bd) { /* internal function. Used by BD-J. */ @@ -1023,7 +1116,7 @@ } mask = {0}; //bd_mutex_lock(&bd->mutex); - memcpy(&mask.mask, &bd->st0.uo_mask, sizeof(BD_UO_MASK)); + memcpy(&mask.mask, &bd->uo_mask, sizeof(BD_UO_MASK)); //bd_mutex_unlock(&bd->mutex); return mask.u64; @@ -1031,6 +1124,13 @@ #endif #ifdef USING_BDJAVA +void bd_set_bdj_kit(BLURAY *bd, int mask) +{ + _queue_event(bd, BD_EVENT_KEY_INTEREST_TABLE, mask); +} +#endif + +#ifdef USING_BDJAVA void bd_select_rate(BLURAY *bd, float rate, int reason) { if (reason == BDJ_PLAYBACK_STOP) { @@ -1215,8 +1315,6 @@ } } - memset(&bd->bdj_uo_mask, 0, sizeof(BD_UO_MASK)); - return !bdj_process_event(bd->bdjava, BDJ_EVENT_START, title); #else (void)bd; @@ -1243,6 +1341,7 @@ if (bd->bdjava != NULL) { bdj_process_event(bd->bdjava, BDJ_EVENT_STOP, 0); _queue_event(bd, BD_EVENT_STILL, 0); + _queue_event(bd, BD_EVENT_KEY_INTEREST_TABLE, 0); } } #else @@ -1362,7 +1461,10 @@ return NULL; } - bd_open_disc(bd, device_path, keyfile_path); + if (!bd_open_disc(bd, device_path, keyfile_path)) { + bd_close(bd); + return NULL; + } return bd; } @@ -2136,6 +2238,11 @@ nav_title_close(bd->title); bd->title = NULL; } + + /* reset UO mask */ + memset(&bd->st0.uo_mask, 0, sizeof(BD_UO_MASK)); + memset(&bd->gc_uo_mask, 0, sizeof(BD_UO_MASK)); + _update_uo_mask(bd); } static int _open_playlist(BLURAY *bd, const char *f_name, unsigned angle) @@ -2233,7 +2340,9 @@ 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); @@ -2251,6 +2360,20 @@ 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 @@ -2808,6 +2931,7 @@ break; case PSR_PRIMARY_AUDIO_ID: + _bdj_event(bd, BDJ_EVENT_AUDIO_STREAM, ev->new_val); _queue_event(bd, BD_EVENT_AUDIO_STREAM, ev->new_val); break; @@ -2842,6 +2966,7 @@ _queue_event(bd, BD_EVENT_SECONDARY_AUDIO, !!(ev->new_val & 0x40000000)); _queue_event(bd, BD_EVENT_SECONDARY_AUDIO_STREAM, ev->new_val & 0xff); } + _bdj_event(bd, BDJ_EVENT_SECONDARY_STREAM, ev->new_val); break; /* 3D status */ @@ -3066,27 +3191,12 @@ return 0; } - if (bd->st0.uo_mask.title_search) { - BD_DEBUG(DBG_BLURAY | DBG_CRIT, "title search masked by stream\n"); + if (bd->uo_mask.title_search) { + BD_DEBUG(DBG_BLURAY | DBG_CRIT, "title search masked\n"); + _bdj_event(bd, BDJ_EVENT_UO_MASKED, UO_MASK_TITLE_SEARCH_INDEX); return 0; } - if (bd->title_type == title_hdmv) { - if (hdmv_vm_get_uo_mask(bd->hdmv_vm) & HDMV_TITLE_SEARCH_MASK) { - BD_DEBUG(DBG_BLURAY | DBG_CRIT, "title search masked by movie object\n"); - return 0; - } - } - -#ifdef USING_BDJAVA - if (bd->title_type == title_bdj) { - if (bd->bdj_uo_mask.title_search) { - BD_DEBUG(DBG_BLURAY | DBG_CRIT, "title search masked by BD-J\n"); - return 0; - } - } -#endif - return _play_title(bd, title); } @@ -3110,31 +3220,18 @@ return 0; } - if (bd->st0.uo_mask.menu_call) { - BD_DEBUG(DBG_BLURAY | DBG_CRIT, "menu call masked by stream\n"); + if (bd->uo_mask.menu_call) { + BD_DEBUG(DBG_BLURAY | DBG_CRIT, "menu call masked\n"); + _bdj_event(bd, BDJ_EVENT_UO_MASKED, UO_MASK_MENU_CALL_INDEX); return 0; } if (bd->title_type == title_hdmv) { - if (hdmv_vm_get_uo_mask(bd->hdmv_vm) & HDMV_MENU_CALL_MASK) { - BD_DEBUG(DBG_BLURAY | DBG_CRIT, "menu call masked by movie object\n"); - return 0; - } - if (hdmv_vm_suspend_pl(bd->hdmv_vm) < 0) { BD_DEBUG(DBG_BLURAY | DBG_CRIT, "bd_menu_call(): error storing playback location\n"); } } -#ifdef USING_BDJAVA - if (bd->title_type == title_bdj) { - if (bd->bdj_uo_mask.menu_call) { - BD_DEBUG(DBG_BLURAY | DBG_CRIT, "menu call masked by BD-J\n"); - return 0; - } - } -#endif - return _play_title(bd, BLURAY_TITLE_TOP_MENU); } @@ -3230,6 +3327,9 @@ /* update VM state */ bd->hdmv_suspended = !hdmv_vm_running(bd->hdmv_vm); + /* update UO mask */ + _update_hdmv_uo_mask(bd); + return 0; } @@ -3275,6 +3375,7 @@ 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)); @@ -3293,6 +3394,7 @@ return 0; } } +#endif int bytes = _bd_read(bd, buf, len); diff -Nru libbluray-0.8.0/src/libbluray/bluray.h libbluray-0.8.1/src/libbluray/bluray.h --- libbluray-0.8.0/src/libbluray/bluray.h 2015-03-20 13:13:51.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bluray.h 2015-05-15 09:25:06.000000000 +0000 @@ -727,7 +727,13 @@ /* 3D */ BD_EVENT_STEREOSCOPIC_STATUS = 27, /* 0 - 2D, 1 - 3D */ - /*BD_EVENT_LAST = 31, */ + /* BD-J key interest table changed */ + BD_EVENT_KEY_INTEREST_TABLE = 32, /* bitmask, BLURAY_KIT_* */ + + /* UO mask changed */ + BD_EVENT_UO_MASK_CHANGED = 33, /* bitmask, BLURAY_UO_* */ + + /*BD_EVENT_LAST = 33, */ } bd_event_e; @@ -748,6 +754,23 @@ #define BLURAY_TITLE_FIRST_PLAY 0xffff #define BLURAY_TITLE_TOP_MENU 0 +/* BD_EVENT_KEY_INTEREST flags */ +#define BLURAY_KIT_PLAY 0x1 +#define BLURAY_KIT_STOP 0x2 +#define BLURAY_KIT_FFW 0x4 +#define BLURAY_KIT_REW 0x8 +#define BLURAY_KIT_TRACK_NEXT 0x10 +#define BLURAY_KIT_TRACK_PREV 0x20 +#define BLURAY_KIT_PAUSE 0x40 +#define BLURAY_KIT_STILL_OFF 0x80 +#define BLURAY_KIT_SEC_AUDIO 0x100 +#define BLURAY_KIT_SEC_VIDEO 0x200 +#define BLURAY_KIT_PG_TEXTST 0x400 + +/* BD_EVENT_UO_MASK flags */ +#define BLURAY_UO_MENU_CALL 0x1 +#define BLURAY_UO_TITLE_SEARCH 0x2 + /** * * Get event from libbluray event queue. diff -Nru libbluray-0.8.0/src/libbluray/bluray_internal.h libbluray-0.8.1/src/libbluray/bluray_internal.h --- libbluray-0.8.0/src/libbluray/bluray_internal.h 2015-02-18 09:08:30.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bluray_internal.h 2015-05-15 09:25:06.000000000 +0000 @@ -38,7 +38,7 @@ BD_PRIVATE int bd_set_virtual_package(struct bluray *bd, const char *vp_path, int psr_init_backup); /* - * UO mask + * UO mask, KIT */ #define BDJ_MENU_CALL_MASK 0x01 @@ -46,6 +46,7 @@ BD_PRIVATE uint64_t bd_get_uo_mask(struct bluray *bd); BD_PRIVATE void bd_set_bdj_uo_mask(struct bluray *bd, unsigned mask); +BD_PRIVATE void bd_set_bdj_kit(struct bluray *bd, int mask); /* * title selection @@ -73,6 +74,7 @@ BD_PRIVATE int bd_play_playlist_at(struct bluray *bd, int playlist, int playitem, int playmark, int64_t time); BD_PRIVATE void bd_select_rate(struct bluray *bd, float rate, int reason); BD_PRIVATE int bd_bdj_seek(struct bluray *bd, int playitem, int playmark, int64_t time); +BD_PRIVATE int bd_bdj_sound_effect(struct bluray *bd, int id); /* * BD-J overlay diff -Nru libbluray-0.8.0/src/libbluray/bluray-version.h libbluray-0.8.1/src/libbluray/bluray-version.h --- libbluray-0.8.0/src/libbluray/bluray-version.h 2015-04-15 08:40:17.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/bluray-version.h 2015-05-15 09:42:37.000000000 +0000 @@ -27,9 +27,9 @@ #define BLURAY_VERSION_MAJOR 0 #define BLURAY_VERSION_MINOR 8 -#define BLURAY_VERSION_MICRO 0 +#define BLURAY_VERSION_MICRO 1 -#define BLURAY_VERSION_STRING "0.8.0" +#define BLURAY_VERSION_STRING "0.8.1" #define BLURAY_VERSION \ BLURAY_VERSION_CODE(BLURAY_VERSION_MAJOR, BLURAY_VERSION_MINOR, BLURAY_VERSION_MICRO) diff -Nru libbluray-0.8.0/src/libbluray/decoders/graphics_controller.c libbluray-0.8.1/src/libbluray/decoders/graphics_controller.c --- libbluray-0.8.0/src/libbluray/decoders/graphics_controller.c 2015-02-28 16:45:26.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/decoders/graphics_controller.c 2015-05-15 09:25:06.000000000 +0000 @@ -38,6 +38,11 @@ #include "../register.h" #include "../keys.h" +#ifdef _WIN32 +/* mingw: PRId64 seems to expands to %d without stdio.h ... */ +#include +#endif + #include #include @@ -81,7 +86,7 @@ BD_UO_MASK page_uo_mask; /* page effects */ - int effect_idx; + unsigned effect_idx; BD_IG_EFFECT_SEQUENCE *in_effects; BD_IG_EFFECT_SEQUENCE *out_effects; int64_t next_effect_time; /* 90 kHz */ @@ -692,7 +697,6 @@ _select_button(gc, button_id); gc->valid_mouse_position = 0; - gc->page_uo_mask = bd_empty_uo_mask(); if (out_effects) { page = _find_page(&gc->igs->ics->interactive_composition, cur_page_id); @@ -1364,6 +1368,8 @@ if (s->ics->interactive_composition.ui_model == IG_UI_MODEL_POPUP && !gc->popup_visible) { + gc->page_uo_mask = bd_empty_uo_mask(); + if (gc->ig_open) { GC_TRACE("_render_page(): popup menu not visible\n"); _close_osd(gc, BD_OVERLAY_IG); @@ -1381,13 +1387,6 @@ } gc->out_effects = NULL; } - if (gc->in_effects) { - if (gc->effect_idx < gc->in_effects->num_effects) { - _render_effect(gc, &gc->in_effects->effect[gc->effect_idx]); - return 1; - } - gc->in_effects = NULL; - } page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { @@ -1396,6 +1395,16 @@ return -1; } + gc->page_uo_mask = page->uo_mask_table; + + if (gc->in_effects) { + if (gc->effect_idx < gc->in_effects->num_effects) { + _render_effect(gc, &gc->in_effects->effect[gc->effect_idx]); + return 1; + } + gc->in_effects = NULL; + } + palette = _find_palette(s, page->palette_id_ref); if (!palette) { GC_ERROR("_render_page: unknown palette id %d (have %d palettes)\n", @@ -1412,8 +1421,6 @@ s->ics->video_descriptor.video_height); } - gc->page_uo_mask = page->uo_mask_table; - for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; unsigned valid_id = gc->bog_data[ii].enabled_button; @@ -2053,7 +2060,7 @@ } } - if (gc->ig_open && !gc->out_effects) { + if (gc->ig_open) { cmds->page_uo_mask = gc->page_uo_mask; } } diff -Nru libbluray-0.8.0/src/libbluray/decoders/graphics_processor.c libbluray-0.8.1/src/libbluray/decoders/graphics_processor.c --- libbluray-0.8.0/src/libbluray/decoders/graphics_processor.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/decoders/graphics_processor.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "graphics_processor.h" #include "ig_decode.h" diff -Nru libbluray-0.8.0/src/libbluray/decoders/ig_decode.c libbluray-0.8.1/src/libbluray/decoders/ig_decode.c --- libbluray-0.8.0/src/libbluray/decoders/ig_decode.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/decoders/ig_decode.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "ig_decode.h" #include "pg_decode.h" // pg_decode_*() diff -Nru libbluray-0.8.0/src/libbluray/decoders/m2ts_demux.c libbluray-0.8.1/src/libbluray/decoders/m2ts_demux.c --- libbluray-0.8.0/src/libbluray/decoders/m2ts_demux.c 2015-02-18 09:08:30.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/decoders/m2ts_demux.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "m2ts_demux.h" #include "pes_buffer.h" diff -Nru libbluray-0.8.0/src/libbluray/decoders/pes_buffer.c libbluray-0.8.1/src/libbluray/decoders/pes_buffer.c --- libbluray-0.8.0/src/libbluray/decoders/pes_buffer.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/decoders/pes_buffer.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "pes_buffer.h" #include "util/macro.h" diff -Nru libbluray-0.8.0/src/libbluray/decoders/pg_decode.c libbluray-0.8.1/src/libbluray/decoders/pg_decode.c --- libbluray-0.8.0/src/libbluray/decoders/pg_decode.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/decoders/pg_decode.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "pg_decode.h" #include "util/refcnt.h" diff -Nru libbluray-0.8.0/src/libbluray/decoders/rle.c libbluray-0.8.1/src/libbluray/decoders/rle.c --- libbluray-0.8.0/src/libbluray/decoders/rle.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/decoders/rle.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "rle.h" #include "util/logging.h" diff -Nru libbluray-0.8.0/src/libbluray/decoders/textst_decode.c libbluray-0.8.1/src/libbluray/decoders/textst_decode.c --- libbluray-0.8.0/src/libbluray/decoders/textst_decode.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/decoders/textst_decode.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "textst_decode.h" #include "pg_decode.h" // pg_decode_*() diff -Nru libbluray-0.8.0/src/libbluray/disc/aacs.c libbluray-0.8.1/src/libbluray/disc/aacs.c --- libbluray-0.8.0/src/libbluray/disc/aacs.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/disc/aacs.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "aacs.h" #include "file/dl.h" diff -Nru libbluray-0.8.0/src/libbluray/disc/bdplus.c libbluray-0.8.1/src/libbluray/disc/bdplus.c --- libbluray-0.8.0/src/libbluray/disc/bdplus.c 2015-03-06 07:38:13.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/disc/bdplus.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "bdplus.h" #include "file/dl.h" diff -Nru libbluray-0.8.0/src/libbluray/disc/disc.c libbluray-0.8.1/src/libbluray/disc/disc.c --- libbluray-0.8.0/src/libbluray/disc/disc.c 2015-04-15 08:39:49.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/disc/disc.c 2015-05-15 09:25:06.000000000 +0000 @@ -96,7 +96,7 @@ if (p->overlay_root) { char *abs_path = str_printf("%s%s", p->overlay_root, rel_path); - fp = file_open_default()(abs_path, "rb"); + fp = file_open(abs_path, "rb"); X_FREE(abs_path); } @@ -437,7 +437,7 @@ file_mkdirs(cache_path); /* output file in local filesystem */ - fp_out = file_open_default()(cache_path, "wb"); + fp_out = file_open(cache_path, "wb"); if (!fp_out) { BD_DEBUG(DBG_FILE | DBG_CRIT, "error creating cache file %s\n", cache_path); file_close(fp_in); @@ -471,19 +471,19 @@ BD_FILE_H *disc_open_stream(BD_DISC *disc, const char *file) { - BD_FILE_H *fp = disc_open_file(disc, "BDMV" DIR_SEP "STREAM", file); - if (!fp) { - return NULL; - } - - if (disc->dec) { - BD_FILE_H *st = dec_open_stream(disc->dec, fp, atoi(file)); - if (st) { - return st; - } - } + BD_FILE_H *fp = disc_open_file(disc, "BDMV" DIR_SEP "STREAM", file); + if (!fp) { + return NULL; + } + + if (disc->dec) { + BD_FILE_H *st = dec_open_stream(disc->dec, fp, atoi(file)); + if (st) { + return st; + } + } - return fp; + return fp; } const uint8_t *disc_get_data(BD_DISC *disc, int type) @@ -511,3 +511,88 @@ } } +/* + * Pseudo disc ID + * This is used when AACS disc ID is not available + */ + +#define ROTL64(k, n) (((k) << (n)) | ((k) >> (64 - (n)))) + +static uint64_t _fmix64(uint64_t k) +{ + k ^= k >> 33; + k *= UINT64_C(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= UINT64_C(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + return k; +} + +static void _murmurhash3_128(const uint8_t *in, size_t len, void *out) +{ + // original MurmurHash3 was written by Austin Appleby, and is placed in the public domain. + // https://code.google.com/p/smhasher/wiki/MurmurHash3 + const uint64_t c1 = UINT64_C(0x87c37b91114253d5); + const uint64_t c2 = UINT64_C(0x4cf5ad432745937f); + uint64_t h[2] = {0, 0}; + size_t i; + + /* use only N * 16 bytes, ignore tail */ + len &= ~15; + + for (i = 0; i < len; i += 16) { + uint64_t k1, k2; + memcpy(&k1, in + i, sizeof(uint64_t)); + memcpy(&k2, in + i + 8, sizeof(uint64_t)); + + k1 *= c1; k1 = ROTL64(k1, 31); k1 *= c2; h[0] ^= k1; + + h[0] = ROTL64(h[0], 27); h[0] += h[1]; h[0] = h[0] * 5 + 0x52dce729; + + k2 *= c2; k2 = ROTL64(k2, 33); k2 *= c1; h[1] ^= k2; + + h[1] = ROTL64(h[1], 31); h[1] += h[0]; h[1] = h[1] * 5 + 0x38495ab5; + } + + h[0] ^= len; + h[1] ^= len; + + h[0] += h[1]; + h[1] += h[0]; + + h[0] = _fmix64(h[0]); + h[1] = _fmix64(h[1]); + + h[0] += h[1]; + h[1] += h[0]; + + memcpy(out, h, 2*sizeof(uint64_t)); +} + +static int _hash_file(BD_DISC *p, const char *dir, const char *file, void *hash) +{ + uint8_t *data = NULL; + size_t sz; + + sz = disc_read_file(p, dir, file, &data); + if (sz > 16) { + _murmurhash3_128(data, sz, hash); + } + + X_FREE(data); + return sz > 16; +} + +BD_PRIVATE void disc_pseudo_id(BD_DISC *p, uint8_t *id/*[20]*/) +{ + uint8_t h[2][20]; + int i; + + memset(h, 0, sizeof(h)); + _hash_file(p, "BDMV", "MovieObject.bdmv", h[0]); + _hash_file(p, "BDMV", "index.bdmv", h[1]); + + for (i = 0; i < 20; i++) { + id[i] = h[0][i] ^ h[1][i]; + } +} diff -Nru libbluray-0.8.0/src/libbluray/disc/disc.h libbluray-0.8.1/src/libbluray/disc/disc.h --- libbluray-0.8.0/src/libbluray/disc/disc.h 2015-03-20 13:13:51.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/disc/disc.h 2015-05-15 09:25:06.000000000 +0000 @@ -52,6 +52,9 @@ /* Get UDF volume ID */ BD_PRIVATE const char *disc_volume_id(BD_DISC *); +/* Generate pseudo disc ID */ +BD_PRIVATE void disc_pseudo_id(BD_DISC *, uint8_t *id/*[20]*/); + /* Open VFS file (relative to disc root) */ BD_PRIVATE struct bd_file_s *disc_open_file(BD_DISC *disc, const char *dir, const char *file); BD_PRIVATE struct bd_file_s *disc_open_path(BD_DISC *disc, const char *path); diff -Nru libbluray-0.8.0/src/libbluray/hdmv/hdmv_vm.c libbluray-0.8.1/src/libbluray/hdmv/hdmv_vm.c --- libbluray-0.8.0/src/libbluray/hdmv/hdmv_vm.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/hdmv/hdmv_vm.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "hdmv_vm.h" #include "mobj_data.h" @@ -72,6 +76,92 @@ }; /* + * save / restore VM state + */ + +static int _save_state(HDMV_VM *p, uint32_t *s) +{ + memset(s, 0, sizeof(*s) * HDMV_STATE_SIZE); + + if (p->ig_object) { + BD_DEBUG(DBG_HDMV | DBG_CRIT, "_save_state() failed: button object running\n"); + return -1; + } + if (p->object) { + BD_DEBUG(DBG_HDMV | DBG_CRIT, "_save_state() failed: movie object running\n"); + return -1; + } + if (p->event[0].event != HDMV_EVENT_NONE) { + BD_DEBUG(DBG_HDMV | DBG_CRIT, "_save_state() failed: unprocessed events\n"); + return -1; + } + + if (p->playing_object) { + s[0] = (uint32_t)(p->playing_object - p->movie_objects->objects); + s[1] = p->playing_pc; + } else { + s[0] = (uint32_t)-1; + } + + if (p->suspended_object) { + s[2] = (uint32_t)(p->suspended_object - p->movie_objects->objects); + s[3] = p->suspended_pc; + } else { + s[2] = (uint32_t)-1; + } + + /* nv timer ? */ + + return 0; +} + +static int _restore_state(HDMV_VM *p, const uint32_t *s) +{ + if (s[0] == (uint32_t)-1) { + p->playing_object = NULL; + } else if (s[0] >= p->movie_objects->num_objects) { + BD_DEBUG(DBG_HDMV | DBG_CRIT, "_restore_state() failed: invalid playing object index\n"); + return -1; + } else { + p->playing_object = &p->movie_objects->objects[s[0]]; + } + p->playing_pc = s[1]; + + if (s[2] == (uint32_t)-1) { + p->suspended_object = NULL; + } else if (s[2] >= p->movie_objects->num_objects) { + BD_DEBUG(DBG_HDMV | DBG_CRIT, "_restore_state() failed: invalid suspended object index\n"); + return -1; + } else { + p->suspended_object = &p->movie_objects->objects[s[2]]; + } + p->suspended_pc = s[3]; + + p->object = NULL; + p->ig_object = NULL; + memset(p->event, 0, sizeof(p->event)); + + return 0; +} + +int hdmv_vm_save_state(HDMV_VM *p, uint32_t *s) +{ + int result; + bd_mutex_lock(&p->mutex); + result = _save_state(p, s); + bd_mutex_unlock(&p->mutex); + return result; +} + +void hdmv_vm_restore_state(HDMV_VM *p, const uint32_t *s) +{ + bd_mutex_lock(&p->mutex); + _restore_state(p, s); + bd_mutex_unlock(&p->mutex); +} + + +/* * registers: PSR and GPR access */ @@ -149,7 +239,7 @@ /* store result to destination register(s) */ if (dst != dst0) { if (cmd->insn.imm_op1) { - BD_DEBUG(DBG_HDMV|DBG_CRIT, "ERROR: storing to imm ! "); + BD_DEBUG(DBG_HDMV|DBG_CRIT, "storing to imm !\n"); return -1; } ret = _store_reg(p, cmd->dst, dst); @@ -157,7 +247,7 @@ if (src != src0) { if (cmd->insn.imm_op1) { - BD_DEBUG(DBG_HDMV|DBG_CRIT, "ERROR: storing to imm ! "); + BD_DEBUG(DBG_HDMV|DBG_CRIT, "storing to imm !\n"); return -1; } ret += _store_reg(p, cmd->src, src); @@ -1188,7 +1278,7 @@ bd_mutex_lock(&p->mutex); - if ((o = p->object ? p->object : (p->playing_object ? p->playing_object : p->suspended_object))) { + if ((o = (p->object && !p->ig_object) ? p->object : (p->playing_object ? p->playing_object : p->suspended_object))) { mask |= o->menu_call_mask; mask |= o->title_search_mask << 1; } diff -Nru libbluray-0.8.0/src/libbluray/hdmv/hdmv_vm.h libbluray-0.8.1/src/libbluray/hdmv/hdmv_vm.h --- libbluray-0.8.0/src/libbluray/hdmv/hdmv_vm.h 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/hdmv/hdmv_vm.h 2015-05-15 09:25:06.000000000 +0000 @@ -119,4 +119,15 @@ */ BD_PRIVATE int hdmv_vm_resume(HDMV_VM *p); + +/* + * save / restore VM state + */ + +/* VM state size */ +#define HDMV_STATE_SIZE 10 /* * sizeof(uint32_t) */ + +BD_PRIVATE int hdmv_vm_save_state(HDMV_VM *p, uint32_t *s); +BD_PRIVATE void hdmv_vm_restore_state(HDMV_VM *p, const uint32_t *s); + #endif // _HDMV_VM_H_ diff -Nru libbluray-0.8.0/src/libbluray/hdmv/mobj_parse.c libbluray-0.8.1/src/libbluray/hdmv/mobj_parse.c --- libbluray-0.8.0/src/libbluray/hdmv/mobj_parse.c 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/hdmv/mobj_parse.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "mobj_parse.h" #include "mobj_data.h" diff -Nru libbluray-0.8.0/src/libbluray/hdmv/mobj_print.c libbluray-0.8.1/src/libbluray/hdmv/mobj_print.c --- libbluray-0.8.0/src/libbluray/hdmv/mobj_print.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/hdmv/mobj_print.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "mobj_print.h" #include "mobj_data.h" diff -Nru libbluray-0.8.0/src/libbluray/player_settings.h libbluray-0.8.1/src/libbluray/player_settings.h --- libbluray-0.8.0/src/libbluray/player_settings.h 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/player_settings.h 2015-05-15 09:25:06.000000000 +0000 @@ -21,7 +21,7 @@ #define BD_PLAYER_SETTINGS_H_ /* - * BLURAY_PLAYER_SETTING_AUDIO_CAP (PSR12) + * BLURAY_PLAYER_SETTING_AUDIO_CAP (PSR15) * * Player capability for audio (bitmask) */ diff -Nru libbluray-0.8.0/src/libbluray/register.c libbluray-0.8.1/src/libbluray/register.c --- libbluray-0.8.0/src/libbluray/register.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/register.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "register.h" #include "player_settings.h" @@ -29,9 +33,6 @@ #include #include -#define BD_PSR_COUNT 128 -#define BD_GPR_COUNT 4096 - /* * Initial values for player status/setting registers (5.8.2). * @@ -478,3 +479,54 @@ return result; } + +/* + * save / restore registers between playback sessions + */ + +void registers_save(BD_REGISTERS *p, uint32_t *psr, uint32_t *gpr) +{ + bd_psr_lock(p); + + memcpy(gpr, p->gpr, sizeof(p->gpr)); + memcpy(psr, p->psr, sizeof(p->psr)); + + bd_psr_unlock(p); +} + +void registers_restore(BD_REGISTERS *p, const uint32_t *psr, const uint32_t *gpr) +{ + uint32_t new_psr[13]; + + bd_psr_lock(p); + + memcpy(p->gpr, gpr, sizeof(p->gpr)); + memcpy(p->psr, psr, sizeof(p->psr)); + + memcpy(new_psr, p->psr, sizeof(new_psr[0]) * 13); + + /* generate restore events */ + if (p->num_cb) { + BD_PSR_EVENT ev; + unsigned i, j; + + ev.ev_type = BD_PSR_RESTORE; + ev.old_val = 0; /* not used with BD_PSR_RESTORE */ + + for (i = 4; i < 13; i++) { + if (i != PSR_NAV_TIMER) { + + p->psr[i] = new_psr[i]; + + ev.psr_idx = i; + ev.new_val = new_psr[i]; + + for (j = 0; j < p->num_cb; j++) { + p->cb[j].cb(p->cb[j].handle, &ev); + } + } + } + } + + bd_psr_unlock(p); +} diff -Nru libbluray-0.8.0/src/libbluray/register.h libbluray-0.8.1/src/libbluray/register.h --- libbluray-0.8.0/src/libbluray/register.h 2015-02-12 09:56:04.000000000 +0000 +++ libbluray-0.8.1/src/libbluray/register.h 2015-05-15 09:25:06.000000000 +0000 @@ -24,6 +24,10 @@ #include + +#define BD_PSR_COUNT 128 +#define BD_GPR_COUNT 4096 + /* * Player Status Registers */ @@ -260,4 +264,13 @@ void bd_psr_unregister_cb(BD_REGISTERS *, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle); +/* + * save / restore registers between playback sessions + * + * When state is restored, restore events will be generated and playback state is restored. + */ + +BD_PRIVATE void registers_save(BD_REGISTERS *p, uint32_t *psr, uint32_t *gpr); +BD_PRIVATE void registers_restore(BD_REGISTERS *p, const uint32_t *psr, const uint32_t *gpr); + #endif /* _BD_REGISTER_H_ */ diff -Nru libbluray-0.8.0/src/util/array.c libbluray-0.8.1/src/util/array.c --- libbluray-0.8.0/src/util/array.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/util/array.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "array.h" #include "macro.h" diff -Nru libbluray-0.8.0/src/util/logging.c libbluray-0.8.1/src/util/logging.c --- libbluray-0.8.0/src/util/logging.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/util/logging.c 2015-05-15 09:25:06.000000000 +0000 @@ -18,6 +18,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "logging.h" #include "file/file.h" diff -Nru libbluray-0.8.0/src/util/refcnt.c libbluray-0.8.1/src/util/refcnt.c --- libbluray-0.8.0/src/util/refcnt.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/util/refcnt.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "refcnt.h" #include "logging.h" diff -Nru libbluray-0.8.0/src/util/strutl.c libbluray-0.8.1/src/util/strutl.c --- libbluray-0.8.0/src/util/strutl.c 2015-01-26 08:01:57.000000000 +0000 +++ libbluray-0.8.1/src/util/strutl.c 2015-05-15 09:25:06.000000000 +0000 @@ -17,6 +17,10 @@ * . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include "strutl.h" #include "macro.h" @@ -27,22 +31,37 @@ #include #include -char * str_dup(const char *str) +char *str_dup(const char *str) { - return str ? strcpy (malloc(strlen(str) + 1), str) : NULL; + char *dup = NULL; + + if (str) { + size_t size = strlen(str) + 1; + dup = malloc(size); + if (dup) { + memcpy(dup, str, size); + } + } + return dup; } -char * str_printf(const char *fmt, ...) +char *str_printf(const char *fmt, ...) { /* Guess we need no more than 100 bytes. */ - int len; va_list ap; - int size = 100; - char *tmp, *str = NULL; + int len; + int size = 100; + char *tmp, *str = NULL; + + while (1) { + + tmp = realloc(str, size); + if (tmp == NULL) { + X_FREE(str); + return NULL; + } + str = tmp; - str = malloc(size); - while (1) - { /* Try to print in the allocated space. */ va_start(ap, fmt); len = vsnprintf(str, size, fmt, ap); @@ -58,12 +77,6 @@ size = len+1; /* precisely what is needed */ else /* glibc 2.0 */ size *= 2; /* twice the old size */ - - tmp = realloc(str, size); - if (tmp == NULL) { - return str; - } - str = tmp; } }