[SCM] libdvdnav/master: Revert everything to debian/4.2.1-2
rbalint at users.alioth.debian.org
rbalint at users.alioth.debian.org
Thu Feb 13 19:05:15 UTC 2014
The following commit has been merged in the master branch:
commit 2eb7492d186725d0805e568052ed295bdfa260cd
Author: Balint Reczey <balint at balintreczey.hu>
Date: Thu Feb 13 19:45:21 2014 +0100
Revert everything to debian/4.2.1-2
diff --git a/.gitignore b/.gitignore
index e29bbea..845ca06 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,25 +1 @@
-*.la
-*.lo
-*.o
-*~
-.deps/
-.libs/
-/aclocal.m4
-/autom4te.cache/
-/config.guess
-/config.h
-/config.h.in
-/config.log
-/config.status
-/config.sub
-/configure
-/depcomp
-/install-sh
-/libtool
-/ltmain.sh
-/misc/*.pc
-/misc/libdvdnav.spec
-/missing
-/stamp-h1
-Makefile
-Makefile.in
+.pc
diff --git a/AUTHORS b/AUTHORS
index 9c1da8a..cb528af 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,4 +4,3 @@ Rich Wareham <richwareham at users.sourceforge.net>
Kees Cook <kees at outflux.net>
Michael Roitzsch <mroi at users.sourceforge.net>
Frantisek Dvorak <valtri at users.sourceforge.net>
-Diego Elio Pettenò <flameeyes at flameeyes.eu>
diff --git a/ChangeLog b/ChangeLog
index 1280486..dbb4ca0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
-libdvdnav (5.0.0)
+libdvdnav (4.2.1)
+ * fixed failed assertion on menu-less DVDs
+ * fixed playback issues on multi-angle DVDs
+ * fixed crash when playing a DVD from different region than currently set
+ in the DVD drive
+ * fixed segfaults when reading certain DVDs (including "Jack Reacher",
+ "Ghost Protocol", "Inside Man", "Tangled" and "The Dictator")
libdvdnav (4.2.0)
* OS/2 support
diff --git a/DEVELOPMENT-POLICY.txt b/DEVELOPMENT-POLICY.txt
index b45a02d..20c73e5 100644
--- a/DEVELOPMENT-POLICY.txt
+++ b/DEVELOPMENT-POLICY.txt
@@ -1,25 +1,25 @@
-This fork of (the fork of) dvdnav was created to overcome the lack of
-responsiveness of the official development channel (once again).
+This fork of dvdnav was created to overcome the lack of responsiveness
+of the official development channel, not to bastardize this library in
+something for specific usage by mplayer, so these are the rules to follow
+when developing code:
+- don't remove pre-existing code that mplayer doesn't need
+- don't add code to expose the internals of dvdnav
+- don't add code that binds applications to side-effects of the library
+- don't alter the API in an incompatible manner
-This new fork will try to simplify, stabilize, fix the security issues and the
-numerous crashes and maintain a correct player-agnostic library for DVD playback.
-
-This fork will try to maintain correct authorship tracking and a community
-management.
-
-When developing code:
-- Try to not add code to expose the internals of dvdnav, unless necessary
-- Try to maintain and extend the API in an compatible manner
-- Try to not add code that binds applications to side-effects of the library
-- Don't remove pre-existing code because your player doesn't need
When committing code to the repository always follow these rules:
-- Maintain compilability of the library for every commit
-- Split cosmetical and functional changes in different commits
-- One change == One commit
-- Keep the coding style consistent
-- If you break something by accident, fix it as soon as possible.
-- Trivial patches such as spell fixes, prototype mismatch, missing includes,
- more proper variable typization and similar can be committed right away
+- don't break the compilability of the library - always keep svn checkouts usable
+- never mix cosmetical and functional changes
+- don't commit unrelated changes as a single transaction
+- don't split strictly related changes over multiple commits
+- never alter the indentation / bracing / prototyping style of existing files
+- if you break something by accident fix it as soon as possible using the appropriate
+ svn tools to revert your commit(s). If in doubt ask explanations to the
+ mailing list
+- trivial patches such as spell fixes, prototype mismatch, missing includes,
+ more proper variable typization and similar should be committed without asking
+ prior authorization
+
-Please don't break these rules, or we'll need to act :)
+If in reiterated violation of these rules your account will be deleted.
diff --git a/Makefile.am b/Makefile.am
index 0407065..f03ecaa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,62 +1,42 @@
-AM_CPPFLAGS = -I$(top_srcdir)/src $(THREAD_CFLAGS) $(DVDREAD_CFLAGS)
-
-dist_doc_DATA = AUTHORS ChangeLog COPYING README TODO
-
-EXTRA_DIST = msvc/ \
- src/README.MAP \
- src/FELLOWSHIP.map \
- doc/doxy.conf \
- doc/mainpage.cpp \
- doc/tutorial.cpp \
- doc/dvd_structures \
- doc/library_layout
-
-lib_LTLIBRARIES = libdvdnav.la
-
-libdvdnav_la_SOURCES = \
- src/dvdnav.c \
- src/read_cache.c \
- src/navigation.c \
- src/highlight.c \
- src/searching.c \
- src/settings.c \
- src/remap.c \
- src/dvdnav_internal.h \
- src/read_cache.h \
- src/remap.h \
- src/vm/decoder.c \
- src/vm/decoder.h \
- src/vm/vm.c \
- src/vm/vm.h \
- src/vm/play.c \
- src/vm/play.h \
- src/vm/getset.c \
- src/vm/getset.h \
- src/vm/vmget.c \
- src/vm/vmcmd.c \
- src/vm/vmcmd.h
-
-libdvdnav_la_LDFLAGS = \
- -version-info $(DVDNAV_LT_CURRENT):$(DVDNAV_LT_REVISION):$(DVDNAV_LT_AGE) \
- -export-symbols-regex "^dvdnav"
-libdvdnav_la_LIBADD = $(THREAD_LIBS) $(DVDREAD_LIBS)
-
-pkgincludedir = $(includedir)/dvdnav
-
-pkginclude_HEADERS = \
- src/dvdnav/dvdnav.h \
- src/dvdnav/dvdnav_events.h \
- src/dvdnav/dvd_types.h
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = misc/dvdnav.pc misc/dvdnavmini.pc
-
-EXTRA_PROGRAMS = menus
-
-menus_SOURCES = examples/menus.c
-menus_LDADD = libdvdnav.la
-
-docs: misc/doxy.conf
- @if test x"$(DOXYGEN)" != "xno"; then \
- cd misc && $(DOXYGEN) doxy.conf > /dev/null 2> /dev/null; \
- fi
+include $(top_srcdir)/misc/Makefile.common
+
+
+SUBDIRS = src examples doc misc m4
+
+EXTRA_DIST = autogen.sh \
+ AUTHORS \
+ ChangeLog \
+ configure \
+ config.guess \
+ config.sub \
+ COPYING \
+ INSTALL \
+ install-sh \
+ libtool \
+ ltmain.sh \
+ missing \
+ mkinstalldirs \
+ README \
+ TODO
+
+MOSTLYCLEANFILES += $(PACKAGE)_$(VERSION).tar.gz \
+ $(distdir).tar.gz $(PACKAGE).tgz package_descriptions
+
+MAINTAINERCLEANFILES += configure $(ACLOCAL_M4) config.h.in \
+ ltmain.sh config.guess config.sub install-sh missing \
+ mkinstalldirs
+
+world:
+ @$(MAKE) clean all install 2> warnings.log
+ test -s warnings.log || rm warnings.log
+
+prune-cache:
+ -rm -f config.cache
+
+release-check:
+ @./config.status misc/relchk.sh
+ @./autogen.sh noconfig && $(SHELL) misc/relchk.sh
+
+dist-hook:
+ cp -r $(srcdir)/msvc $(distdir)/msvc
+ rm -rf `find $(distdir)/msvc -name CVS`
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..7aa22b1
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,2 @@
+This file is unused.
+The ChangeLog file lists changes for new versions.
diff --git a/README b/README
index df509cd..de3422c 100644
--- a/README
+++ b/README
@@ -14,7 +14,7 @@ encapsulated.
Where does it come from?
------------------------
-This library was based on a lot of code and expertise from the Ogle project.
+This library is based on a lot of code and expertise from the Ogle project.
Ogle was the first DVD player who implemented free DVD navigation. The
libdvdnav developers wish to express their gratitude to the Ogle people
for all the valuable research work they have done.
@@ -23,17 +23,18 @@ Initially, the dvdnav code was part of a plugin to the xine media player
called xine-dvdnav. Later on, the DVD VM specific code was split
from xine-dvdnav and went into the first version of libdvdnav.
-Then, it was forked, and forked again on MPlayer repositories.
-libdvdnav and libdvdread were merged, and then split again.
+Where is it now?
+----------------
-This is now a new fork libdvdnav, that was created to overcome the lack of
-responsiveness of the official development channel (once again).
+libdvdnav is hosted at http://dvdnav.mplayerhq.hu/ .
+Please report bugs to the developers mailinglist at
+mailto:dvdnav-discuss at mplayerhq.hu .
-This new fork will try to simplify, stabilize, fix the security issues and the
-numerous crashes and maintain a correct player-agnostic library for DVD playback.
-
-This fork will try to maintain correct authorship tracking, by using git and a
-proper history.
+We are still in beta stage, but libdvdnav is already quite usable. With
+regular DVD playback, there should not be any serious issues. The library
+also makes some limited effort to handle error situations gracefully, but
+there are still assertions in the code that may trigger on some DVDs. Please
+send a report to the developer mailinglist, if you encounter such problems.
How can I use it?
-----------------
diff --git a/TODO b/TODO
index 55ffcfe..3fe2eed 100644
--- a/TODO
+++ b/TODO
@@ -9,3 +9,4 @@
* cleanup public API and fix libtool versioning
* Update decoder.c with some of the more rare commands. Update already done to vmcmd.c
* RELEASE! (maybe it's time for libdvdnav 0.5?)
+* Replace the auto* build system with a custom and clean one based on ffmpeg's (partly done)
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..077b682
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname "$0"`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd "$srcdir"
+
+AUTORECONF=${AUTORECONF-autoreconf}
+
+if ! type $AUTORECONF >/dev/null 2>&1; then
+ echo "**Error**: Missing \`autoreconf' program." >&2
+ echo "You will need the autoconf and automake packages." >&2
+ echo "You can download them from ftp://ftp.gnu.org/pub/gnu/." >&2
+ exit 1
+fi
+
+$AUTORECONF -v --install || exit $?
+cd "$ORIGDIR" || exit $?
+
+test "$1" = noconfig && NOCONFIGURE=1
+
+if test -z "$NOCONFIGURE"; then
+ "$srcdir"/configure "$@"
+fi
diff --git a/configure.ac b/configure.ac
index d2ab0b1..0a8d3a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,3 +1,10 @@
+dnl --------------------------------------------------------------
+dnl Configure.ac for libdvdnav
+dnl --------------------------------------------------------------
+
+dnl --------------------------------------------------------------
+dnl Require autoconf version 2.53
+dnl --------------------------------------------------------------
AC_PREREQ([2.53])
dnl --------------------------------------------------------------
@@ -5,16 +12,16 @@ dnl Making releases: dvdnav_sub += 1; change DVDNAV_LT_* accordingly
dnl
dnl These are defined in m4 so they can be passed to AC_INIT
dnl --------------------------------------------------------------
-m4_define([dvdnav_major], [5])
-m4_define([dvdnav_minor], [0])
-m4_define([dvdnav_sub], [0])
+m4_define([dvdnav_major], [4])
+m4_define([dvdnav_minor], [2])
+m4_define([dvdnav_sub], [1])
m4_define([dvdnav_pre], [])
AC_INIT([libdvdnav], [dvdnav_major.dvdnav_minor.dvdnav_sub[]dvdnav_pre])
AC_CONFIG_SRCDIR([src/dvdnav.c])
-m4_include([m4/ax_check_compile_flag.m4])
-AM_INIT_AUTOMAKE([1.6 foreign])
+AM_INIT_AUTOMAKE([1.6])
+dnl create a config.h file (Automake will add -DHAVE_CONFIG_H)
AC_CONFIG_HEADERS([config.h])
AC_CANONICAL_HOST
@@ -60,14 +67,73 @@ AC_SUBST(DVDNAV_LT_CURRENT)
AC_SUBST(DVDNAV_LT_AGE)
AC_SUBST(DVDNAV_LT_REVISION)
+dnl --------------------------------------------------------------
+dnl Make possible to build for another arch.
+dnl --------------------------------------------------------------
+if test x$DVDNAV_BUILD != "x"; then
+ AC_MSG_RESULT(*** build forced to $DVDNAV_BUILD ***)
+ build=$DVDNAV_BUILD
+ host=$DVDNAV_BUILD
+else
+ check_athlon=yes
+fi
+
+dnl --------------------------------------------------------------
+dnl Checks for programs.
+dnl --------------------------------------------------------------
+dnl Save CFLAGS, AC_ISC_POSIX set some unwanted default CFLAGS
+saved_CFLAGS="$CFLAGS"
+AC_ISC_POSIX
+CFLAGS="$saved_CFLAGS"
AC_PROG_CC
-LT_INIT
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+AC_PROG_LN_S
+PKG_PROG_PKG_CONFIG
-AC_SYS_LARGEFILE
+dnl --------------------------------------------------------------
+dnl Libtool
+dnl --------------------------------------------------------------
+dnl LT_PREREQ only available in libtool-2.2+
+dnl LT_PREREQ([1.4.0])
+AC_LIBTOOL_DLOPEN
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+if ${CONFIG_SHELL} ./libtool --features | grep "enable static" >/dev/null; then
+ STATIC="-static"
+else
+ STATIC=
+fi
+AC_SUBST(STATIC)
+
+dnl --------------------------------------------------------------
+dnl Checks for header files.
+dnl --------------------------------------------------------------
+AC_HEADER_STDC
+AC_CHECK_HEADER(unistd.h)
+AC_CHECK_HEADER(string.h)
+
+dnl --------------------------------------------------------------
+dnl Checks for typedefs, structures, and compiler characteristics.
+dnl --------------------------------------------------------------
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+dnl AC_CHECK_TYPES([ptrdiff_t])
AC_C_BIGENDIAN
-AS_CASE([$host],
- [*mingw32* | *cygwin*], [AC_CHECK_FUNCS(gettimeofday)])
+dnl -------------------------------------------------------------
+dnl Check for basic *nix fonction that we may emulate on windows.
+dnl -------------------------------------------------------------
+case $host in
+ *mingw32* | *cygwin*)
+ AC_CHECK_FUNCS(gettimeofday)
+ ;;
+ *)
+ ;;
+esac
dnl ---------------------------------------------
dnl threads
@@ -89,12 +155,67 @@ esac
AC_SUBST(THREAD_LIBS)
AC_SUBST(THREAD_CFLAGS)
-PKG_CHECK_MODULES([DVDREAD], [dvdread])
+dnl ---------------------------------------------
+dnl dynamic linker
+dnl ---------------------------------------------
+case $host in
+ *mingw32*)
+ CFLAGS="-idirafter \$(top_srcdir)/msvc/include $CFLAGS"
+ LDFLAGS="-no-undefined $LDFLAGS"
+ ;;
+ *cygwin*)
+ LDFLAGS="-no-undefined $LDFLAGS"
+ ;;
+ *os2*)
+ LDFLAGS="-no-undefined -Zbin-files $LDFLAGS"
+ ;;
+ *)
+ AC_CHECK_LIB(c, dlopen,
+ DYNAMIC_LD_LIBS="",
+ AC_CHECK_LIB(dl, dlopen,
+ DYNAMIC_LD_LIBS="-ldl",
+ AC_MSG_ERROR(dynamic linker needed)))
+ AC_SUBST(DYNAMIC_LD_LIBS)
+ ;;
+esac
+
+dnl ---------------------------------------------
+dnl libdvdread
+dnl ---------------------------------------------
+AC_ARG_WITH([dvdread-config],
+ [AS_HELP_STRING([--with-dvdread-config=PROG],
+ [dvdread-config program to use @<:@default=from PATH@:>@])],
+ [DVDREAD_CONFIG="$withval"],
+ [DVDREAD_CONFIG=""])
+
+dnl by default, search pkg-config, and then fall back to dvdread-config
+DVDREAD_PKG_CONFIG="no"
+if test "x$DVDREAD_CONFIG" = "x"; then
+ PKG_CHECK_MODULES([DVDREAD], [dvdread],
+ [DVDREAD_PKG_CONFIG="yes"],
+ [dnl User didn't specify program, search PATH
+ AC_PATH_PROG([DVDREAD_CONFIG], [dvdread-config], [no])
+ test "x$DVDREAD_CONFIG" = xno && \
+ AC_MSG_ERROR([dvdread-config required to link with libdvdread])
+ ])
+fi
+if test "x$DVDREAD_PKG_CONFIG" != "xyes"; then
+ DVDREAD_CFLAGS=`$DVDREAD_CONFIG --cflags` || \
+ AC_MSG_ERROR([Could not get libdvdread CFLAGS from $DVDREAD_CONFIG])
+ DVDREAD_LIBS=`$DVDREAD_CONFIG --libs` || \
+ AC_MSG_ERROR([Could not get libdvdread LIBS from $DVDREAD_CONFIG])
+fi
+AC_SUBST([DVDREAD_CFLAGS])
+AC_SUBST([DVDREAD_LIBS])
dnl ---------------------------------------------
-dnl Check for bitfield compiler flag
+dnl cflags
dnl ---------------------------------------------
-AX_CHECK_COMPILE_FLAG([-mno-ms-bitfields], [CFLAGS="-mno-ms-bitfields $CFLAGS"])
+dnl Common cflags for all platforms
+CFLAGS="-O3 -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE $CFLAGS"
+DEBUG_CFLAGS="-g -DDEBUG $CFLAGS"
+
+AC_SUBST(DEBUG_CFLAGS)
dnl ---------------------------------------------
dnl Check for doxygen (dynamic documentation generator)
@@ -102,11 +223,25 @@ dnl ---------------------------------------------
AC_CHECK_PROG(DOXYGEN, doxygen, doxygen, no)
dnl ---------------------------------------------
+dnl Some include paths ( !!! DO NOT REMOVE !!! )
+dnl ---------------------------------------------
+INCLUDES='-I$(top_srcdir) $(DVDNAV_CFLAGS)'
+AC_SUBST(INCLUDES)
+
+dnl ---------------------------------------------
dnl Output configuration files
dnl ---------------------------------------------
AC_OUTPUT([
Makefile
+src/Makefile
+src/vm/Makefile
+misc/Makefile
+misc/dvdnav-config
misc/dvdnav.pc
misc/dvdnavmini.pc
misc/libdvdnav.spec
+misc/relchk.sh
+m4/Makefile
+doc/Makefile
+examples/Makefile
])
diff --git a/configure2 b/configure2
new file mode 100755
index 0000000..0f2d476
--- /dev/null
+++ b/configure2
@@ -0,0 +1,182 @@
+#!/bin/sh
+
+dvdnav_sh_version=4.2.1
+dvdnav_sh_major=`echo $dvdnav_sh_version | awk -F. '{print $1}'`
+
+cc=gcc
+make=make
+: ${PKG_CONFIG:=pkg-config}
+
+# find source path
+source_path="`dirname \"$0\"`"
+source_path_used="yes"
+if test -z "$source_path" -o "$source_path" = "." ; then
+ source_path="`pwd`"
+ source_path_used="no"
+else
+ source_path="`cd \"$source_path\" && pwd`"
+ echo "$source_path" | grep -q '[[:blank:]]' &&
+ die "Out of tree builds are impossible with whitespace in source path."
+fi
+
+show_help(){
+ echo "Usage: configure [options]"
+ echo "Options: [defaults in brackets after descriptions]"
+ echo
+ echo "Standard options:"
+ echo " --help print this message"
+ echo " --prefix=PREFIX install in PREFIX [$PREFIX]"
+ echo " --libdir=DIR install libs in DIR [PREFIX/lib]"
+ echo " --shlibdir=DIR install shared libs in DIR [PREFIX/lib]"
+ echo " --incdir=DIR install includes in DIR [PREFIX/include/dvdnav]"
+ echo " --enable-static build static libraries [default=yes]"
+ echo " --disable-static do not build static libraries [default=no]"
+ echo " --enable-shared build shared libraries [default=no]"
+ echo " --disable-shared do not build shared libraries [default=yes]"
+ echo " --enable-debug compile with debug symbols [default=yes]"
+ echo " --disable-debug compile without debug symbols [default=no]"
+ echo " --with-dvdread=PATH compile libdvdnav with an external libdvdread"
+ echo "Advanced options (experts only):"
+ echo " --cc=CC use C compiler CC [$cc]"
+ echo " --make=MAKE use specified make [$make]"
+ echo " --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS"
+ echo " --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS"
+ echo "Developer options:"
+ echo " --disable-strip disable stripping of executables and shared libraries"
+ echo " --disable-opts disable compiler optimizations"
+ echo "Environment variables:"
+ echo " PKG_CONFIG use specified pkg-config [$PKG_CONFIG]"
+ exit 1
+}
+
+SHARED=yes
+STATIC=yes
+DVDREAD_CONFIG=""
+DVDREAD_PKG_CONFIG="${PKG_CONFIG} dvdread"
+PREFIX=/usr/local/
+INSTALLSTRIP=-s
+USEDEBUG=-g
+optimizations="-O3"
+threadlib="-lpthread"
+
+for opt do
+ optval=`echo $opt | cut -d '=' -f 2-`
+ case "$opt" in
+ --enable-shared) SHARED=yes
+ ;;
+ --disable-shared) SHARED=no
+ ;;
+ --enable-static) STATIC=yes
+ ;;
+ --disable-static) STATIC=no
+ ;;
+ --with-dvdread-config=*) DVDREAD_CONFIG="$optval"
+ ;;
+ --prefix=*) PREFIX="$optval"
+ ;;
+ --libdir=*) libdir="$optval"
+ ;;
+ --shlibdir=*) shlibdir="$optval"
+ ;;
+ --incdir=*) incdir="$optval"
+ ;;
+ --cc=*) cc="$optval"
+ ;;
+ --make=*) make="$optval"
+ ;;
+ --extra-cflags=*) cflags="$cflags $optval"
+ ;;
+ --extra-ldflags=*) ldflags="$ldflags $optval"
+ ;;
+ --disable-strip) INSTALLSTRIP=
+ ;;
+ --disable-opts) optimizations=""
+ ;;
+ --disable-debug) USEDEBUG=""
+ ;;
+ --enable-debug) USEDEBUG="-g"
+ ;;
+ --help) show_help
+ ;;
+ esac
+done
+
+PREFIX=`cd $PREFIX && pwd`
+
+test -z "$libdir" && libdir=$PREFIX/lib
+test -z "$shlibdir" && shlibdir=$PREFIX/lib
+test -z "$incdir" && incdir=$PREFIX/include/dvdnav
+
+dvdread=no
+if test -z "$DVDREAD_CONFIG" ; then
+ DVDREAD_CONFIG=${DVDREAD_PKG_CONFIG}
+ $DVDREAD_CONFIG --exists >> /dev/null 2>&1 && dvdread=yes
+fi
+if test "$dvdread" != "yes" ; then
+ DVDREAD_CONFIG=dvdread-config
+ $DVDREAD_CONFIG --prefix >> /dev/null 2>&1 && dvdread=yes
+fi
+if test "$dvdread" != "yes" ; then
+ echo "$DVDREAD_CONFIG returned an error. Can't proceed"
+ exit 1
+fi
+dvdread_cflags=`$DVDREAD_CONFIG --cflags`
+dvdread_libs=`$DVDREAD_CONFIG --libs`
+
+targetos=`uname -s`
+case $targetos in
+ Darwin)
+ SHLDFLAGS="-dynamiclib -Wl,-single_module -Wl,-read_only_relocs,suppress"
+ ;;
+ *)
+ SHLDFLAGS="-shared"
+ ;;
+esac
+
+cat > config.mak << EOF
+# Automatically generated by configure, do not edit
+PREFIX=$PREFIX
+libdir=$libdir
+shlibdir=$shlibdir
+incdir=$incdir
+THREADLIB=$threadlib
+BUILD_SHARED=$SHARED
+BUILD_STATIC=$STATIC
+SHLIB_VERSION=$dvdnav_sh_version
+SHLIB_MAJOR=$dvdnav_sh_major
+CC=$cc
+MAKE=$make
+CFLAGS=$optimizations $cflags
+LDFLAGS=$ldflags
+SHLDFLAGS=$SHLDFLAGS
+INSTALLSTRIP=$INSTALLSTRIP
+USEDEBUG=$USEDEBUG
+DVDREAD_CFLAGS=$dvdread_cflags
+DVDREAD_LIBS=$dvdread_libs
+
+SRC_PATH="$source_path"
+SRC_PATH_BARE=$source_path
+
+EOF
+
+cat > config.h << EOF
+/* Automatically generated by configure, do not edit */
+#include "version.h"
+EOF
+
+# build tree in object directory if source path is different from current one
+if test "$source_path_used" != "no"; then
+ FILES="\
+ Makefile \
+ misc \
+ "
+ for f in $FILES ; do
+ ln -sf "$source_path/$f" $f
+ done
+fi
+
+[ -d obj ] || mkdir -p obj
+
+echo
+echo "Done, type 'make install' to build and install"
+
diff --git a/debian/changelog b/debian/changelog
index e5cf7a9..7af2092 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,3 @@
-libdvdnav (4.2.1-3) unstable; urgency=low
-
- * Reintroduce dvdnav_dup and dvdnav_dup_free API calls (Closes: #735760)
-
- -- Balint Reczey <balint at balintreczey.hu> Thu, 13 Feb 2014 17:26:10 +0100
-
libdvdnav (4.2.1-2) unstable; urgency=medium
* debian/: documentation package added (Closes: #735108)
diff --git a/debian/patches/0003-Adds-a-function-to-create-a-dpu-of-a-dvdnav-handle.patch b/debian/patches/0003-Adds-a-function-to-create-a-dpu-of-a-dvdnav-handle.patch
deleted file mode 100644
index 642955e..0000000
--- a/debian/patches/0003-Adds-a-function-to-create-a-dpu-of-a-dvdnav-handle.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 5c7ddc5ca6cde54743b3ce019cb757022e47c71e Mon Sep 17 00:00:00 2001
-From: Erik Hovland <erik at hovland.org>
-Date: Mon, 21 May 2012 16:41:55 -0700
-Subject: [PATCH] Adds a function to create a dpu of a dvdnav handle
-
-This adds a function to create a duplicate of a dvdnav handle and it's
-state. This allows you to recursively move through the handle. HandBrake
-uses these functions to do recursive automated search of the menus for
-something that looks like the main feature.
----
- src/dvdnav.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++
- src/dvdnav/dvdnav.h | 3 +++
- 2 files changed, 64 insertions(+)
-
-diff --git a/src/dvdnav.c b/src/dvdnav.c
-index 5859d6e..5349ecd 100644
---- a/src/dvdnav.c
-+++ b/src/dvdnav.c
-@@ -71,6 +71,67 @@ static dvdnav_status_t dvdnav_clear(dvdnav_t * this) {
- return DVDNAV_STATUS_OK;
- }
-
-+dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src) {
-+ dvdnav_t *this;
-+
-+ (*dest) = NULL;
-+ this = (dvdnav_t*)malloc(sizeof(dvdnav_t));
-+ if(!this)
-+ return DVDNAV_STATUS_ERR;
-+
-+ memcpy(this, src, sizeof(dvdnav_t));
-+ this->file = NULL;
-+
-+ pthread_mutex_init(&this->vm_lock, NULL);
-+
-+ this->vm = vm_new_copy(src->vm);
-+ if(!this->vm) {
-+ printerr("Error initialising the DVD VM.");
-+ pthread_mutex_destroy(&this->vm_lock);
-+ free(this);
-+ return DVDNAV_STATUS_ERR;
-+ }
-+
-+ /* Start the read-ahead cache. */
-+ this->cache = dvdnav_read_cache_new(this);
-+
-+ (*dest) = this;
-+ return DVDNAV_STATUS_OK;
-+}
-+
-+dvdnav_status_t dvdnav_free_dup(dvdnav_t *this) {
-+
-+#ifdef LOG_DEBUG
-+ fprintf(MSG_OUT, "libdvdnav: free_dup:called\n");
-+#endif
-+
-+ if (this->file) {
-+ pthread_mutex_lock(&this->vm_lock);
-+ DVDCloseFile(this->file);
-+#ifdef LOG_DEBUG
-+ fprintf(MSG_OUT, "libdvdnav: close:file closing\n");
-+#endif
-+ this->file = NULL;
-+ pthread_mutex_unlock(&this->vm_lock);
-+ }
-+
-+ /* Free the VM */
-+ if(this->vm)
-+ vm_free_copy(this->vm);
-+
-+ pthread_mutex_destroy(&this->vm_lock);
-+
-+ /* We leave the final freeing of the entire structure to the cache,
-+ * because we don't know, if there are still buffers out in the wild,
-+ * that must return first. */
-+ if(this->cache)
-+ dvdnav_read_cache_free(this->cache);
-+ else
-+ free(this);
-+
-+ return DVDNAV_STATUS_OK;
-+}
-+
- dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
- dvdnav_t *this;
- struct timeval time;
-diff --git a/src/dvdnav/dvdnav.h b/src/dvdnav/dvdnav.h
-index 3e1b91a..ca78099 100644
---- a/src/dvdnav/dvdnav.h
-+++ b/src/dvdnav/dvdnav.h
-@@ -89,6 +89,9 @@ typedef int32_t dvdnav_status_t;
- */
- dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path);
-
-+dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src);
-+dvdnav_status_t dvdnav_free_dup(dvdnav_t *this);
-+
- /*
- * Closes a dvdnav_t previously opened with dvdnav_open(), freeing any
- * memory associated with it.
---
-1.7.10.4
diff --git a/debian/patches/series b/debian/patches/series
index eb0b36c..ea00e44 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,2 @@
0001-inttypes.patch
0002-hurd.patch
-0003-Adds-a-function-to-create-a-dpu-of-a-dvdnav-handle.patch
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..205f055
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,8 @@
+include $(top_srcdir)/misc/Makefile.common
+
+EXTRA_DIST = doxy.conf mainpage.cpp tutorial.cpp dvd_structures library_layout
+
+docs: doxy.conf
+ @if test x"$(DOXYGEN)" != "xno"; then \
+ $(DOXYGEN) doxy.conf > /dev/null 2> /dev/null; \
+ fi
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..c4540f5
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,13 @@
+include $(top_srcdir)/misc/Makefile.common
+
+AM_CPPFLAGS = -DDVDNAV_COMPILE $(DVDREAD_CFLAGS) -I$(top_srcdir)/src
+
+DVDNAV_LIB = $(top_builddir)/src/libdvdnav.la
+
+noinst_PROGRAMS = menus
+
+menus_SOURCES = menus.c
+menus_LDADD = $(DVDNAV_LIB) $(DVDREAD_LIBS)
+
+$(DVDNAV_LIB):
+ @cd $(top_builddir)/src/ && $(MAKE) libdvdnav.la
diff --git a/m4/Makefile.am b/m4/Makefile.am
new file mode 100644
index 0000000..7f444b1
--- /dev/null
+++ b/m4/Makefile.am
@@ -0,0 +1,7 @@
+include $(top_srcdir)/misc/Makefile.common
+
+EXTRA_DIST = dvdnav.m4
+
+m4datadir = $(datadir)/aclocal
+
+m4data_DATA = dvdnav.m4
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
deleted file mode 100644
index c3a8d69..0000000
--- a/m4/ax_check_compile_flag.m4
+++ /dev/null
@@ -1,72 +0,0 @@
-# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
-#
-# DESCRIPTION
-#
-# Check whether the given FLAG works with the current language's compiler
-# or gives an error. (Warnings, however, are ignored)
-#
-# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
-# success/failure.
-#
-# If EXTRA-FLAGS is defined, it is added to the current language's default
-# flags (e.g. CFLAGS) when the check is done. The check is thus made with
-# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
-# force the compiler to issue an error when a bad flag is given.
-#
-# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
-# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
-#
-# LICENSE
-#
-# Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
-# Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.com>
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
-
-#serial 2
-
-AC_DEFUN([AX_CHECK_COMPILE_FLAG],
-[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
-AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
-AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
- ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
- _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
- [AS_VAR_SET(CACHEVAR,[yes])],
- [AS_VAR_SET(CACHEVAR,[no])])
- _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
-AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
- [m4_default([$2], :)],
- [m4_default([$3], :)])
-AS_VAR_POPDEF([CACHEVAR])dnl
-])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/dvdnav.m4 b/m4/dvdnav.m4
new file mode 100644
index 0000000..44d8991
--- /dev/null
+++ b/m4/dvdnav.m4
@@ -0,0 +1,181 @@
+dnl Configure paths for DVDNAV
+dnl
+dnl Copyright (C) 2001 Daniel Caujolle-Bert <segfault at club-internet.fr>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+dnl
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a configuration
+dnl script generated by Autoconf, you may include it under the same
+dnl distribution terms that you use for the rest of that program.
+dnl
+
+dnl AM_PATH_DVDNAV([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for DVDNAV, and define DVDNAV_CFLAGS and DVDNAV_LIBS
+dnl
+AC_DEFUN([AM_PATH_DVDNAV],
+[dnl
+dnl Get the cflags and libraries from the dvdnav-config script
+dnl
+AC_ARG_WITH(dvdnav-prefix,
+ AC_HELP_STRING([--with-dvdnav-prefix=DIR], [prefix where DVDNAV is installed (optional)]),
+ dvdnav_config_prefix="$withval", dvdnav_config_prefix="")
+AC_ARG_WITH(dvdnav-exec-prefix,
+ AC_HELP_STRING([--with-dvdnav-exec-prefix=DIR], [exec prefix where DVDNAV is installed (optional)]),
+ dvdnav_config_exec_prefix="$withval", dvdnav_config_exec_prefix="")
+AC_ARG_ENABLE(dvdnavtest,
+ AC_HELP_STRING([--disable-dvdnavtest], [do not try to compile and run a test DVDNAV program]),
+ enable_dvdnavtest=$enableval, enable_dvdnavtest=yes)
+
+ if test x$dvdnav_config_exec_prefix != x ; then
+ dvdnav_config_args="$dvdnav_config_args --exec-prefix=$dvdnav_config_exec_prefix"
+ if test x${DVDNAV_CONFIG+set} != xset ; then
+ DVDNAV_CONFIG=$dvdnav_config_exec_prefix/bin/dvdnav-config
+ fi
+ fi
+ if test x$dvdnav_config_prefix != x ; then
+ dvdnav_config_args="$dvdnav_config_args --prefix=$dvdnav_config_prefix"
+ if test x${DVDNAV_CONFIG+set} != xset ; then
+ DVDNAV_CONFIG=$dvdnav_config_prefix/bin/dvdnav-config
+ fi
+ fi
+
+ min_dvdnav_version=ifelse([$1], ,0.0.0,$1)
+ if test "x$enable_dvdnavtest" != "xyes" ; then
+ AC_MSG_CHECKING([for DVDNAV-LIB version >= $min_dvdnav_version])
+ else
+ AC_PATH_PROG(DVDNAV_CONFIG, dvdnav-config, no)
+ AC_MSG_CHECKING([for DVDNAV-LIB version >= $min_dvdnav_version])
+ no_dvdnav=""
+ if test "$DVDNAV_CONFIG" = "no" ; then
+ no_dvdnav=yes
+ else
+ DVDNAV_CFLAGS=`$DVDNAV_CONFIG $dvdnav_config_args --cflags`
+ DVDNAV_LIBS=`$DVDNAV_CONFIG $dvdnav_config_args --libs`
+ dvdnav_config_major_version=`$DVDNAV_CONFIG $dvdnav_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ dvdnav_config_minor_version=`$DVDNAV_CONFIG $dvdnav_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ dvdnav_config_sub_version=`$DVDNAV_CONFIG $dvdnav_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+ dnl if test "x$enable_dvdnavtest" = "xyes" ; then
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $DVDNAV_CFLAGS"
+ LIBS="$DVDNAV_LIBS $LIBS"
+dnl
+dnl Now check if the installed DVDNAV is sufficiently new. (Also sanity
+dnl checks the results of dvdnav-config to some extent
+dnl
+ AC_LANG_SAVE()
+ AC_LANG_C()
+ rm -f conf.dvdnavtest
+ AC_TRY_RUN([
+#include <dvdnav.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main ()
+{
+ int major, minor, sub;
+ char *tmp_version;
+
+ system ("touch conf.dvdnavtest");
+
+ /* HP/UX 9 (%@#!) writes to sscanf strings */
+ tmp_version = (char *) strdup("$min_dvdnav_version");
+ if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &sub) != 3) {
+ printf("%s, bad version string\n", "$min_dvdnav_version");
+ exit(1);
+ }
+
+ if (($dvdnav_config_major_version > major) ||
+ (($dvdnav_config_major_version == major) && ($dvdnav_config_minor_version > minor)) ||
+ (($dvdnav_config_major_version == major) && ($dvdnav_config_minor_version == minor) && ($dvdnav_config_sub_version >= sub))) {
+ return 0;
+ } else {
+ printf("\n*** An old version of libdvdnav (%d.%d.%d) was found.\n",
+ $dvdnav_config_major_version, $dvdnav_config_minor_version, $dvdnav_config_sub_version);
+ printf("*** You need a version of libdvdnav newer than %d.%d.%d. The latest version of\n",
+ major, minor, sub);
+ printf("*** libdvdnav is always available from:\n");
+ printf("*** http://dvd.sourceforge.net\n");
+ printf("***\n");
+ printf("*** If you have already installed a sufficiently new version, this error\n");
+ printf("*** probably means that the wrong copy of the dvdnav-config shell script is\n");
+ printf("*** being found. The easiest way to fix this is to remove the old version\n");
+ printf("*** of libdvdnav, but you can also set the DVDNAV_CONFIG environment to point to the\n");
+ printf("*** correct copy of dvdnav-config. (In this case, you will have to\n");
+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+ printf("*** so that the correct libraries are found at run-time))\n");
+ }
+ return 1;
+}
+],, no_dvdnav=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ if test "x$no_dvdnav" = x ; then
+ AC_MSG_RESULT(yes)
+ ifelse([$2], , :, [$2])
+ else
+ AC_MSG_RESULT(no)
+ if test "$DVDNAV_CONFIG" = "no" ; then
+ echo "*** The dvdnav-config script installed by DVDNAV could not be found"
+ echo "*** If DVDNAV was installed in PREFIX, make sure PREFIX/bin is in"
+ echo "*** your path, or set the DVDNAV_CONFIG environment variable to the"
+ echo "*** full path to dvdnav-config."
+ else
+ if test -f conf.dvdnavtest ; then
+ :
+ else
+ echo "*** Could not run DVDNAV test program, checking why..."
+ CFLAGS="$CFLAGS $DVDNAV_CFLAGS"
+ LIBS="$LIBS $DVDNAV_LIBS"
+ AC_TRY_LINK([
+#include <dvdnav.h>
+#include <stdio.h>
+], [ return 0; ],
+ [ echo "*** The test program compiled, but did not run. This usually means"
+ echo "*** that the run-time linker is not finding DVDNAV or finding the wrong"
+ echo "*** version of DVDNAV. If it is not finding DVDNAV, you'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+ echo "***"],
+ [ echo "*** The test program failed to compile or link. See the file config.log for the"
+ echo "*** exact error that occured. This usually means DVDNAV was incorrectly installed"
+ echo "*** or that you have moved DVDNAV since it was installed. In the latter case, you"
+ echo "*** may want to edit the dvdnav-config script: $DVDNAV_CONFIG" ])
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ DVDNAV_CFLAGS=""
+ DVDNAV_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(DVDNAV_CFLAGS)
+ AC_SUBST(DVDNAV_LIBS)
+ AC_LANG_RESTORE()
+ rm -f conf.dvdnavtest
+])
diff --git a/misc/Makefile.am b/misc/Makefile.am
new file mode 100644
index 0000000..8672630
--- /dev/null
+++ b/misc/Makefile.am
@@ -0,0 +1,8 @@
+include $(top_srcdir)/misc/Makefile.common
+
+EXTRA_DIST = dvdnav-config.in libdvdnav.spec.in libdvdnav.spec Makefile.common relchk.sh relchk.sh.in
+
+bin_SCRIPTS = dvdnav-config
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = dvdnav.pc dvdnavmini.pc
diff --git a/misc/dvdnav-config.in b/misc/dvdnav-config.in
new file mode 100644
index 0000000..194f4a1
--- /dev/null
+++ b/misc/dvdnav-config.in
@@ -0,0 +1,88 @@
+#!/bin/sh
+#
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+exec_prefix_set=no
+
+usage()
+{
+ cat <<EOF
+Usage: dvdnav-config [OPTIONS] [LIBRARIES]
+Options:
+ [--prefix[=DIR]]
+ [--exec-prefix[=DIR]]
+ [--version]
+ [--libs]
+ [--minilibs]
+ [--cflags]
+EOF
+ exit $1
+}
+
+if test $# -eq 0; then
+ usage 1 1>&2
+fi
+
+while test $# -gt 0; do
+ case "$1" in
+ -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ case $1 in
+ --prefix=*)
+ prefix=$optarg
+ if test $exec_prefix_set = no ; then
+ exec_prefix=$optarg
+ fi
+ ;;
+ --prefix)
+ echo_prefix=yes
+ ;;
+ --exec-prefix=*)
+ exec_prefix=$optarg
+ exec_prefix_set=yes
+ ;;
+ --exec-prefix)
+ echo_exec_prefix=yes
+ ;;
+ --version)
+ echo @DVDNAV_MAJOR at .@DVDNAV_MINOR at .@DVDNAV_SUB@
+ ;;
+ --cflags)
+ echo_cflags=yes
+ ;;
+ --libs)
+ echo_libs=yes
+ ;;
+ --minilibs)
+ echo_minilibs=yes
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+
+if test "$echo_prefix" = "yes"; then
+ echo $prefix
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+ echo $exec_prefix
+fi
+
+if test "$echo_cflags" = "yes"; then
+ echo -I at includedir@ -I at includedir@/libdvdread @THREAD_CFLAGS@
+fi
+
+if test "$echo_libs" = "yes"; then
+ echo -L at libdir@ -ldvdnav -ldvdread @THREAD_LIBS@
+fi
+
+if test "$echo_minilibs" = "yes"; then
+ echo -L at libdir@ -ldvdnavmini @THREAD_LIBS@
+fi
diff --git a/misc/dvdnav-config2.sh b/misc/dvdnav-config2.sh
new file mode 100644
index 0000000..8dfcd32
--- /dev/null
+++ b/misc/dvdnav-config2.sh
@@ -0,0 +1,72 @@
+ extracflags="-DDVDNAV_USES_EXTERNAL_DVDREAD"
+
+usage()
+{
+ cat <<EOF
+Usage: dvdnav-config [OPTIONS] [LIBRARIES]
+Options:
+ [--prefix[=DIR]]
+ [--version]
+ [--libs]
+ [--cflags]
+ [--minilibs]
+ [--minicflags]
+EOF
+ exit $1
+}
+
+if test $# -eq 0; then
+ usage 1 1>&2
+fi
+
+while test $# -gt 0; do
+ case "$1" in
+ -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ case $1 in
+ --prefix)
+ echo_prefix=yes
+ ;;
+ --version)
+ echo $version
+ ;;
+ --cflags)
+ echo_cflags=yes
+ ;;
+ --minicflags)
+ echo_minicflags=yes
+ ;;
+ --libs)
+ echo_libs=yes
+ ;;
+ --minilibs)
+ echo_minilibs=yes
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+
+if test "$echo_prefix" = "yes"; then
+ echo $prefix
+fi
+
+if test "$echo_cflags" = "yes"; then
+ echo -I$prefix/include $dvdread_cflags $extracflags $threadcflags
+fi
+
+if test "$echo_minicflags" = "yes"; then
+ echo -I$prefix/include -I$prefix/include/dvdnav $extracflags $threadcflags
+fi
+
+if test "$echo_libs" = "yes"; then
+ echo -L$libdir -ldvdnav $dvdread_libs $threadlib
+fi
+
+if test "$echo_minilibs" = "yes"; then
+ echo -L$libdir -ldvdnavmini $threadlib
+fi
diff --git a/misc/dvdnavmini.pc b/misc/dvdnavmini.pc
deleted file mode 100644
index 1cd0106..0000000
--- a/misc/dvdnavmini.pc
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=/usr/local
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib
-includedir=${prefix}/include
-
-Name: libdvdnavmini
-Description: DVD Navigation mini library
-Version: 4.2.0
-
-Requires: dvdnav
diff --git a/misc/dvdnavmini.pc.in b/misc/dvdnavmini.pc.in
index 7638701..52945b3 100644
--- a/misc/dvdnavmini.pc.in
+++ b/misc/dvdnavmini.pc.in
@@ -7,4 +7,5 @@ Name: libdvdnavmini
Description: DVD Navigation mini library
Version: @VERSION@
-Requires: dvdnav
+Cflags: -I${includedir} @DVDREAD_CFLAGS@ @THREAD_CFLAGS@
+Libs: -L${libdir} -ldvdnav @THREAD_LIBS@
diff --git a/misc/relchk.sh.in b/misc/relchk.sh.in
new file mode 100755
index 0000000..98a31fc
--- /dev/null
+++ b/misc/relchk.sh.in
@@ -0,0 +1,66 @@
+#!/bin/sh
+##
+## A simple compare directory content utility.
+##
+
+topdir="`pwd`"
+distdir="@PACKAGE_NAME at -@PACKAGE_VERSION@"
+log="$topdir/dist-log"
+logerror="$topdir/dist-errors"
+
+getdir() {
+ if test -r .relignore; then
+ filelist=`ls | grep -Fxvf .relignore`
+ else
+ filelist=`ls`
+ fi
+
+ for file in $filelist; do
+
+ if test -d $file -a $file != "CVS" -a $file != $distdir; then
+ (cd $file && getdir) || (cd ..)
+ else
+ if test ! -d $file -a \
+ $file != $log -a \
+ $file != $logerror -a \
+ $file != "$distdir.tar.gz"; then
+
+ orifile=`pwd`/$file
+
+ distfile=$topdir/$distdir${orifile##*$topdir}
+
+ echo -e "check:\t$orifile\nand\t$distfile" >> $log
+
+ if test ! -e $distfile; then
+ missingfile=${orifile##$topdir}
+ echo "${missingfile#/} is missing in tarball" >> $logerror
+ fi
+
+ fi
+ fi
+
+ done
+}
+
+main() {
+ rm -f $log $logerror
+
+ make config.status && make dist && mv $distdir.tar.gz $distdir.tmp.tar.gz && \
+ cp config.status config.tmp.status && make clean && make distclean && \
+ mv $distdir.tmp.tar.gz $distdir.tar.gz && mv config.tmp.status config.status && \
+ tar -xzf $distdir.tar.gz
+
+ echo "Check is running, be patient..."
+ getdir
+
+ rm -rf $distdir
+ rm -f $distdir.tar.gz
+ ./config.status --recheck
+ ./config.status
+
+ echo " * Log is ${log##*/}"
+ echo " * Error log is ${logerror##*/}"
+
+}
+
+main
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..c7502a3
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,34 @@
+include $(top_srcdir)/misc/Makefile.common
+
+SUBDIRS = vm
+
+includedir = ${prefix}/include/dvdnav
+
+AM_CPPFLAGS = $(THREAD_CFLAGS) $(DVDREAD_CFLAGS) \
+ -I$(top_srcdir)/src/vm
+
+EXTRA_DIST = README.MAP FELLOWSHIP.map
+
+lib_LTLIBRARIES = libdvdnav.la libdvdnavmini.la
+
+libdvdnav_la_SOURCES = dvdnav.c \
+ read_cache.c navigation.c highlight.c \
+ searching.c settings.c remap.c \
+ dvdnav_internal.h read_cache.h remap.h
+
+libdvdnav_la_LIBADD = $(THREAD_LIBS) $(DVDREAD_LIBS) \
+ $(top_builddir)/src/vm/libdvdvm.la
+
+libdvdnav_la_LDFLAGS = \
+ -version-info $(DVDNAV_LT_CURRENT):$(DVDNAV_LT_REVISION):$(DVDNAV_LT_AGE) \
+ -export-symbols-regex "(^dvdnav.*|^nav.*|^ifo.*|^DVD.*)"
+# -release $(DVDNAV_MAJOR).$(DVDNAV_MINOR).$(DVDNAV_SUB)
+
+libdvdnavmini_la_SOURCES = $(libdvdnav_la_SOURCES)
+
+libdvdnavmini_la_LIBADD = $(THREAD_LIBS) \
+ $(top_builddir)/src/vm/libdvdvm.la
+
+libdvdnavmini_la_LDFLAGS = $(libdvdnav_la_LDFLAGS)
+
+include_HEADERS = dvdnav/dvdnav.h dvdnav/dvdnav_events.h dvdnav/dvd_types.h
diff --git a/src/dvdnav.c b/src/dvdnav.c
index 4f2a34a..f95032b 100644
--- a/src/dvdnav.c
+++ b/src/dvdnav.c
@@ -71,67 +71,6 @@ static dvdnav_status_t dvdnav_clear(dvdnav_t * this) {
return DVDNAV_STATUS_OK;
}
-dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src) {
- dvdnav_t *this;
-
- (*dest) = NULL;
- this = (dvdnav_t*)malloc(sizeof(dvdnav_t));
- if(!this)
- return DVDNAV_STATUS_ERR;
-
- memcpy(this, src, sizeof(dvdnav_t));
- this->file = NULL;
-
- pthread_mutex_init(&this->vm_lock, NULL);
-
- this->vm = vm_new_copy(src->vm);
- if(!this->vm) {
- printerr("Error initialising the DVD VM.");
- pthread_mutex_destroy(&this->vm_lock);
- free(this);
- return DVDNAV_STATUS_ERR;
- }
-
- /* Start the read-ahead cache. */
- this->cache = dvdnav_read_cache_new(this);
-
- (*dest) = this;
- return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_free_dup(dvdnav_t *this) {
-
-#ifdef LOG_DEBUG
- fprintf(MSG_OUT, "libdvdnav: free_dup:called\n");
-#endif
-
- if (this->file) {
- pthread_mutex_lock(&this->vm_lock);
- DVDCloseFile(this->file);
-#ifdef LOG_DEBUG
- fprintf(MSG_OUT, "libdvdnav: close:file closing\n");
-#endif
- this->file = NULL;
- pthread_mutex_unlock(&this->vm_lock);
- }
-
- /* Free the VM */
- if(this->vm)
- vm_free_copy(this->vm);
-
- pthread_mutex_destroy(&this->vm_lock);
-
- /* We leave the final freeing of the entire structure to the cache,
- * because we don't know, if there are still buffers out in the wild,
- * that must return first. */
- if(this->cache)
- dvdnav_read_cache_free(this->cache);
- else
- free(this);
-
- return DVDNAV_STATUS_OK;
-}
-
dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
dvdnav_t *this;
struct timeval time;
@@ -264,12 +203,12 @@ int64_t dvdnav_convert_time(dvd_time_t *time) {
int64_t result;
int64_t frames;
- result = ((int64_t)(time->hour >> 4 )) * 10 * 60 * 60 * 90000;
- result += ((int64_t)(time->hour & 0x0f)) * 60 * 60 * 90000;
- result += ((int64_t)(time->minute >> 4 )) * 10 * 60 * 90000;
- result += ((int64_t)(time->minute & 0x0f)) * 60 * 90000;
- result += ((int64_t)(time->second >> 4 )) * 10 * 90000;
- result += ((int64_t)(time->second & 0x0f)) * 90000;
+ result = (time->hour >> 4 ) * 10 * 60 * 60 * 90000ull;
+ result += (time->hour & 0x0f) * 60 * 60 * 90000;
+ result += (time->minute >> 4 ) * 10 * 60 * 90000;
+ result += (time->minute & 0x0f) * 60 * 90000;
+ result += (time->second >> 4 ) * 10 * 90000;
+ result += (time->second & 0x0f) * 90000;
frames = ((time->frame_u & 0x30) >> 4) * 10;
frames += ((time->frame_u & 0x0f) ) ;
@@ -403,18 +342,18 @@ static int32_t dvdnav_get_vobu(dvdnav_t *this, dsi_t *nav_dsi, pci_t *nav_pci, d
if((next = nav_pci->nsml_agli.nsml_agl_dsta[angle-1]) != 0) {
if((next & 0x3fffffff) != 0) {
- if(next & 0x80000000)
- vobu->vobu_next = - (int32_t)(next & 0x3fffffff);
- else
- vobu->vobu_next = + (int32_t)(next & 0x3fffffff);
+ if(next & 0x80000000)
+ vobu->vobu_next = - (int32_t)(next & 0x3fffffff);
+ else
+ vobu->vobu_next = + (int32_t)(next & 0x3fffffff);
}
} else if((next = nav_dsi->sml_agli.data[angle-1].address) != 0) {
vobu->vobu_length = nav_dsi->sml_pbi.ilvu_ea;
if((next & 0x80000000) && (next != 0x7fffffff))
- vobu->vobu_next = - (int32_t)(next & 0x3fffffff);
+ vobu->vobu_next = - (int32_t)(next & 0x3fffffff);
else
- vobu->vobu_next = + (int32_t)(next & 0x3fffffff);
+ vobu->vobu_next = + (int32_t)(next & 0x3fffffff);
}
}
@@ -433,7 +372,7 @@ static int32_t dvdnav_get_vobu(dvdnav_t *this, dsi_t *nav_dsi, pci_t *nav_pci, d
*/
dvdnav_status_t dvdnav_get_next_block(dvdnav_t *this, uint8_t *buf,
- int32_t *event, int32_t *len) {
+ int32_t *event, int32_t *len) {
unsigned char *block;
dvdnav_status_t status;
@@ -465,7 +404,7 @@ int64_t dvdnav_get_current_time(dvdnav_t *this) {
}
dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
- int32_t *event, int32_t *len) {
+ int32_t *event, int32_t *len) {
dvd_state_t *state;
int32_t result;
@@ -516,29 +455,29 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
vm_get_angle_info(this->vm, ¤t, &num_angles);
if (num_angles > 1) {
int32_t result, block;
- /* we have to skip the first VOBU when seeking in a multiangle feature,
- * because it might belong to the wrong angle */
- block = this->position_next.cell_start + this->position_next.block;
- result = dvdnav_read_cache_block(this->cache, block, 1, buf);
- if(result <= 0) {
- printerr("Error reading NAV packet.");
- pthread_mutex_unlock(&this->vm_lock);
- return DVDNAV_STATUS_ERR;
- }
- /* Decode nav into pci and dsi. Then get next VOBU info. */
- if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) {
- printerr("Expected NAV packet but none found.");
- pthread_mutex_unlock(&this->vm_lock);
- return DVDNAV_STATUS_ERR;
- }
- dvdnav_get_vobu(this, &this->dsi, &this->pci, &this->vobu);
- /* skip to next, if there is a next */
- if (this->vobu.vobu_next != SRI_END_OF_CELL) {
- this->vobu.vobu_start += this->vobu.vobu_next;
- this->vobu.vobu_next = 0;
- }
- /* update VM state */
- this->vm->state.blockN = this->vobu.vobu_start - this->position_next.cell_start;
+ /* we have to skip the first VOBU when seeking in a multiangle feature,
+ * because it might belong to the wrong angle */
+ block = this->position_next.cell_start + this->position_next.block;
+ result = dvdnav_read_cache_block(this->cache, block, 1, buf);
+ if(result <= 0) {
+ printerr("Error reading NAV packet.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+ /* Decode nav into pci and dsi. Then get next VOBU info. */
+ if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) {
+ printerr("Expected NAV packet but none found.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+ dvdnav_get_vobu(this, &this->dsi, &this->pci, &this->vobu);
+ /* skip to next, if there is a next */
+ if (this->vobu.vobu_next != SRI_END_OF_CELL) {
+ this->vobu.vobu_start += this->vobu.vobu_next;
+ this->vobu.vobu_next = 0;
+ }
+ /* update VM state */
+ this->vm->state.blockN = this->vobu.vobu_start - this->position_next.cell_start;
}
}
this->position_current.hop_channel = this->position_next.hop_channel;
@@ -580,10 +519,8 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
return DVDNAV_STATUS_OK;
}
- /* Check to see if we need to change the currently opened VOB or open
- * a new one because we don't currently have an opened VOB. */
- if((this->file == NULL) ||
- (this->position_current.vts != this->position_next.vts) ||
+ /* Check to see if we need to change the currently opened VOB */
+ if((this->position_current.vts != this->position_next.vts) ||
(this->position_current.domain != this->position_next.domain)) {
dvd_read_domain_t domain;
int32_t vtsN;
@@ -599,16 +536,16 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
/* Use the DOMAIN to find whether to open menu or title VOBs */
switch(this->position_next.domain) {
- case DVD_DOMAIN_FirstPlay:
- case DVD_DOMAIN_VMGM:
+ case FP_DOMAIN:
+ case VMGM_DOMAIN:
domain = DVD_READ_MENU_VOBS;
vtsN = 0;
break;
- case DVD_DOMAIN_VTSMenu:
+ case VTSM_DOMAIN:
domain = DVD_READ_MENU_VOBS;
vtsN = this->position_next.vts;
break;
- case DVD_DOMAIN_VTSTitle:
+ case VTS_DOMAIN:
domain = DVD_READ_TITLE_VOBS;
vtsN = this->position_next.vts;
break;
@@ -719,7 +656,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
fprintf(MSG_OUT, "libdvdnav: SPU_CLUT_CHANGE\n");
#endif
(*len) = 16 * sizeof(uint32_t);
- memcpy(*buf, state->pgc->palette, sizeof(state->pgc->palette));
+ memcpy(*buf, &(state->pgc->palette), 16 * sizeof(uint32_t));
this->spu_clut_changed = 0;
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
@@ -795,15 +732,16 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
/* we are about to leave a cell, so a lot of state changes could occur;
* under certain conditions, the application should get in sync with us before this,
* otherwise it might show stills or menus too shortly */
- if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip)
+ if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip) {
this->sync_wait = 1;
-
- if(!this->position_current.still || this->skip_still ) {
- /* no active cell still -> get us to the next cell */
- vm_get_next_cell(this->vm);
- this->position_current.still = 0; /* still gets activated at end of cell */
- this->skip_still = 0;
- this->sync_wait_skip = 0;
+ } else {
+ if( this->position_current.still == 0 || this->skip_still ) {
+ /* no active cell still -> get us to the next cell */
+ vm_get_next_cell(this->vm);
+ this->position_current.still = 0; /* still gets activated at end of cell */
+ this->skip_still = 0;
+ this->sync_wait_skip = 0;
+ }
}
/* handle related state changes in next iteration */
(*event) = DVDNAV_NOP;
@@ -972,20 +910,20 @@ uint16_t dvdnav_audio_stream_format(dvdnav_t *this, uint8_t stream) {
switch(attr.audio_format) {
case 0:
- format = DVD_AUDIO_FORMAT_AC3;
+ format = DVDNAV_FORMAT_AC3;
break;
case 2: /* MPEG-1 or MPEG-2 without extension bitstream. */
case 3: /* MPEG-2 with extension bitstream. */
- format = DVD_AUDIO_FORMAT_MPEG2_EXT;
+ format = DVDNAV_FORMAT_MPEGAUDIO;
break;
case 4:
- format = DVD_AUDIO_FORMAT_LPCM;
+ format = DVDNAV_FORMAT_LPCM;
break;
case 6:
- format = DVD_AUDIO_FORMAT_DTS;
+ format = DVDNAV_FORMAT_DTS;
break;
case 7:
- format = DVD_AUDIO_FORMAT_SDDS;
+ format = DVDNAV_FORMAT_SDDS;
break;
default:
format = 0xffff;
@@ -1141,7 +1079,7 @@ int8_t dvdnav_get_active_spu_stream(dvdnav_t *this) {
return retval;
}
-static int8_t dvdnav_is_domain(dvdnav_t *this, DVDDomain_t domain) {
+static int8_t dvdnav_is_domain(dvdnav_t *this, domain_t domain) {
int8_t retval;
if(!this->started) {
@@ -1158,19 +1096,19 @@ static int8_t dvdnav_is_domain(dvdnav_t *this, DVDDomain_t domain) {
/* First Play domain. (Menu) */
int8_t dvdnav_is_domain_fp(dvdnav_t *this) {
- return dvdnav_is_domain(this, DVD_DOMAIN_FirstPlay);
+ return dvdnav_is_domain(this, FP_DOMAIN);
}
/* Video management Menu domain. (Menu) */
int8_t dvdnav_is_domain_vmgm(dvdnav_t *this) {
- return dvdnav_is_domain(this, DVD_DOMAIN_VMGM);
+ return dvdnav_is_domain(this, VMGM_DOMAIN);
}
/* Video Title Menu domain (Menu) */
int8_t dvdnav_is_domain_vtsm(dvdnav_t *this) {
- return dvdnav_is_domain(this, DVD_DOMAIN_VTSMenu);
+ return dvdnav_is_domain(this, VTSM_DOMAIN);
}
/* Video Title domain (playing movie). */
int8_t dvdnav_is_domain_vts(dvdnav_t *this) {
- return dvdnav_is_domain(this, DVD_DOMAIN_VTSTitle);
+ return dvdnav_is_domain(this, VTS_DOMAIN);
}
/* Generally delegate angle information handling to VM */
@@ -1193,7 +1131,7 @@ dvdnav_status_t dvdnav_angle_change(dvdnav_t *this, int32_t angle) {
}
dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *this, int32_t *current_angle,
- int32_t *number_of_angles) {
+ int32_t *number_of_angles) {
pthread_mutex_lock(&this->vm_lock);
vm_get_angle_info(this->vm, current_angle, number_of_angles);
pthread_mutex_unlock(&this->vm_lock);
diff --git a/src/dvdnav/dvd_types.h b/src/dvdnav/dvd_types.h
index baec680..08b46d3 100644
--- a/src/dvdnav/dvd_types.h
+++ b/src/dvdnav/dvd_types.h
@@ -42,13 +42,6 @@ typedef enum {
DVD_MENU_Part = 7
} DVDMenuID_t;
-/* Domain */
-typedef enum {
- DVD_DOMAIN_FirstPlay = 1, /* First Play Domain */
- DVD_DOMAIN_VTSTitle = 2, /* Video Title Set Domain */
- DVD_DOMAIN_VMGM = 4, /* Video Manager Domain */
- DVD_DOMAIN_VTSMenu = 8 /* Video Title Set Menu Domain */
-} DVDDomain_t;
/*
* Structure containing info on highlight areas
@@ -56,7 +49,7 @@ typedef enum {
*/
typedef struct {
uint32_t palette; /* The CLUT entries for the highlight palette
- (4-bits per entry -> 4 entries) */
+ (4-bits per entry -> 4 entries) */
uint16_t sx,sy,ex,ey; /* The start/end x,y positions */
uint32_t pts; /* Highlight PTS to match with SPU */
@@ -64,22 +57,20 @@ typedef struct {
uint32_t buttonN;
} dvdnav_highlight_area_t;
-/* The audio format */
-typedef enum {
- DVD_AUDIO_FORMAT_AC3 = 0,
- DVD_AUDIO_FORMAT_UNKNOWN_1 = 1,
- DVD_AUDIO_FORMAT_MPEG = 2,
- DVD_AUDIO_FORMAT_MPEG2_EXT = 3,
- DVD_AUDIO_FORMAT_LPCM = 4,
- DVD_AUDIO_FORMAT_UNKNOWN_5 = 5,
- DVD_AUDIO_FORMAT_DTS = 6,
- DVD_AUDIO_FORMAT_SDDS = 7
-} DVDAudioFormat_t;
/* the following types are currently unused */
#if 0
+/* Domain */
+typedef enum {
+ DVD_DOMAIN_FirstPlay, /* First Play Domain */
+ DVD_DOMAIN_VMG, /* Video Manager Domain */
+ DVD_DOMAIN_VTSMenu, /* Video Title Set Menu Domain */
+ DVD_DOMAIN_VTSTitle, /* Video Title Set Domain */
+ DVD_DOMAIN_Stop /* Stop Domain */
+} DVDDomain_t;
+
/* User operation permissions */
typedef enum {
UOP_FLAG_TitleOrTimePlay = 0x00000001,
@@ -167,6 +158,19 @@ typedef enum {
DVD_AUDIO_APP_MODE_Other = 3
} DVDAudioAppMode_t;
+/* The audio format */
+typedef enum {
+ DVD_AUDIO_FORMAT_AC3 = 0,
+ DVD_AUDIO_FORMAT_MPEG1 = 1,
+ DVD_AUDIO_FORMAT_MPEG1_DRC = 2,
+ DVD_AUDIO_FORMAT_MPEG2 = 3,
+ DVD_AUDIO_FORMAT_MPEG2_DRC = 4,
+ DVD_AUDIO_FORMAT_LPCM = 5,
+ DVD_AUDIO_FORMAT_DTS = 6,
+ DVD_AUDIO_FORMAT_SDDS = 7,
+ DVD_AUDIO_FORMAT_Other = 8
+} DVDAudioFormat_t;
+
/* Audio language extension */
typedef enum {
DVD_AUDIO_LANG_EXT_NotSpecified = 0,
diff --git a/src/dvdnav/dvdnav.h b/src/dvdnav/dvdnav.h
index f9ded31..6cea0cb 100644
--- a/src/dvdnav/dvdnav.h
+++ b/src/dvdnav/dvdnav.h
@@ -63,6 +63,12 @@ typedef int32_t dvdnav_status_t;
#define DVDNAV_STATUS_ERR 0
#define DVDNAV_STATUS_OK 1
+#define DVDNAV_FORMAT_AC3 0
+#define DVDNAV_FORMAT_MPEGAUDIO 3
+#define DVDNAV_FORMAT_LPCM 4
+#define DVDNAV_FORMAT_DTS 5
+#define DVDNAV_FORMAT_SDDS 6
+
/*********************************************************************
* initialisation & housekeeping functions *
*********************************************************************/
@@ -83,9 +89,6 @@ typedef int32_t dvdnav_status_t;
*/
dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path);
-dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src);
-dvdnav_status_t dvdnav_free_dup(dvdnav_t *this);
-
/*
* Closes a dvdnav_t previously opened with dvdnav_open(), freeing any
* memory associated with it.
@@ -196,7 +199,7 @@ dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *self, int32_t *pgc_bas
* See the dvdnav_events.h header for information on the various events.
*/
dvdnav_status_t dvdnav_get_next_block(dvdnav_t *self, uint8_t *buf,
- int32_t *event, int32_t *len);
+ int32_t *event, int32_t *len);
/*
* This basically does the same as dvdnav_get_next_block. The only difference is
@@ -207,7 +210,7 @@ dvdnav_status_t dvdnav_get_next_block(dvdnav_t *self, uint8_t *buf,
* dvdnav_free_cache_block().
*/
dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *self, uint8_t **buf,
- int32_t *event, int32_t *len);
+ int32_t *event, int32_t *len);
/*
* All buffers which came from the internal cache (when dvdnav_get_next_cache_block()
@@ -296,7 +299,7 @@ uint32_t dvdnav_describe_title_chapters(dvdnav_t *self, int32_t title, uint64_t
* Currently unimplemented!
*/
dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *self, int32_t title,
- int32_t part, int32_t parts_to_play);
+ int32_t part, int32_t parts_to_play);
/*
* Play the specified title starting from the specified time.
@@ -304,7 +307,7 @@ dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *self, int32_t title,
* Currently unimplemented!
*/
dvdnav_status_t dvdnav_time_play(dvdnav_t *self, int32_t title,
- uint64_t time);
+ uint64_t time);
/*
* Stop playing the current position and jump to the specified menu.
@@ -319,14 +322,14 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *self, DVDMenuID_t menu);
* is set to the current menu's ID.
*/
dvdnav_status_t dvdnav_current_title_info(dvdnav_t *self, int32_t *title,
- int32_t *part);
+ int32_t *part);
/*
* Return the title number, pgcn and pgn currently being played.
* A title of 0 indicates, we are in a menu.
*/
dvdnav_status_t dvdnav_current_title_program(dvdnav_t *self, int32_t *title,
- int32_t *pgcn, int32_t *pgn);
+ int32_t *pgcn, int32_t *pgn);
/*
* Return the current position (in blocks) within the current
@@ -336,8 +339,8 @@ dvdnav_status_t dvdnav_current_title_program(dvdnav_t *self, int32_t *title,
* Use is discouraged!
*/
dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *self,
- uint32_t *pos,
- uint32_t *len);
+ uint32_t *pos,
+ uint32_t *len);
/*
* This function is only available for compatibility reasons.
@@ -367,7 +370,7 @@ dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int32_t part);
* fcntl.h.
*/
dvdnav_status_t dvdnav_sector_search(dvdnav_t *self,
- int64_t offset, int32_t origin);
+ uint64_t offset, int32_t origin);
/*
returns the current stream time in PTS ticks as reported by the IFO structures
@@ -379,11 +382,10 @@ int64_t dvdnav_get_current_time(dvdnav_t *self);
* Stop playing the current position and start playback of the title
* from the specified timecode.
*
- * Currently implemented using interpolation. That interpolation is slightly
- * inaccurate.
+ * Currently implemented using interpolation, which is slightly inaccurate.
*/
dvdnav_status_t dvdnav_time_search(dvdnav_t *self,
- uint64_t time);
+ uint64_t time);
/*
* Stop playing current position and play the "GoUp"-program chain.
@@ -418,7 +420,7 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *self);
* relative position in and the length of the current program chain.
*/
dvdnav_status_t dvdnav_get_position(dvdnav_t *self, uint32_t *pos,
- uint32_t *len);
+ uint32_t *len);
/*********************************************************************
@@ -463,7 +465,7 @@ dsi_t* dvdnav_get_current_nav_dsi(dvdnav_t *self);
* Get the area associated with a certain button.
*/
dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode,
- dvdnav_highlight_area_t *highlight);
+ dvdnav_highlight_area_t *highlight);
/*
* Move button highlight around as suggested by function name (e.g. with arrow keys).
@@ -517,19 +519,19 @@ dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, pci_t *pci, int32_t x, int
* Set which menu language we should use per default.
*/
dvdnav_status_t dvdnav_menu_language_select(dvdnav_t *self,
- char *code);
+ char *code);
/*
* Set which audio language we should use per default.
*/
dvdnav_status_t dvdnav_audio_language_select(dvdnav_t *self,
- char *code);
+ char *code);
/*
* Set which spu language we should use per default.
*/
dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *self,
- char *code);
+ char *code);
/*********************************************************************
@@ -667,7 +669,7 @@ dvdnav_status_t dvdnav_angle_change(dvdnav_t *self, int32_t angle);
* Returns the current angle and number of angles present.
*/
dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *self, int32_t *current_angle,
- int32_t *number_of_angles);
+ int32_t *number_of_angles);
/*********************************************************************
* domain queries *
diff --git a/src/dvdnav/dvdnav_events.h b/src/dvdnav/dvdnav_events.h
index b912c54..921e8d8 100644
--- a/src/dvdnav/dvdnav_events.h
+++ b/src/dvdnav/dvdnav_events.h
@@ -31,7 +31,7 @@
* A regular data block from the DVD has been returned.
* This one should be demuxed and decoded for playback.
*/
-#define DVDNAV_BLOCK_OK 0
+#define DVDNAV_BLOCK_OK 0
/*
@@ -39,7 +39,7 @@
*
* Just ignore this.
*/
-#define DVDNAV_NOP 1
+#define DVDNAV_NOP 1
/*
@@ -53,7 +53,7 @@
* A length of 0xff means an infinite still which has to be skipped
* indirectly by some user interaction.
*/
-#define DVDNAV_STILL_FRAME 2
+#define DVDNAV_STILL_FRAME 2
typedef struct {
/* The length (in seconds) the still frame should be displayed for,
@@ -67,7 +67,7 @@ typedef struct {
*
* Inform the SPU decoding/overlaying engine to switch SPU channels.
*/
-#define DVDNAV_SPU_STREAM_CHANGE 3
+#define DVDNAV_SPU_STREAM_CHANGE 3
typedef struct {
/* The physical (MPEG) stream number for widescreen SPU display.
@@ -95,7 +95,7 @@ typedef struct {
*
* Inform the audio decoder to switch channels.
*/
-#define DVDNAV_AUDIO_STREAM_CHANGE 4
+#define DVDNAV_AUDIO_STREAM_CHANGE 4
typedef struct {
/* The physical (MPEG) stream number. */
@@ -114,13 +114,13 @@ typedef struct {
* information only when necessary and update the decoding/displaying
* accordingly.
*/
-#define DVDNAV_VTS_CHANGE 5
+#define DVDNAV_VTS_CHANGE 5
typedef struct {
int old_vtsN; /* the old VTS number */
- DVDDomain_t old_domain; /* the old domain */
+ dvd_read_domain_t old_domain; /* the old domain */
int new_vtsN; /* the new VTS number */
- DVDDomain_t new_domain; /* the new domain */
+ dvd_read_domain_t new_domain; /* the new domain */
} dvdnav_vts_change_event_t;
@@ -134,7 +134,7 @@ typedef struct {
* Some useful information for accurate time display is also reported
* together with this event.
*/
-#define DVDNAV_CELL_CHANGE 6
+#define DVDNAV_CELL_CHANGE 6
typedef struct {
int cellN; /* the new cell number */
@@ -161,7 +161,7 @@ typedef struct {
* NAV packets can also be used for time display, because they are
* timestamped relatively to the current Cell.
*/
-#define DVDNAV_NAV_PACKET 7
+#define DVDNAV_NAV_PACKET 7
/*
@@ -170,7 +170,7 @@ typedef struct {
* Applications should end playback here. A subsequent dvdnav_get_next_block()
* call will restart the VM from the beginning of the DVD.
*/
-#define DVDNAV_STOP 8
+#define DVDNAV_STOP 8
/*
@@ -184,7 +184,7 @@ typedef struct {
* to handle the mode 2 highlighting (that is some different colour the
* button turns to on activation) in your application.
*/
-#define DVDNAV_HIGHLIGHT 9
+#define DVDNAV_HIGHLIGHT 9
typedef struct {
/* highlight mode: 0 - hide, 1 - show, 2 - activate, currently always 1 */
@@ -192,7 +192,7 @@ typedef struct {
/* FIXME: these fields are currently not set */
uint32_t palette; /* The CLUT entries for the highlight palette
- (4-bits per entry -> 4 entries) */
+ (4-bits per entry -> 4 entries) */
uint16_t sx,sy,ex,ey; /* The start/end x,y positions */
uint32_t pts; /* Highlight PTS to match with SPU */
@@ -207,7 +207,7 @@ typedef struct {
* Inform the SPU decoder/overlaying engine to update its colour lookup table.
* The CLUT is given as 16 uint32_t's in the buffer.
*/
-#define DVDNAV_SPU_CLUT_CHANGE 10
+#define DVDNAV_SPU_CLUT_CHANGE 10
/*
@@ -216,7 +216,7 @@ typedef struct {
* A non-seamless operation has been performed. Applications can drop all
* their internal fifo's content, which will speed up the response.
*/
-#define DVDNAV_HOP_CHANNEL 12
+#define DVDNAV_HOP_CHANNEL 12
/*
@@ -230,7 +230,7 @@ typedef struct {
* when they receive this type of event.
* Once this is achieved, call dvdnav_skip_wait().
*/
-#define DVDNAV_WAIT 13
+#define DVDNAV_WAIT 13
#endif /* LIBDVDNAV_DVDNAV_EVENTS_H */
diff --git a/src/dvdnav_internal.h b/src/dvdnav_internal.h
index 2b5a5c2..089ab14 100644
--- a/src/dvdnav_internal.h
+++ b/src/dvdnav_internal.h
@@ -187,17 +187,17 @@ int64_t dvdnav_convert_time(dvd_time_t *time);
#ifdef __GNUC__
#define printerrf(format, args...) \
- do { if (this) snprintf(this->err_str, MAX_ERR_LEN, format, ## args); } while (0)
+ do { if (this) snprintf(this->err_str, MAX_ERR_LEN, format, ## args); } while (0)
#else
#ifdef _MSC_VER
#define printerrf(str) \
- do { if (this) snprintf(this->err_str, MAX_ERR_LEN, str); } while (0)
+ do { if (this) snprintf(this->err_str, MAX_ERR_LEN, str); } while (0)
#else
#define printerrf(...) \
- do { if (this) snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__); } while (0)
+ do { if (this) snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__); } while (0)
#endif /* WIN32 */
#endif
#define printerr(str) \
- do { if (this) strncpy(this->err_str, str, MAX_ERR_LEN - 1); } while (0)
+ do { if (this) strncpy(this->err_str, str, MAX_ERR_LEN - 1); } while (0)
#endif /* LIBDVDNAV_DVDNAV_INTERNAL_H */
diff --git a/src/highlight.c b/src/highlight.c
index 01539a8..f484357 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -242,13 +242,8 @@ static btni_t *get_current_button(dvdnav_t *this, pci_t *pci) {
}
static dvdnav_status_t button_auto_action(dvdnav_t *this, pci_t *pci) {
- btni_t *button_ptr;
- if ((button_ptr = get_current_button(this, pci)) == NULL)
- return DVDNAV_STATUS_ERR;
-
- if (button_ptr->auto_action_mode)
+ if (get_current_button(this, pci)->auto_action_mode)
return dvdnav_button_activate(this, pci);
-
return DVDNAV_STATUS_OK;
}
@@ -293,7 +288,7 @@ dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this, pci_t *pci) {
}
dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode,
- dvdnav_highlight_area_t *highlight) {
+ dvdnav_highlight_area_t *highlight) {
btni_t *button_ptr;
#ifdef BUTTON_TESTING
@@ -371,11 +366,7 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) {
return DVDNAV_STATUS_ERR;
}
- if ((button_ptr = get_current_button(this, pci)) == NULL) {
- pthread_mutex_unlock(&this->vm_lock);
- return DVDNAV_STATUS_ERR;
- }
-
+ button_ptr = get_current_button(this, pci);
/* Finally, make the VM execute the appropriate code and probably
* schedule a jump */
#ifdef BUTTON_TESTING
@@ -440,7 +431,7 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int32_t button)
}
dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, pci_t *pci,
- int32_t button) {
+ int32_t button) {
/* A trivial function */
if(dvdnav_button_select(this, pci, button) != DVDNAV_STATUS_ERR)
return dvdnav_button_activate(this, pci);
diff --git a/src/navigation.c b/src/navigation.c
index 50437f2..6f8a080 100644
--- a/src/navigation.c
+++ b/src/navigation.c
@@ -99,8 +99,8 @@ dvdnav_status_t dvdnav_current_title_info(dvdnav_t *this, int32_t *title, int32_
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
- if ( (this->vm->state.domain == DVD_DOMAIN_VTSMenu)
- || (this->vm->state.domain == DVD_DOMAIN_VMGM) ) {
+ if ( (this->vm->state.domain == VTSM_DOMAIN)
+ || (this->vm->state.domain == VMGM_DOMAIN) ) {
/* Get current Menu ID: into *part. */
if(! vm_get_current_menu(this->vm, part)) {
pthread_mutex_unlock(&this->vm_lock);
@@ -112,7 +112,7 @@ dvdnav_status_t dvdnav_current_title_info(dvdnav_t *this, int32_t *title, int32_
return DVDNAV_STATUS_OK;
}
}
- if (this->vm->state.domain == DVD_DOMAIN_VTSTitle) {
+ if (this->vm->state.domain == VTS_DOMAIN) {
retval = vm_get_current_title_part(this->vm, title, part);
pthread_mutex_unlock(&this->vm_lock);
return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
@@ -142,8 +142,8 @@ dvdnav_status_t dvdnav_current_title_program(dvdnav_t *this, int32_t *title, int
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
- if ( (this->vm->state.domain == DVD_DOMAIN_VTSMenu)
- || (this->vm->state.domain == DVD_DOMAIN_VMGM) ) {
+ if ( (this->vm->state.domain == VTSM_DOMAIN)
+ || (this->vm->state.domain == VMGM_DOMAIN) ) {
/* Get current Menu ID: into *part. */
if(! vm_get_current_menu(this->vm, &part)) {
pthread_mutex_unlock(&this->vm_lock);
@@ -157,7 +157,7 @@ dvdnav_status_t dvdnav_current_title_program(dvdnav_t *this, int32_t *title, int
return DVDNAV_STATUS_OK;
}
}
- if (this->vm->state.domain == DVD_DOMAIN_VTSTitle) {
+ if (this->vm->state.domain == VTS_DOMAIN) {
retval = vm_get_current_title_part(this->vm, title, &part);
*pgcn = this->vm->state.pgcN;
*pgn = this->vm->state.pgN;
@@ -245,7 +245,7 @@ dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int32_t title, int32_t part) {
}
dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *this, int32_t title,
- int32_t part, int32_t parts_to_play) {
+ int32_t part, int32_t parts_to_play) {
/* FIXME: Implement auto-stop */
if (dvdnav_part_play(this, title, part) == DVDNAV_STATUS_OK)
printerr("Not implemented yet.");
@@ -253,7 +253,7 @@ dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *this, int32_t title,
}
dvdnav_status_t dvdnav_time_play(dvdnav_t *this, int32_t title,
- uint64_t time) {
+ uint64_t time) {
/* FIXME: Implement */
printerr("Not implemented yet.");
return DVDNAV_STATUS_ERR;
@@ -268,7 +268,8 @@ dvdnav_status_t dvdnav_stop(dvdnav_t *this) {
dvdnav_status_t dvdnav_go_up(dvdnav_t *this) {
/* A nice easy function... delegate to the VM */
- int retval;
+ int32_t retval;
+
pthread_mutex_lock(&this->vm_lock);
retval = vm_jump_up(this->vm);
pthread_mutex_unlock(&this->vm_lock);
diff --git a/src/read_cache.c b/src/read_cache.c
index a9871fe..0c61e7d 100644
--- a/src/read_cache.c
+++ b/src/read_cache.c
@@ -194,21 +194,21 @@ void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count)
/* we still haven't found a cache chunk, let's allocate a new one */
for (i = 0; i < READ_CACHE_CHUNKS; i++)
if (!self->chunk[i].cache_buffer) {
- use = i;
- break;
- }
+ use = i;
+ break;
+ }
if (use >= 0) {
/* We start with a sensible figure for the first malloc of 500 blocks.
* Some DVDs I have seen venture to 450 blocks.
* This is so that fewer realloc's happen if at all.
*/
- self->chunk[i].cache_buffer_base =
- malloc((block_count > 500 ? block_count : 500) * DVD_VIDEO_LB_LEN + ALIGNMENT);
- self->chunk[i].cache_buffer =
- (uint8_t *)(((uintptr_t)self->chunk[i].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT);
- self->chunk[i].cache_malloc_size = block_count > 500 ? block_count : 500;
- dprintf("pre_cache DVD read malloc %d blocks\n",
- (block_count > 500 ? block_count : 500 ));
+ self->chunk[i].cache_buffer_base =
+ malloc((block_count > 500 ? block_count : 500) * DVD_VIDEO_LB_LEN + ALIGNMENT);
+ self->chunk[i].cache_buffer =
+ (uint8_t *)(((uintptr_t)self->chunk[i].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT);
+ self->chunk[i].cache_malloc_size = block_count > 500 ? block_count : 500;
+ dprintf("pre_cache DVD read malloc %d blocks\n",
+ (block_count > 500 ? block_count : 500 ));
}
}
}
@@ -311,9 +311,8 @@ int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count,
} else {
- if (self->dvd_self->use_read_ahead) {
+ if (self->dvd_self->use_read_ahead)
dprintf("cache miss on sector %d\n", sector);
- }
res = DVDReadBlocks(self->dvd_self->file,
sector,
diff --git a/src/remap.c b/src/remap.c
index 664300b..4632a49 100644
--- a/src/remap.c
+++ b/src/remap.c
@@ -63,9 +63,6 @@ struct remap_s {
static remap_t* remap_new( char *title) {
remap_t *map = malloc( sizeof(remap_t));
- if (map == NULL)
- return NULL;
-
map->title = strdup(title);
map->maxblocks = 0;
map->nblocks = 0;
@@ -77,32 +74,32 @@ static remap_t* remap_new( char *title) {
static int compare_block( block_t *a, block_t *b) {
/* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */
if (a->domain < b->domain) {
- return -1;
+ return -1;
} else if (a->domain > b->domain) {
- return 1;
+ return 1;
}
if (a->title < b->title) {
- return -1;
+ return -1;
} else if (a->title > b->title) {
- return 1;
+ return 1;
}
if (a->program < b->program) {
- return -1;
+ return -1;
} else if (a->program > b->program) {
- return 1;
+ return 1;
}
if (a->end_block < b->start_block) {
- return -1;
+ return -1;
} else if (a->start_block > b->end_block) {
- /*
- * if a->start_block == b->end_block then the two regions
- * aren't strictly overlapping, but they should be merged
- * anyway since there are zero blocks between them
- */
- return 1;
+ /*
+ * if a->start_block == b->end_block then the two regions
+ * aren't strictly overlapping, but they should be merged
+ * anyway since there are zero blocks between them
+ */
+ return 1;
}
return 0;
@@ -115,15 +112,15 @@ static block_t *findblock( remap_t *map, block_t *key) {
int res;
while (lb <= ub) {
- mid = lb + (ub - lb)/2;
- res = compare_block( key, &map->blocks[mid]);
- if (res < 0) {
- ub = mid-1;
- } else if (res > 0) {
- lb = mid+1;
- } else {
- return &map->blocks[mid];
- }
+ mid = lb + (ub - lb)/2;
+ res = compare_block( key, &map->blocks[mid]);
+ if (res < 0) {
+ ub = mid-1;
+ } else if (res > 0) {
+ lb = mid+1;
+ } else {
+ return &map->blocks[mid];
+ }
}
return NULL;
}
@@ -138,35 +135,31 @@ static void remap_add_node( remap_t *map, block_t block) {
int n;
b = findblock( map, &block);
if (b) {
- /* overlaps an existing block */
- mergeblock( b, block);
+ /* overlaps an existing block */
+ mergeblock( b, block);
} else {
/* new block */
- if (map->nblocks >= map->maxblocks) {
- if ((map->blocks = realloc( map->blocks, sizeof( block_t)*( map->maxblocks + 20))) == NULL)
- return;
-
- map->maxblocks += 20;
- }
- n = map->nblocks++;
- while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {
- map->blocks[ n] = map->blocks[ n-1];
- n--;
- }
- map->blocks[ n] = block;
+ if (map->nblocks >= map->maxblocks) {
+ map->maxblocks += 20;
+ map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks);
+ }
+ n = map->nblocks++;
+ while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {
+ map->blocks[ n] = map->blocks[ n-1];
+ n--;
+ }
+ map->blocks[ n] = block;
}
}
static int parseblock(char *buf, int *dom, int *tt, int *pg,
- unsigned long *start, unsigned long *end) {
+ unsigned long *start, unsigned long *end) {
long tmp;
char *tok;
- char *epos = NULL;
+ char *epos;
char *marker[]={"domain", "title", "program", "start", "end"};
int st = 0;
- if ((tok = strtok( buf, " ")) == NULL)
- return st;
-
+ tok = strtok( buf, " ");
while (st < 5) {
if (strcmp(tok, marker[st])) return -st-1000;
tok = strtok( NULL, " ");
@@ -174,24 +167,24 @@ static int parseblock(char *buf, int *dom, int *tt, int *pg,
tmp = strtol( tok, &epos, 0);
if (*epos != 0 && *epos != ',') return -st-3000;
switch (st) {
- case 0:
- *dom = (int)tmp;
- break;
- case 1:
- *tt = (int)tmp;
- break;
- case 2:
- *pg = (int)tmp;
- break;
- case 3:
- *start = tmp;
- break;
- case 4:
- *end = tmp;
- break;
- }
- st++;
- if (!(tok = strtok( NULL, " "))) return -st-2000;
+ case 0:
+ *dom = (int)tmp;
+ break;
+ case 1:
+ *tt = (int)tmp;
+ break;
+ case 2:
+ *pg = (int)tmp;
+ break;
+ case 3:
+ *start = tmp;
+ break;
+ case 4:
+ *end = tmp;
+ break;
+ }
+ st++;
+ tok = strtok( NULL, " ");
}
return st;
}
@@ -217,30 +210,25 @@ remap_t* remap_loadmap( char *title) {
/* Open the map file */
fp = fopen( fname, "r");
if (!fp) {
- fprintf(MSG_OUT, "libdvdnav: Unable to find map file '%s'\n", fname);
- return NULL;
+ fprintf(MSG_OUT, "libdvdnav: Unable to find map file '%s'\n", fname);
+ return NULL;
}
/* Load the map file */
- if ((map = remap_new( title)) == NULL) {
- fprintf(MSG_OUT, "libdvdnav: Unable to load map '%s'\n", title);
- fclose(fp);
- return NULL;
- }
-
+ map = remap_new( title);
while (fgets( buf, sizeof(buf), fp) != NULL) {
if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue;
if (strncasecmp( buf, "debug", 5) == 0) {
- map->debug = 1;
- } else {
- res = parseblock( buf,
- &tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block);
- if (res != 5) {
- fprintf(MSG_OUT, "libdvdnav: Ignoring map line (%d): %s\n", res, buf);
- continue;
- }
- remap_add_node( map, tmp);
- }
+ map->debug = 1;
+ } else {
+ res = parseblock( buf,
+ &tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block);
+ if (res != 5) {
+ fprintf(MSG_OUT, "libdvdnav: Ignoring map line (%d): %s\n", res, buf);
+ continue;
+ }
+ remap_add_node( map, tmp);
+ }
}
fclose(fp);
@@ -252,15 +240,15 @@ remap_t* remap_loadmap( char *title) {
}
unsigned long remap_block(
- remap_t *map, int domain, int title, int program,
- unsigned long cblock, unsigned long offset)
+ remap_t *map, int domain, int title, int program,
+ unsigned long cblock, unsigned long offset)
{
block_t key;
block_t *b;
if (map->debug) {
- fprintf(MSG_OUT, "libdvdnav: %s: domain %d, title %d, program %d, start %lx, next %lx\n",
- map->title, domain, title, program, cblock, cblock+offset);
+ fprintf(MSG_OUT, "libdvdnav: %s: domain %d, title %d, program %d, start %lx, next %lx\n",
+ map->title, domain, title, program, cblock, cblock+offset);
}
key.domain = domain;
@@ -271,7 +259,7 @@ unsigned long remap_block(
if (b) {
if (map->debug) {
- fprintf(MSG_OUT, "libdvdnav: Redirected to %lx\n", b->end_block);
+ fprintf(MSG_OUT, "libdvdnav: Redirected to %lx\n", b->end_block);
}
return b->end_block - cblock;
}
diff --git a/src/remap.h b/src/remap.h
index bb4a92d..3d4dced 100644
--- a/src/remap.h
+++ b/src/remap.h
@@ -25,7 +25,7 @@ typedef struct remap_s remap_t;
remap_t* remap_loadmap( char *title);
unsigned long remap_block(
- remap_t *map, int domain, int title, int program,
- unsigned long cblock, unsigned long offset);
+ remap_t *map, int domain, int title, int program,
+ unsigned long cblock, unsigned long offset);
#endif /* LIBDVDNAV_REMAP_H */
diff --git a/src/searching.c b/src/searching.c
index 80956ac..620778f 100644
--- a/src/searching.c
+++ b/src/searching.c
@@ -58,14 +58,14 @@ static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_
/* Search through the VOBU_ADMAP for the nearest VOBU
* to the target block */
switch(domain) {
- case DVD_DOMAIN_FirstPlay:
- case DVD_DOMAIN_VMGM:
+ case FP_DOMAIN:
+ case VMGM_DOMAIN:
admap = this->vm->vmgi->menu_vobu_admap;
break;
- case DVD_DOMAIN_VTSMenu:
+ case VTSM_DOMAIN:
admap = this->vm->vtsi->menu_vobu_admap;
break;
- case DVD_DOMAIN_VTSTitle:
+ case VTS_DOMAIN:
admap = this->vm->vtsi->vts_vobu_admap;
break;
default:
@@ -73,7 +73,7 @@ static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_
}
if(admap) {
uint32_t address = 0;
- uint32_t vobu_start, next_vobu = 0;
+ uint32_t vobu_start, next_vobu;
int admap_entries = (admap->last_byte + 1 - VOBU_ADMAP_SIZE)/VOBU_ADMAP_SIZE;
/* Search through ADMAP for best sector */
@@ -99,7 +99,7 @@ static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_
/* FIXME: right now, this function does not use the time tables but interpolates
only the cell times */
dvdnav_status_t dvdnav_time_search(dvdnav_t *this,
- uint64_t time) {
+ uint64_t time) {
uint64_t target = time;
uint64_t length = 0;
@@ -158,7 +158,7 @@ dvdnav_status_t dvdnav_time_search(dvdnav_t *this,
uint32_t vobu;
#ifdef LOG_DEBUG
fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n",
- cell_nr, first_cell_nr, last_cell_nr);
+ cell_nr, first_cell_nr, last_cell_nr);
#endif
if (dvdnav_scan_admap(this, state->domain, target, 0, &vobu) == DVDNAV_STATUS_OK) {
uint32_t start = state->pgc->cell_playback[cell_nr-1].first_sector;
@@ -182,7 +182,7 @@ dvdnav_status_t dvdnav_time_search(dvdnav_t *this,
}
dvdnav_status_t dvdnav_sector_search(dvdnav_t *this,
- int64_t offset, int32_t origin) {
+ uint64_t offset, int32_t origin) {
uint32_t target = 0;
uint32_t current_pos;
uint32_t cur_sector;
@@ -213,7 +213,7 @@ dvdnav_status_t dvdnav_sector_search(dvdnav_t *this,
return DVDNAV_STATUS_ERR;
}
#ifdef LOG_DEBUG
- fprintf(MSG_OUT, "libdvdnav: seeking to offset=%lld pos=%u length=%u\n", offset, target, length);
+ fprintf(MSG_OUT, "libdvdnav: seeking to offset=%lu pos=%u length=%u\n", offset, target, length);
fprintf(MSG_OUT, "libdvdnav: Before cellN=%u blockN=%u\n", state->cellN, state->blockN);
#endif
@@ -231,16 +231,11 @@ dvdnav_status_t dvdnav_sector_search(dvdnav_t *this,
target = offset;
break;
case SEEK_CUR:
- if((signed)target + offset >= length) {
+ if(target + offset >= length) {
printerr("Request to seek behind end.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
- if((signed)target + offset < 0) {
- printerr("Request to seek before start.");
- pthread_mutex_unlock(&this->vm_lock);
- return DVDNAV_STATUS_ERR;
- }
target += offset;
break;
case SEEK_END:
@@ -314,7 +309,7 @@ dvdnav_status_t dvdnav_sector_search(dvdnav_t *this,
uint32_t vobu;
#ifdef LOG_DEBUG
fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n",
- cell_nr, first_cell_nr, last_cell_nr);
+ cell_nr, first_cell_nr, last_cell_nr);
#endif
if (dvdnav_scan_admap(this, state->domain, target, 0, &vobu) == DVDNAV_STATUS_OK) {
int32_t start = state->pgc->cell_playback[cell_nr-1].first_sector;
@@ -408,7 +403,8 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) {
pthread_mutex_lock(&this->vm_lock);
if(!this->vm->state.pgc) {
printerr("No current PGC.");
- goto fail;
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
}
#ifdef LOG_DEBUG
@@ -416,25 +412,17 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) {
#endif
/* make a copy of current VM and try to navigate the copy to the next PG */
try_vm = vm_new_copy(this->vm);
- if (try_vm == NULL) {
- printerr("Unable to copy the VM.");
- goto fail;
- }
-
if (!vm_jump_next_pg(try_vm) || try_vm->stopped) {
vm_free_copy(try_vm);
/* next_pg failed, try to jump at least to the next cell */
try_vm = vm_new_copy(this->vm);
- if (try_vm == NULL) {
- printerr("Unable to copy the VM.");
- goto fail;
- }
vm_get_next_cell(try_vm);
if (try_vm->stopped) {
vm_free_copy(try_vm);
fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n");
printerr("Skip to next chapter failed.");
- goto fail;
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
}
}
this->cur_cell_time = 0;
@@ -449,10 +437,6 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) {
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
-
-fail:
- pthread_mutex_unlock(&this->vm_lock);
- return DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) {
@@ -461,18 +445,14 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) {
pthread_mutex_lock(&this->vm_lock);
if(!this->vm->state.pgc) {
printerr("No current PGC.");
- goto fail;
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
}
this->cur_cell_time = 0;
/* make a copy of current VM and try to navigate the copy to the menu */
try_vm = vm_new_copy(this->vm);
- if (try_vm == NULL) {
- printerr("Unable to copy VM.");
- goto fail;
- }
-
- if ( (menu == DVD_MENU_Escape) && (this->vm->state.domain != DVD_DOMAIN_VTSTitle)) {
+ if ( (menu == DVD_MENU_Escape) && (this->vm->state.domain != VTS_DOMAIN)) {
/* Try resume */
if (vm_jump_resume(try_vm) && !try_vm->stopped) {
/* merge changes on success */
@@ -497,16 +477,13 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) {
} else {
vm_free_copy(try_vm);
printerr("No such menu or menu not reachable.");
- goto fail;
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
}
-
-fail:
- pthread_mutex_unlock(&this->vm_lock);
- return DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_get_position(dvdnav_t *this, uint32_t *pos,
- uint32_t *len) {
+ uint32_t *len) {
uint32_t cur_sector;
int32_t cell_nr, first_cell_nr, last_cell_nr;
cell_playback_t *cell;
@@ -553,8 +530,6 @@ dvdnav_status_t dvdnav_get_position(dvdnav_t *this, uint32_t *pos,
*len = 0;
for (cell_nr = first_cell_nr; cell_nr <= last_cell_nr; cell_nr++) {
cell = &(state->pgc->cell_playback[cell_nr-1]);
- if(cell->block_type == BLOCK_TYPE_ANGLE_BLOCK && cell->block_mode != BLOCK_MODE_FIRST_CELL)
- continue;
if (cell_nr == state->cellN) {
/* the current sector is in this cell,
* pos is length of PG up to here + sector's offset in this cell */
@@ -571,8 +546,8 @@ dvdnav_status_t dvdnav_get_position(dvdnav_t *this, uint32_t *pos,
}
dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *this,
- uint32_t *pos,
- uint32_t *len) {
+ uint32_t *pos,
+ uint32_t *len) {
uint32_t cur_sector;
uint32_t first_cell_nr;
uint32_t last_cell_nr;
@@ -641,20 +616,12 @@ uint32_t dvdnav_describe_title_chapters(dvdnav_t *this, int32_t title, uint64_t
length = 0;
for(i=0; i<parts; i++) {
uint32_t cellnr, endcellnr;
- if (ifo->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc_start_byte >= ifo->vts_pgcit->last_byte) {
- printerr("PGC start out of bounds");
- continue;
- }
- if (0 == ifo->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc_start_byte) {
- printerr("PGC start zero.");
- continue;
- }
- if (0 != (ifo->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc_start_byte & 1)) {
- printerr("PGC start unaligned.");
+ if (ptt[i].pgcn == 0 || ptt[i].pgcn > ifo->vts_pgcit->nr_of_pgci_srp) {
+ printerr("PGCN out of bounds.");
continue;
}
- if (0 != ((uintptr_t)(ifo->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc) & 1)) {
- printerr("PGC pointer unaligned.");
+ if (ifo->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc_start_byte >= ifo->vts_pgcit->last_byte) {
+ printerr("PGC start out of bounds");
continue;
}
pgc = ifo->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc;
@@ -666,7 +633,7 @@ uint32_t dvdnav_describe_title_chapters(dvdnav_t *this, int32_t title, uint64_t
printerr("Program map missing.");
continue;
}
- if(ptt[i].pgn > pgc->nr_of_programs) {
+ if(ptt[i].pgn == 0 || ptt[i].pgn > pgc->nr_of_programs) {
printerr("WRONG part number.");
goto fail;
}
diff --git a/src/vm/Makefile.am b/src/vm/Makefile.am
new file mode 100644
index 0000000..1731ed5
--- /dev/null
+++ b/src/vm/Makefile.am
@@ -0,0 +1,16 @@
+include $(top_srcdir)/misc/Makefile.common
+
+includedir = ${prefix}/include/dvdnav
+
+AM_CPPFLAGS = -DDVDNAV_COMPILE $(THREAD_CFLAGS) $(DVDREAD_CFLAGS) \
+ -I$(top_srcdir)/src
+
+noinst_LTLIBRARIES = libdvdvm.la
+
+libdvdvm_la_SOURCES = decoder.c vm.c vmcmd.c
+
+libdvdvm_la_LDFLAGS = $(THREAD_LIBS)
+
+include_HEADERS =
+
+noinst_HEADERS = decoder.h vm.h vmcmd.h
diff --git a/src/vm/decoder.c b/src/vm/decoder.c
index 84a82c5..fb4ade5 100644
--- a/src/vm/decoder.c
+++ b/src/vm/decoder.c
@@ -30,8 +30,6 @@
#include <limits.h>
#include <string.h> /* For memset */
#include <sys/time.h>
-#include <assert.h>
-
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h> /* vm_cmd_t */
@@ -133,7 +131,7 @@ static uint16_t eval_reg_or_data(command_t* command, int32_t imm, int32_t start)
lower four bits for the general purpose register number. */
/* Evaluates gprm or data depending on bit, data is in byte n */
static uint16_t eval_reg_or_data_2(command_t* command,
- int32_t imm, int32_t start) {
+ int32_t imm, int32_t start) {
if(imm) /* immediate */
return vm_getbits(command, (start - 1), 7);
else
@@ -230,9 +228,9 @@ static int32_t eval_special_instruction(command_t* command, int32_t cond) {
line = vm_getbits(command, 7, 8);
level = vm_getbits(command, 11, 4);
if(cond) {
- /* This always succeeds now, if we want real parental protection */
- /* we need to ask the user and have passwords and stuff. */
- command->registers->SPRM[13] = level;
+ /* This always succeeds now, if we want real parental protection */
+ /* we need to ask the user and have passwords and stuff. */
+ command->registers->SPRM[13] = level;
}
return cond ? line : 0;
}
@@ -264,26 +262,26 @@ static int32_t eval_link_instruction(command_t* command, int32_t cond, link_t *r
switch(op) {
case 1:
- return eval_link_subins(command, cond, return_values);
+ return eval_link_subins(command, cond, return_values);
case 4:
- return_values->command = LinkPGCN;
- return_values->data1 = vm_getbits(command, 14, 15);
- return cond;
+ return_values->command = LinkPGCN;
+ return_values->data1 = vm_getbits(command, 14, 15);
+ return cond;
case 5:
- return_values->command = LinkPTTN;
- return_values->data1 = vm_getbits(command, 9, 10);
- return_values->data2 = vm_getbits(command, 15, 6);
- return cond;
+ return_values->command = LinkPTTN;
+ return_values->data1 = vm_getbits(command, 9, 10);
+ return_values->data2 = vm_getbits(command, 15, 6);
+ return cond;
case 6:
- return_values->command = LinkPGN;
- return_values->data1 = vm_getbits(command, 6, 7);
- return_values->data2 = vm_getbits(command, 15, 6);
- return cond;
+ return_values->command = LinkPGN;
+ return_values->data1 = vm_getbits(command, 6, 7);
+ return_values->data2 = vm_getbits(command, 15, 6);
+ return cond;
case 7:
- return_values->command = LinkCN;
- return_values->data1 = vm_getbits(command, 7, 8);
- return_values->data2 = vm_getbits(command, 15, 6);
- return cond;
+ return_values->command = LinkCN;
+ return_values->data1 = vm_getbits(command, 7, 8);
+ return_values->data2 = vm_getbits(command, 15, 6);
+ return cond;
}
return 0;
}
@@ -380,17 +378,17 @@ static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_
data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
data2 = vm_getbits(command, 23, 8); /* ?? size */
if(cond) {
- command->registers->SPRM[9] = data; /* time */
- command->registers->SPRM[10] = data2; /* pgcN */
+ command->registers->SPRM[9] = data; /* time */
+ command->registers->SPRM[10] = data2; /* pgcN */
}
break;
case 3: /* Mode: Counter / Register + Set */
data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
data2 = vm_getbits(command, 19, 4);
if(vm_getbits(command, 23, 1)) {
- command->registers->GPRM_mode[data2] |= 1; /* Set bit 0 */
+ command->registers->GPRM_mode[data2] |= 1; /* Set bit 0 */
} else {
- command->registers->GPRM_mode[data2] &= ~ 0x01; /* Reset bit 0 */
+ command->registers->GPRM_mode[data2] &= ~ 0x01; /* Reset bit 0 */
}
if(cond) {
set_GPRM(command->registers, data2, data);
@@ -399,7 +397,7 @@ static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_
case 6: /* Set system reg 8 (Highlighted button) */
data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31); /* Not system reg!! */
if(cond) {
- command->registers->SPRM[8] = data;
+ command->registers->SPRM[8] = data;
}
break;
}
@@ -518,8 +516,8 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu
cond = eval_if_version_1(&command);
res = eval_special_instruction(&command, cond);
if(res == -1) {
- fprintf(MSG_OUT, "libdvdnav: Unknown Instruction!\n");
- assert(0);
+ fprintf(MSG_OUT, "libdvdnav: Unknown Instruction!\n");
+ abort();
}
break;
case 1: /* Link/jump instructions */
@@ -531,29 +529,29 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu
res = eval_link_instruction(&command, cond, return_values);
}
if(res)
- res = -1;
+ res = -1;
break;
case 2: /* System set instructions */
cond = eval_if_version_2(&command);
res = eval_system_set(&command, cond, return_values);
if(res)
- res = -1;
+ res = -1;
break;
case 3: /* Set instructions, either Compare or Link may be used */
cond = eval_if_version_3(&command);
eval_set_version_1(&command, cond);
if(vm_getbits(&command, 51, 4)) {
- res = eval_link_instruction(&command, cond, return_values);
+ res = eval_link_instruction(&command, cond, return_values);
}
if(res)
- res = -1;
+ res = -1;
break;
case 4: /* Set, Compare -> Link Sub-Instruction */
eval_set_version_2(&command, /*True*/ 1);
cond = eval_if_version_4(&command);
res = eval_link_subins(&command, cond, return_values);
if(res)
- res = -1;
+ res = -1;
break;
case 5: /* Compare -> (Set and Link Sub-Instruction) */
/* FIXME: These are wrong. Need to be updated from vmcmd.c */
@@ -561,7 +559,7 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu
eval_set_version_2(&command, cond);
res = eval_link_subins(&command, cond, return_values);
if(res)
- res = -1;
+ res = -1;
break;
case 6: /* Compare -> Set, allways Link Sub-Instruction */
/* FIXME: These are wrong. Need to be updated from vmcmd.c */
@@ -569,11 +567,11 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu
eval_set_version_2(&command, cond);
res = eval_link_subins(&command, /*True*/ 1, return_values);
if(res)
- res = -1;
+ res = -1;
break;
default: /* Unknown command */
fprintf(MSG_OUT, "libdvdnav: WARNING: Unknown Command=%x\n", vm_getbits(&command, 63, 3));
- assert(0);
+ abort();
}
/* Check if there are bits not yet examined */
@@ -588,7 +586,7 @@ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *retu
/* Evaluate a set of commands in the given register set (which is modified) */
int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands,
- registers_t *registers, link_t *return_values) {
+ registers_t *registers, link_t *return_values) {
int32_t i = 0;
int32_t total = 0;
@@ -747,7 +745,7 @@ void vm_print_link(link_t value) {
break;
case JumpSS_VTSM:
fprintf(MSG_OUT, "libdvdnav: %s vts %d title %d menu %d\n",
- cmd, value.data1, value.data2, value.data3);
+ cmd, value.data1, value.data2, value.data3);
break;
case CallSS_FP:
fprintf(MSG_OUT, "libdvdnav: %s resume cell %d\n", cmd, value.data1);
diff --git a/src/vm/decoder.h b/src/vm/decoder.h
index 2fb04ae..4306d66 100644
--- a/src/vm/decoder.h
+++ b/src/vm/decoder.h
@@ -22,8 +22,6 @@
#ifndef LIBDVDNAV_DECODER_H
#define LIBDVDNAV_DECODER_H
-#include <sys/time.h>
-
/* link command types */
typedef enum {
LinkNoLink = 0,
@@ -95,7 +93,7 @@ typedef struct {
* the link where to continue, the return value indicates if a jump
* has been performed */
int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands,
- registers_t *registers, link_t *return_values);
+ registers_t *registers, link_t *return_values);
/* extracts some bits from the command */
uint32_t vm_getbits(command_t* command, int32_t start, int32_t count);
diff --git a/src/vm/getset.c b/src/vm/getset.c
deleted file mode 100644
index 26ea5fb..0000000
--- a/src/vm/getset.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Håkan Hjort
- * Copyright (C) 2001 Rich Wareham <richwareham at users.sourceforge.net>
- * 2002-2004 the dvdnav project
- *
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- *
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with libdvdnav; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <inttypes.h>
-
-#include <dvdread/nav_types.h>
-#include <dvdread/ifo_types.h>
-#include <dvdread/ifo_read.h>
-#include "dvdnav/dvdnav.h"
-
-#include "decoder.h"
-#include "remap.h"
-#include "vm.h"
-#include "getset.h"
-#include "dvdnav_internal.h"
-
-#include "getset.h"
-/* Set functions */
-
-int set_TT(vm_t *vm, int tt) {
- return set_PTT(vm, tt, 1);
-}
-
-int set_PTT(vm_t *vm, int tt, int ptt) {
- assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
- return set_VTS_PTT(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
- vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, ptt);
-}
-
-int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn) {
- return set_VTS_PTT(vm, vtsN, vts_ttn, 1);
-}
-
-int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) {
- int pgcN, pgN, res;
-
- (vm->state).domain = DVD_DOMAIN_VTSTitle;
-
- if (vtsN != (vm->state).vtsN)
- if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
- return 0;
-
- if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts) ||
- (part < 1) || (part > vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts) ) {
- return 0;
- }
-
- pgcN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn;
- pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn;
-
- (vm->state).TT_PGCN_REG = pgcN;
- (vm->state).PTTN_REG = part;
- (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
- if( (vm->state.TTN_REG) == 0 )
- return 0;
-
- (vm->state).VTS_TTN_REG = vts_ttn;
- (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
- /* Any other registers? */
-
- res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
- (vm->state).pgN = pgN;
- return res;
-}
-
-int set_PROG(vm_t *vm, int tt, int pgcn, int pgn) {
- assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
- return set_VTS_PROG(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
- vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, pgcn, pgn);
-}
-
-int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn) {
- int pgcN, pgN, res, title, part = 0;
-
- (vm->state).domain = DVD_DOMAIN_VTSTitle;
-
- if (vtsN != (vm->state).vtsN)
- if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
- return 0;
-
- if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts)) {
- return 0;
- }
-
- pgcN = pgcn;
- pgN = pgn;
-
- (vm->state).TT_PGCN_REG = pgcN;
- (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
- assert( (vm->state.TTN_REG) != 0 );
- (vm->state).VTS_TTN_REG = vts_ttn;
- (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
- /* Any other registers? */
-
- res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
- (vm->state).pgN = pgN;
- vm_get_current_title_part(vm, &title, &part);
- (vm->state).PTTN_REG = part;
- return res;
-}
-
-int set_FP_PGC(vm_t *vm) {
- (vm->state).domain = DVD_DOMAIN_FirstPlay;
- if (!vm->vmgi->first_play_pgc) {
- return set_PGCN(vm, 1);
- }
- (vm->state).pgc = vm->vmgi->first_play_pgc;
- (vm->state).pgcN = vm->vmgi->vmgi_mat->first_play_pgc;
- return 1;
-}
-
-
-int set_MENU(vm_t *vm, int menu) {
- assert((vm->state).domain == DVD_DOMAIN_VMGM || (vm->state).domain == DVD_DOMAIN_VTSMenu);
- return set_PGCN(vm, get_ID(vm, menu));
-}
-
-int set_PGCN(vm_t *vm, int pgcN) {
- pgcit_t *pgcit;
-
- pgcit = get_PGCIT(vm);
- if (pgcit == NULL)
- return 0;
-
- if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: ** No such pgcN = %d\n", pgcN);
-#endif
- return 0;
- }
-
- (vm->state).pgc = pgcit->pgci_srp[pgcN - 1].pgc;
- (vm->state).pgcN = pgcN;
- (vm->state).pgN = 1;
-
- if((vm->state).domain == DVD_DOMAIN_VTSTitle)
- (vm->state).TT_PGCN_REG = pgcN;
-
- return 1;
-}
-
-/* Figure out the correct pgN from the cell and update (vm->state). */
-int set_PGN(vm_t *vm) {
- int new_pgN = 0;
- int dummy, part = 0;
-
- while(new_pgN < (vm->state).pgc->nr_of_programs
- && (vm->state).cellN >= (vm->state).pgc->program_map[new_pgN])
- new_pgN++;
-
- if(new_pgN == (vm->state).pgc->nr_of_programs) /* We are at the last program */
- if((vm->state).cellN > (vm->state).pgc->nr_of_cells)
- return 0; /* We are past the last cell */
-
- (vm->state).pgN = new_pgN;
-
- if((vm->state).domain == DVD_DOMAIN_VTSTitle) {
- if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
- return 0; /* ?? */
-
- vm_get_current_title_part(vm, &dummy, &part);
- (vm->state).PTTN_REG = part;
- }
- return 1;
-}
-
-/* Must be called before domain is changed (set_PGCN()) */
-void set_RSMinfo(vm_t *vm, int cellN, int blockN) {
- int i;
-
- if(cellN) {
- (vm->state).rsm_cellN = cellN;
- (vm->state).rsm_blockN = blockN;
- } else {
- (vm->state).rsm_cellN = (vm->state).cellN;
- (vm->state).rsm_blockN = blockN;
- }
- (vm->state).rsm_vtsN = (vm->state).vtsN;
- (vm->state).rsm_pgcN = get_PGCN(vm);
-
- /* assert((vm->state).rsm_pgcN == (vm->state).TT_PGCN_REG); for DVD_DOMAIN_VTSTitle */
-
- for(i = 0; i < 5; i++) {
- (vm->state).rsm_regs[i] = (vm->state).registers.SPRM[4 + i];
- }
-}
-
-/* Get functions */
-
-/* Searches the TT tables, to find the current TT.
- * returns the current TT.
- * returns 0 if not found.
- */
-int get_TT(vm_t *vm, int vtsN, int vts_ttn) {
- int i;
- int tt=0;
-
- for(i = 1; i <= vm->vmgi->tt_srpt->nr_of_srpts; i++) {
- if( vm->vmgi->tt_srpt->title[i - 1].title_set_nr == vtsN &&
- vm->vmgi->tt_srpt->title[i - 1].vts_ttn == vts_ttn) {
- tt=i;
- break;
- }
- }
- return tt;
-}
-
-/* Search for entry_id match of the PGC Category in the current VTS PGCIT table.
- * Return pgcN based on entry_id match.
- */
-int get_ID(vm_t *vm, int id) {
- int pgcN, i;
- pgcit_t *pgcit;
-
- /* Relies on state to get the correct pgcit. */
- pgcit = get_PGCIT(vm);
- assert(pgcit != NULL);
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: ** Searching for menu (0x%x) entry PGC\n", id);
-#endif
-
- /* Force high bit set. */
- id |=0x80;
-
- /* Get menu/title */
- for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
- if( (pgcit->pgci_srp[i].entry_id) == id) {
- pgcN = i + 1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: Found menu.\n");
-#endif
- return pgcN;
- }
- }
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: ** No such id/menu (0x%02x) entry PGC\n", id & 0x7f);
- for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
- if ( (pgcit->pgci_srp[i].entry_id & 0x80) == 0x80) {
- fprintf(MSG_OUT, "libdvdnav: Available menus: 0x%x\n",
- pgcit->pgci_srp[i].entry_id & 0x7f);
- }
- }
-#endif
- return 0; /* error */
-}
-
-/* FIXME: we have a pgcN member in the vm's state now, so this should be obsolete */
-int get_PGCN(vm_t *vm) {
- pgcit_t *pgcit;
- int pgcN = 1;
-
- pgcit = get_PGCIT(vm);
-
- if (pgcit) {
- while(pgcN <= pgcit->nr_of_pgci_srp) {
- if(pgcit->pgci_srp[pgcN - 1].pgc == (vm->state).pgc) {
- assert((vm->state).pgcN == pgcN);
- return pgcN;
- }
- pgcN++;
- }
- }
- fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n",
- (vm->state).domain);
- return 0; /* error */
-}
-
-pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang) {
- int i;
-
- if(h == NULL || h->pgci_ut == NULL) {
- fprintf(MSG_OUT, "libdvdnav: *** pgci_ut handle is NULL ***\n");
- return NULL; /* error? */
- }
-
- i = 0;
- while(i < h->pgci_ut->nr_of_lus
- && h->pgci_ut->lu[i].lang_code != lang)
- i++;
- if(i == h->pgci_ut->nr_of_lus) {
- fprintf(MSG_OUT, "libdvdnav: Language '%c%c' not found, using '%c%c' instead\n",
- (char)(lang >> 8), (char)(lang & 0xff),
- (char)(h->pgci_ut->lu[0].lang_code >> 8),
- (char)(h->pgci_ut->lu[0].lang_code & 0xff));
- fprintf(MSG_OUT, "libdvdnav: Menu Languages available: ");
- for(i = 0; i < h->pgci_ut->nr_of_lus; i++) {
- fprintf(MSG_OUT, "%c%c ",
- (char)(h->pgci_ut->lu[i].lang_code >> 8),
- (char)(h->pgci_ut->lu[i].lang_code & 0xff));
- }
- fprintf(MSG_OUT, "\n");
- i = 0; /* error? */
- }
-
- return h->pgci_ut->lu[i].pgcit;
-}
-
-/* Uses state to decide what to return */
-pgcit_t* get_PGCIT(vm_t *vm) {
- pgcit_t *pgcit = NULL;
-
- switch ((vm->state).domain) {
- case DVD_DOMAIN_VTSTitle:
- if(!vm->vtsi) return NULL;
- pgcit = vm->vtsi->vts_pgcit;
- break;
- case DVD_DOMAIN_VTSMenu:
- if(!vm->vtsi) return NULL;
- pgcit = get_MENU_PGCIT(vm, vm->vtsi, (vm->state).registers.SPRM[0]);
- break;
- case DVD_DOMAIN_VMGM:
- case DVD_DOMAIN_FirstPlay:
- pgcit = get_MENU_PGCIT(vm, vm->vmgi, (vm->state).registers.SPRM[0]);
- break;
- default:
- abort();
- }
-
- return pgcit;
-}
-
diff --git a/src/vm/getset.h b/src/vm/getset.h
deleted file mode 100644
index da2d53e..0000000
--- a/src/vm/getset.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Håkan Hjort
- * Copyright (C) 2001 Rich Wareham <richwareham at users.sourceforge.net>
- * 2002-2004 the dvdnav project
- *
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- *
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with libdvdnav; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* get_XYZ returns a value.
- * set_XYZ sets state using passed parameters.
- * returns success/failure.
- */
-
-/* Set */
-int set_TT(vm_t *vm, int tt);
-int set_PTT(vm_t *vm, int tt, int ptt);
-int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn);
-int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part);
-int set_PROG(vm_t *vm, int tt, int pgcn, int pgn);
-int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn);
-int set_FP_PGC(vm_t *vm);
-int set_MENU(vm_t *vm, int menu);
-int set_PGCN(vm_t *vm, int pgcN);
-int set_PGN(vm_t *vm); /* Set PGN based on (vm->state).CellN */
-void set_RSMinfo(vm_t *vm, int cellN, int blockN);
-
-/* Get */
-int get_TT(vm_t *vm, int vtsN, int vts_ttn);
-int get_ID(vm_t *vm, int id);
-int get_PGCN(vm_t *vm);
-
-pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
-pgcit_t* get_PGCIT(vm_t *vm);
-
diff --git a/src/vm/play.c b/src/vm/play.c
deleted file mode 100644
index 03d76f7..0000000
--- a/src/vm/play.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Håkan Hjort
- * Copyright (C) 2001 Rich Wareham <richwareham at users.sourceforge.net>
- * 2002-2004 the dvdnav project
- *
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- *
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with libdvdnav; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <dvdread/nav_types.h>
-#include <dvdread/ifo_types.h>
-#include <dvdread/ifo_read.h>
-#include "dvdnav/dvdnav.h"
-
-#include "decoder.h"
-#include "remap.h"
-#include "vm.h"
-#include "play.h"
-#include "vm/getset.h"
-
-#include "dvdnav_internal.h"
-
-/* Playback control */
-
-link_t play_PGC(vm_t *vm) {
- link_t link_values;
-
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: play_PGC:");
- if((vm->state).domain != FP_DOMAIN) {
- fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm));
- } else {
- fprintf(MSG_OUT, " first_play_pgc\n");
- }
-#endif
-
- /* This must be set before the pre-commands are executed because they
- * might contain a CallSS that will save resume state */
-
- /* FIXME: This may be only a temporary fix for something... */
- (vm->state).pgN = 1;
- (vm->state).cellN = 0;
- (vm->state).blockN = 0;
-
- /* eval -> updates the state and returns either
- - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- - just play video i.e first PG
- (This is what happens if you fall of the end of the pre_cmds)
- - or an error (are there more cases?) */
- if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) {
- if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds,
- (vm->state).pgc->command_tbl->nr_of_pre,
- &(vm->state).registers, &link_values)) {
- /* link_values contains the 'jump' return value */
- return link_values;
- } else {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n");
-#endif
- }
- }
- return play_PG(vm);
-}
-
-link_t play_PGC_PG(vm_t *vm, int pgN) {
- link_t link_values;
-
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: play_PGC_PG:");
- if((vm->state).domain != FP_DOMAIN) {
- fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm));
- } else {
- fprintf(MSG_OUT, " first_play_pgc\n");
- }
-#endif
-
- /* This must be set before the pre-commands are executed because they
- * might contain a CallSS that will save resume state */
-
- /* FIXME: This may be only a temporary fix for something... */
- (vm->state).pgN = pgN;
- (vm->state).cellN = 0;
- (vm->state).blockN = 0;
-
- /* eval -> updates the state and returns either
- - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- - just play video i.e first PG
- (This is what happens if you fall of the end of the pre_cmds)
- - or an error (are there more cases?) */
- if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) {
- if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds,
- (vm->state).pgc->command_tbl->nr_of_pre,
- &(vm->state).registers, &link_values)) {
- /* link_values contains the 'jump' return value */
- return link_values;
- } else {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n");
-#endif
- }
- }
- return play_PG(vm);
-}
-
-link_t play_PGC_post(vm_t *vm) {
- link_t link_values = { LinkNoLink, 0, 0, 0 };
-
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n");
-#endif
-
- /* eval -> updates the state and returns either
- - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- - just go to next PGC
- (This is what happens if you fall of the end of the post_cmds)
- - or an error (are there more cases?) */
- if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_post &&
- vmEval_CMD((vm->state).pgc->command_tbl->post_cmds,
- (vm->state).pgc->command_tbl->nr_of_post,
- &(vm->state).registers, &link_values)) {
- return link_values;
- }
-
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n");
-#endif
- /* Should end up in the STOP_DOMAIN if next_pgc is 0. */
- if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) {
- link_values.command = Exit;
- return link_values;
- }
- return play_PGC(vm);
-}
-
-link_t play_PG(vm_t *vm) {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i)\n", (vm->state).pgN);
-#endif
-
- assert((vm->state).pgN > 0);
- if((vm->state).pgN > (vm->state).pgc->nr_of_programs) {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i) > pgc->nr_of_programs (%i)\n",
- (vm->state).pgN, (vm->state).pgc->nr_of_programs );
-#endif
- assert((vm->state).pgN == (vm->state).pgc->nr_of_programs + 1);
- return play_PGC_post(vm);
- }
-
- (vm->state).cellN = (vm->state).pgc->program_map[(vm->state).pgN - 1];
-
- return play_Cell(vm);
-}
-
-link_t play_Cell(vm_t *vm) {
- static const link_t play_this = {PlayThis, /* Block in Cell */ 0, 0, 0};
-
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: play_Cell: (vm->state).cellN (%i)\n", (vm->state).cellN);
-#endif
-
- assert((vm->state).cellN > 0);
- if((vm->state).cellN > (vm->state).pgc->nr_of_cells) {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: (vm->state).cellN (%i) > pgc->nr_of_cells (%i)\n",
- (vm->state).cellN, (vm->state).pgc->nr_of_cells );
-#endif
- assert((vm->state).cellN == (vm->state).pgc->nr_of_cells + 1);
- return play_PGC_post(vm);
- }
-
- /* Multi angle/Interleaved */
- switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
- case 0: /* Normal */
- assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0);
- break;
- case 1: /* The first cell in the block */
- switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) {
- case 0: /* Not part of a block */
- assert(0);
- break;
- case 1: /* Angle block */
- /* Loop and check each cell instead? So we don't get outside the block? */
- (vm->state).cellN += (vm->state).AGL_REG - 1;
-#ifdef DVDNAV_STRICT
- assert((vm->state).cellN <= (vm->state).pgc->nr_of_cells);
- assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0);
- assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1);
-#else
- if (!((vm->state).cellN <= (vm->state).pgc->nr_of_cells) ||
- !((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0) ||
- !((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1)) {
- fprintf(MSG_OUT, "libdvdnav: Invalid angle block\n");
- (vm->state).cellN -= (vm->state).AGL_REG - 1;
- }
-#endif
- break;
- case 2: /* ?? */
- case 3: /* ?? */
- default:
- fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n",
- (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode,
- (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type);
- assert(0);
- }
- break;
- case 2: /* Cell in the block */
- case 3: /* Last cell in the block */
- /* These might perhaps happen for RSM or LinkC commands? */
- default:
- fprintf(MSG_OUT, "libdvdnav: Cell is in block but did not enter at first cell!\n");
- }
-
- /* Updates (vm->state).pgN and PTTN_REG */
- if(!set_PGN(vm)) {
- /* Should not happen */
- assert(0);
- return play_PGC_post(vm);
- }
- (vm->state).cell_restart++;
- (vm->state).blockN = 0;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: Cell should restart here\n");
-#endif
- return play_this;
-}
-
-link_t play_Cell_post(vm_t *vm) {
- cell_playback_t *cell;
-
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: play_Cell_post: (vm->state).cellN (%i)\n", (vm->state).cellN);
-#endif
-
- cell = &(vm->state).pgc->cell_playback[(vm->state).cellN - 1];
-
- /* Still time is already taken care of before we get called. */
-
- /* Deal with a Cell command, if any */
- if(cell->cell_cmd_nr != 0) {
- link_t link_values;
-
- if ((vm->state).pgc->command_tbl != NULL &&
- (vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr) {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: Cell command present, executing\n");
-#endif
- if(vmEval_CMD(&(vm->state).pgc->command_tbl->cell_cmds[cell->cell_cmd_nr - 1], 1,
- &(vm->state).registers, &link_values)) {
- return link_values;
- } else {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: Cell command didn't do a Jump, Link or Call\n");
-#endif
- }
- } else {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: Invalid Cell command\n");
-#endif
- }
- }
-
- /* Where to continue after playing the cell... */
- /* Multi angle/Interleaved */
- switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
- case 0: /* Normal */
- assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0);
- (vm->state).cellN++;
- break;
- case 1: /* The first cell in the block */
- case 2: /* A cell in the block */
- case 3: /* The last cell in the block */
- default:
- switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) {
- case 0: /* Not part of a block */
- assert(0);
- break;
- case 1: /* Angle block */
- /* Skip the 'other' angles */
- (vm->state).cellN++;
- while((vm->state).cellN <= (vm->state).pgc->nr_of_cells &&
- (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode >= 2) {
- (vm->state).cellN++;
- }
- break;
- case 2: /* ?? */
- case 3: /* ?? */
- default:
- fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n",
- (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode,
- (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type);
- assert(0);
- }
- break;
- }
-
- /* Figure out the correct pgN for the new cell */
- if(!set_PGN(vm)) {
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: last cell in this PGC\n");
-#endif
- return play_PGC_post(vm);
- }
- return play_Cell(vm);
-}
diff --git a/src/vm/play.h b/src/vm/play.h
deleted file mode 100644
index 7d76471..0000000
--- a/src/vm/play.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Håkan Hjort
- * Copyright (C) 2001 Rich Wareham <richwareham at users.sourceforge.net>
- * 2002-2004 the dvdnav project
- *
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- *
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with libdvdnav; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* Play */
-link_t play_PGC(vm_t *vm);
-link_t play_PGC_PG(vm_t *vm, int pgN);
-link_t play_PGC_post(vm_t *vm);
-link_t play_PG(vm_t *vm);
-link_t play_Cell(vm_t *vm);
-link_t play_Cell_post(vm_t *vm);
-
diff --git a/src/vm/vm.c b/src/vm/vm.c
index 6d9b6ee..9feadcd 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -45,8 +45,6 @@
#include "decoder.h"
#include "remap.h"
#include "vm.h"
-#include "play.h"
-#include "getset.h"
#include "dvdnav_internal.h"
#ifdef _MSC_VER
@@ -66,51 +64,78 @@
/* Local prototypes */
+/* get_XYZ returns a value.
+ * set_XYZ sets state using passed parameters.
+ * returns success/failure.
+ */
+
+/* Play */
+static link_t play_PGC(vm_t *vm);
+static link_t play_PGC_PG(vm_t *vm, int pgN);
+static link_t play_PGC_post(vm_t *vm);
+static link_t play_PG(vm_t *vm);
+static link_t play_Cell(vm_t *vm);
+static link_t play_Cell_post(vm_t *vm);
+
/* Process link - returns 1 if a hop has been performed */
static int process_command(vm_t *vm,link_t link_values);
-/* Helper functions */
-static void vm_close(vm_t *vm);
+/* Set */
+static int set_TT(vm_t *vm, int tt);
+static int set_PTT(vm_t *vm, int tt, int ptt);
+static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn);
+static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part);
+static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn);
+static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn);
+static int set_FP_PGC(vm_t *vm);
+static int set_MENU(vm_t *vm, int menu);
+static int set_PGCN(vm_t *vm, int pgcN);
+static int set_PGN(vm_t *vm); /* Set PGN based on (vm->state).CellN */
+static void set_RSMinfo(vm_t *vm, int cellN, int blockN);
-/* Debug functions */
+/* Get */
+static int get_TT(vm_t *vm, int vtsN, int vts_ttn);
+static int get_ID(vm_t *vm, int id);
+static int get_PGCN(vm_t *vm);
-#ifdef TRACE
-void vm_position_print(vm_t *vm, vm_position_t *position) {
- fprintf(MSG_OUT, "libdvdnav: But=%x Spu=%x Aud=%x Ang=%x Hop=%x vts=%x dom=%x cell=%x cell_restart=%x cell_start=%x still=%x block=%x\n",
- position->button,
- position->spu_channel,
- position->audio_channel,
- position->angle_channel,
- position->hop_channel,
- position->vts,
- position->domain,
- position->cell,
- position->cell_restart,
- position->cell_start,
- position->still,
- position->block);
-}
+static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
+static pgcit_t* get_PGCIT(vm_t *vm);
+
+/* Helper functions */
+
+#ifdef TRACE
static void vm_print_current_domain_state(vm_t *vm) {
- const char *domain;
-
- switch(vm->state.domain) {
- case DVD_DOMAIN_VTSTitle: domain = "Video Title"; break;
- case DVD_DOMAIN_VTSMenu: domain = "Video Title Menu"; break;
- case DVD_DOMAIN_VMGM: domain = "Video Manager Menu"; break;
- case DVD_DOMAIN_FirstPlay: domain = "First Play"; break;
- default: domain = "Unknown"; break;
+ switch((vm->state).domain) {
+ case VTS_DOMAIN:
+ fprintf(MSG_OUT, "libdvdnav: Video Title Domain: -\n");
+ break;
+
+ case VTSM_DOMAIN:
+ fprintf(MSG_OUT, "libdvdnav: Video Title Menu Domain: -\n");
+ break;
+
+ case VMGM_DOMAIN:
+ fprintf(MSG_OUT, "libdvdnav: Video Manager Menu Domain: -\n");
+ break;
+
+ case FP_DOMAIN:
+ fprintf(MSG_OUT, "libdvdnav: First Play Domain: -\n");
+ break;
+
+ default:
+ fprintf(MSG_OUT, "libdvdnav: Unknown Domain: -\n");
+ break;
}
- fprintf(MSG_OUT, "libdvdnav: %s Domain: VTS:%d PGC:%d PG:%u CELL:%u BLOCK:%u VTS_TTN:%u TTN:%u TT_PGCN:%u\n",
- domain,
- vm->state.vtsN,
+ fprintf(MSG_OUT, "libdvdnav: VTS:%d PGC:%d PG:%u CELL:%u BLOCK:%u VTS_TTN:%u TTN:%u TT_PGCN:%u\n",
+ (vm->state).vtsN,
get_PGCN(vm),
- vm->state.pgN,
- vm->state.cellN,
- vm->state.blockN,
- vm->state.VTS_TTN_REG,
- vm->state.TTN_REG,
- vm->state.TT_PGCN_REG);
+ (vm->state).pgN,
+ (vm->state).cellN,
+ (vm->state).blockN,
+ (vm->state).VTS_TTN_REG,
+ (vm->state).TTN_REG,
+ (vm->state).TT_PGCN_REG);
}
#endif
@@ -137,90 +162,67 @@ static int os2_open(const char *name, int oflag)
}
#endif
-static int dvd_read_name(char *name, char *serial, const char *device) {
- /* Because we are compiling with _FILE_OFFSET_BITS=64
- * all off_t are 64bit.
- */
- off_t off;
- ssize_t read_size = 0;
- int fd = -1, i;
- uint8_t data[DVD_VIDEO_LB_LEN];
-
- /* Read DVD name */
- if (device == NULL) {
- fprintf(MSG_OUT, "libdvdnav: Device name string NULL\n");
- goto fail;
- }
- if ((fd = open(device, O_RDONLY)) == -1) {
- fprintf(MSG_OUT, "libdvdnav: Unable to open device file %s.\n", device);
- goto fail;
- }
-
- if ((off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET )) == (off_t) - 1) {
- fprintf(MSG_OUT, "libdvdnav: Unable to seek to the title block %u.\n", 32);
- goto fail;
- }
-
- if( off != ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) {
- fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 );
- goto fail;
- }
-
- if ((read_size = read( fd, data, DVD_VIDEO_LB_LEN )) == -1) {
- fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
- goto fail;
- }
-
- close(fd);
- fd = -1;
- if (read_size != DVD_VIDEO_LB_LEN) {
- fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
- goto fail;
- }
-
- fprintf(MSG_OUT, "libdvdnav: DVD Title: ");
- for(i=25; i < 73; i++ ) {
- if((data[i] == 0)) break;
- if((data[i] > 32) && (data[i] < 127)) {
- fprintf(MSG_OUT, "%c", data[i]);
- } else {
- fprintf(MSG_OUT, " ");
- }
- }
- strncpy(name, (char*) &data[25], 48);
- name[48] = 0;
- fprintf(MSG_OUT, "\nlibdvdnav: DVD Serial Number: ");
- for(i=73; i < 89; i++ ) {
- if((data[i] == 0)) break;
- if((data[i] > 32) && (data[i] < 127)) {
- fprintf(MSG_OUT, "%c", data[i]);
- } else {
- fprintf(MSG_OUT, " ");
- }
- }
- strncpy(serial, (char*) &data[73], 14);
- serial[14] = 0;
- fprintf(MSG_OUT, "\nlibdvdnav: DVD Title (Alternative): ");
- for(i=89; i < 128; i++ ) {
- if((data[i] == 0)) break;
- if((data[i] > 32) && (data[i] < 127)) {
- fprintf(MSG_OUT, "%c", data[i]);
+static void dvd_read_name(char *name, char *serial, const char *device) {
+ /* Because we are compiling with _FILE_OFFSET_BITS=64
+ * all off_t are 64bit.
+ */
+ off_t off;
+ int fd, i;
+ uint8_t data[DVD_VIDEO_LB_LEN];
+
+ /* Read DVD name */
+ fd = open(device, O_RDONLY);
+ if (fd > 0) {
+ off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET );
+ if( off == ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) {
+ off = read( fd, data, DVD_VIDEO_LB_LEN );
+ if (off == ( (off_t) DVD_VIDEO_LB_LEN )) {
+ fprintf(MSG_OUT, "libdvdnav: DVD Title: ");
+ for(i=25; i < 73; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(MSG_OUT, "%c", data[i]);
+ } else {
+ fprintf(MSG_OUT, " ");
+ }
+ }
+ strncpy(name, (char*) &data[25], 48);
+ name[48] = 0;
+ fprintf(MSG_OUT, "\nlibdvdnav: DVD Serial Number: ");
+ for(i=73; i < 89; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(MSG_OUT, "%c", data[i]);
+ } else {
+ fprintf(MSG_OUT, " ");
+ }
+ }
+ strncpy(serial, (char*) &data[73], (i-73));
+ serial[14] = 0;
+ fprintf(MSG_OUT, "\nlibdvdnav: DVD Title (Alternative): ");
+ for(i=89; i < 128; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(MSG_OUT, "%c", data[i]);
+ } else {
+ fprintf(MSG_OUT, " ");
+ }
+ }
+ fprintf(MSG_OUT, "\n");
+ } else {
+ fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
+ }
+ } else {
+ fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 );
+ }
+ close(fd);
} else {
- fprintf(MSG_OUT, " ");
- }
+ fprintf(MSG_OUT, "NAME OPEN FAILED\n");
}
- fprintf(MSG_OUT, "\n");
- return 1;
-
-fail:
- if (fd >= 0)
- close(fd);
-
- return 0;
}
-int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) {
- if(vm->state.vtsN == vtsN) {
+static int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) {
+ if((vm->state).vtsN == vtsN) {
return 1; /* We alread have it */
}
@@ -252,7 +254,7 @@ int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) {
fprintf(MSG_OUT, "libdvdnav: ifoRead_TITLE_VOBU_ADMAP vtsi failed\n");
return 0;
}
- vm->state.vtsN = vtsN;
+ (vm->state).vtsN = vtsN;
return 1;
}
@@ -261,11 +263,11 @@ int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) {
/* Initialisation & Destruction */
vm_t* vm_new_vm() {
- return (vm_t*)calloc(sizeof(vm_t), sizeof(char));
+ return (vm_t*)calloc(1, sizeof(vm_t));
}
void vm_free_vm(vm_t *vm) {
- vm_close(vm);
+ vm_stop(vm);
free(vm);
}
@@ -291,12 +293,6 @@ dvd_reader_t *vm_get_dvd_reader(vm_t *vm) {
/* Basic Handling */
int vm_start(vm_t *vm) {
- if (vm->stopped) {
- if (!vm_reset(vm, NULL))
- return 0;
-
- vm->stopped = 0;
- }
/* Set pgc to FP (First Play) pgc */
set_FP_PGC(vm);
process_command(vm, play_PGC(vm));
@@ -304,10 +300,6 @@ int vm_start(vm_t *vm) {
}
void vm_stop(vm_t *vm) {
- vm->stopped = 1;
-}
-
-static void vm_close(vm_t *vm) {
if(vm->vmgi) {
ifoClose(vm->vmgi);
vm->vmgi=NULL;
@@ -325,43 +317,43 @@ static void vm_close(vm_t *vm) {
int vm_reset(vm_t *vm, const char *dvdroot) {
/* Setup State */
- memset(vm->state.registers.SPRM, 0, sizeof(vm->state.registers.SPRM));
- memset(vm->state.registers.GPRM, 0, sizeof(vm->state.registers.GPRM));
- memset(vm->state.registers.GPRM_mode, 0, sizeof(vm->state.registers.GPRM_mode));
- memset(vm->state.registers.GPRM_mode, 0, sizeof(vm->state.registers.GPRM_mode));
- memset(vm->state.registers.GPRM_time, 0, sizeof(vm->state.registers.GPRM_time));
- vm->state.registers.SPRM[0] = ('e'<<8)|'n'; /* Player Menu Languange code */
- vm->state.AST_REG = 15; /* 15 why? */
- vm->state.SPST_REG = 62; /* 62 why? */
- vm->state.AGL_REG = 1;
- vm->state.TTN_REG = 1;
- vm->state.VTS_TTN_REG = 1;
- /* vm->state.TT_PGCN_REG = 0 */
- vm->state.PTTN_REG = 1;
- vm->state.HL_BTNN_REG = 1 << 10;
- vm->state.PTL_REG = 15; /* Parental Level */
- vm->state.registers.SPRM[12] = ('U'<<8)|'S'; /* Parental Management Country Code */
- vm->state.registers.SPRM[16] = ('e'<<8)|'n'; /* Initial Language Code for Audio */
- vm->state.registers.SPRM[18] = ('e'<<8)|'n'; /* Initial Language Code for Spu */
- vm->state.registers.SPRM[20] = 0x1; /* Player Regional Code Mask. Region free! */
- vm->state.registers.SPRM[14] = 0x100; /* Try Pan&Scan */
-
- vm->state.pgN = 0;
- vm->state.cellN = 0;
- vm->state.cell_restart = 0;
-
- vm->state.domain = DVD_DOMAIN_FirstPlay;
- vm->state.rsm_vtsN = 0;
- vm->state.rsm_cellN = 0;
- vm->state.rsm_blockN = 0;
-
- vm->state.vtsN = -1;
+ memset((vm->state).registers.SPRM, 0, sizeof((vm->state).registers.SPRM));
+ memset((vm->state).registers.GPRM, 0, sizeof((vm->state).registers.GPRM));
+ memset((vm->state).registers.GPRM_mode, 0, sizeof((vm->state).registers.GPRM_mode));
+ memset((vm->state).registers.GPRM_mode, 0, sizeof((vm->state).registers.GPRM_mode));
+ memset((vm->state).registers.GPRM_time, 0, sizeof((vm->state).registers.GPRM_time));
+ (vm->state).registers.SPRM[0] = ('e'<<8)|'n'; /* Player Menu Languange code */
+ (vm->state).AST_REG = 15; /* 15 why? */
+ (vm->state).SPST_REG = 62; /* 62 why? */
+ (vm->state).AGL_REG = 1;
+ (vm->state).TTN_REG = 1;
+ (vm->state).VTS_TTN_REG = 1;
+ /* (vm->state).TT_PGCN_REG = 0 */
+ (vm->state).PTTN_REG = 1;
+ (vm->state).HL_BTNN_REG = 1 << 10;
+ (vm->state).PTL_REG = 15; /* Parental Level */
+ (vm->state).registers.SPRM[12] = ('U'<<8)|'S'; /* Parental Management Country Code */
+ (vm->state).registers.SPRM[16] = ('e'<<8)|'n'; /* Initial Language Code for Audio */
+ (vm->state).registers.SPRM[18] = ('e'<<8)|'n'; /* Initial Language Code for Spu */
+ (vm->state).registers.SPRM[20] = 0x1; /* Player Regional Code Mask. Region free! */
+ (vm->state).registers.SPRM[14] = 0x100; /* Try Pan&Scan */
+
+ (vm->state).pgN = 0;
+ (vm->state).cellN = 0;
+ (vm->state).cell_restart = 0;
+
+ (vm->state).domain = FP_DOMAIN;
+ (vm->state).rsm_vtsN = 0;
+ (vm->state).rsm_cellN = 0;
+ (vm->state).rsm_blockN = 0;
+
+ (vm->state).vtsN = -1;
vm->hop_channel = 0;
if (vm->dvd && dvdroot) {
/* a new dvd device has been requested */
- vm_close(vm);
+ vm_stop(vm);
}
if (!vm->dvd) {
vm->dvd = DVDOpen(dvdroot);
@@ -399,8 +391,8 @@ int vm_reset(vm_t *vm, const char *dvdroot) {
/* return 0; Not really used for now.. */
}
/* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */
- if (dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot) == 1)
- vm->map = remap_loadmap(vm->dvd_name);
+ dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot);
+ vm->map = remap_loadmap(vm->dvd_name);
}
if (vm->vmgi) {
int i, mask;
@@ -423,8 +415,7 @@ vm_t *vm_new_copy(vm_t *source) {
int pgcN = get_PGCN(source);
int pgN = (source->state).pgN;
- if (target == NULL || pgcN == 0)
- goto fail;
+ assert(pgcN);
memcpy(target, source, sizeof(vm_t));
@@ -434,22 +425,15 @@ vm_t *vm_new_copy(vm_t *source) {
if (vtsN > 0) {
(target->state).vtsN = 0;
if (!ifoOpenNewVTSI(target, target->dvd, vtsN))
- goto fail;
+ assert(0);
/* restore pgc pointer into the new vtsi */
if (!set_PGCN(target, pgcN))
- goto fail;
-
+ assert(0);
(target->state).pgN = pgN;
}
return target;
-
-fail:
- if (target != NULL)
- vm_free_vm(target);
-
- return NULL;
}
void vm_merge(vm_t *target, vm_t *source) {
@@ -469,22 +453,22 @@ void vm_free_copy(vm_t *vm) {
/* regular playback */
void vm_position_get(vm_t *vm, vm_position_t *position) {
- position->button = vm->state.HL_BTNN_REG >> 10;
- position->vts = vm->state.vtsN;
- position->domain = vm->state.domain;
- position->spu_channel = vm->state.SPST_REG;
- position->audio_channel = vm->state.AST_REG;
- position->angle_channel = vm->state.AGL_REG;
+ position->button = (vm->state).HL_BTNN_REG >> 10;
+ position->vts = (vm->state).vtsN;
+ position->domain = (vm->state).domain;
+ position->spu_channel = (vm->state).SPST_REG;
+ position->audio_channel = (vm->state).AST_REG;
+ position->angle_channel = (vm->state).AGL_REG;
position->hop_channel = vm->hop_channel; /* Increases by one on each hop */
- position->cell = vm->state.cellN;
- position->cell_restart = vm->state.cell_restart;
- position->cell_start = vm->state.pgc->cell_playback[vm->state.cellN - 1].first_sector;
- position->still = vm->state.pgc->cell_playback[vm->state.cellN - 1].still_time;
- position->block = vm->state.blockN;
+ position->cell = (vm->state).cellN;
+ position->cell_restart = (vm->state).cell_restart;
+ position->cell_start = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector;
+ position->still = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].still_time;
+ position->block = (vm->state).blockN;
/* handle PGC stills at PGC end */
- if (vm->state.cellN == vm->state.pgc->nr_of_cells)
- position->still += vm->state.pgc->still_time;
+ if ((vm->state).cellN == (vm->state).pgc->nr_of_cells)
+ position->still += (vm->state).pgc->still_time;
/* still already determined */
if (position->still)
return;
@@ -496,19 +480,19 @@ void vm_position_get(vm_t *vm, vm_position_t *position) {
* are equal and the cells are very short, so we abuse these conditions to
* detect such discs. I consider these discs broken, so the fix is somewhat
* broken, too. */
- if ((vm->state.pgc->cell_playback[vm->state.cellN - 1].last_sector ==
- vm->state.pgc->cell_playback[vm->state.cellN - 1].last_vobu_start_sector) &&
- (vm->state.pgc->cell_playback[vm->state.cellN - 1].last_sector -
- vm->state.pgc->cell_playback[vm->state.cellN - 1].first_sector < 1024)) {
+ if (((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector ==
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_vobu_start_sector) &&
+ ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector -
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector < 1024)) {
int time;
- int size = vm->state.pgc->cell_playback[vm->state.cellN - 1].last_sector -
- vm->state.pgc->cell_playback[vm->state.cellN - 1].first_sector;
- time = (vm->state.pgc->cell_playback[vm->state.cellN - 1].playback_time.hour >> 4 ) * 36000;
- time += (vm->state.pgc->cell_playback[vm->state.cellN - 1].playback_time.hour & 0x0f) * 3600;
- time += (vm->state.pgc->cell_playback[vm->state.cellN - 1].playback_time.minute >> 4 ) * 600;
- time += (vm->state.pgc->cell_playback[vm->state.cellN - 1].playback_time.minute & 0x0f) * 60;
- time += (vm->state.pgc->cell_playback[vm->state.cellN - 1].playback_time.second >> 4 ) * 10;
- time += (vm->state.pgc->cell_playback[vm->state.cellN - 1].playback_time.second & 0x0f) * 1;
+ int size = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector -
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector;
+ time = ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour >> 4 ) * 36000;
+ time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour & 0x0f) * 3600;
+ time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute >> 4 ) * 600;
+ time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0x0f) * 60;
+ time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second >> 4 ) * 10;
+ time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0x0f) * 1;
if (!time || size / time > 30)
/* datarate is too high, it might be a very short, but regular cell */
return;
@@ -525,17 +509,17 @@ void vm_get_next_cell(vm_t *vm) {
/* Jumping */
int vm_jump_pg(vm_t *vm, int pg) {
- vm->state.pgN = pg;
+ (vm->state).pgN = pg;
process_command(vm, play_PG(vm));
return 1;
}
int vm_jump_cell_block(vm_t *vm, int cell, int block) {
- vm->state.cellN = cell;
+ (vm->state).cellN = cell;
process_command(vm, play_Cell(vm));
/* play_Cell can jump to a different cell in case of angles */
- if (vm->state.cellN == cell)
- vm->state.blockN = block;
+ if ((vm->state).cellN == cell)
+ (vm->state).blockN = block;
return 1;
}
@@ -547,8 +531,8 @@ int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn) {
/* Some DVDs do not want us to jump directly into a title and have
* PGC pre commands taking us back to some menu. Since we do not like that,
* we do not execute PGC pre commands that would do a jump. */
- /* process_command(vm, play_PGC_PG(vm, vm->state.pgN)); */
- link = play_PGC_PG(vm, vm->state.pgN);
+ /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */
+ link = play_PGC_PG(vm, (vm->state).pgN);
if (link.command != PlayThis)
/* jump occured -> ignore it and play the PG anyway */
process_command(vm, play_PG(vm));
@@ -565,8 +549,8 @@ int vm_jump_title_part(vm_t *vm, int title, int part) {
/* Some DVDs do not want us to jump directly into a title and have
* PGC pre commands taking us back to some menu. Since we do not like that,
* we do not execute PGC pre commands that would do a jump. */
- /* process_command(vm, play_PGC_PG(vm, vm->state.pgN)); */
- link = play_PGC_PG(vm, vm->state.pgN);
+ /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */
+ link = play_PGC_PG(vm, (vm->state).pgN);
if (link.command != PlayThis)
/* jump occured -> ignore it and play the PG anyway */
process_command(vm, play_PG(vm));
@@ -581,33 +565,33 @@ int vm_jump_top_pg(vm_t *vm) {
}
int vm_jump_next_pg(vm_t *vm) {
- if(vm->state.pgN >= vm->state.pgc->nr_of_programs) {
+ if((vm->state).pgN >= (vm->state).pgc->nr_of_programs) {
/* last program -> move to TailPGC */
process_command(vm, play_PGC_post(vm));
return 1;
} else {
- vm_jump_pg(vm, vm->state.pgN + 1);
+ vm_jump_pg(vm, (vm->state).pgN + 1);
return 1;
}
}
int vm_jump_prev_pg(vm_t *vm) {
- if (vm->state.pgN <= 1) {
+ if ((vm->state).pgN <= 1) {
/* first program -> move to last program of previous PGC */
- if (vm->state.pgc->prev_pgc_nr && set_PGCN(vm, vm->state.pgc->prev_pgc_nr)) {
+ if ((vm->state).pgc->prev_pgc_nr && set_PGCN(vm, (vm->state).pgc->prev_pgc_nr)) {
process_command(vm, play_PGC(vm));
- vm_jump_pg(vm, vm->state.pgc->nr_of_programs);
+ vm_jump_pg(vm, (vm->state).pgc->nr_of_programs);
return 1;
}
return 0;
} else {
- vm_jump_pg(vm, vm->state.pgN - 1);
+ vm_jump_pg(vm, (vm->state).pgN - 1);
return 1;
}
}
int vm_jump_up(vm_t *vm) {
- if(vm->state.pgc->goup_pgc_nr && set_PGCN(vm, vm->state.pgc->goup_pgc_nr)) {
+ if((vm->state).pgc->goup_pgc_nr && set_PGCN(vm, (vm->state).pgc->goup_pgc_nr)) {
process_command(vm, play_PGC(vm));
return 1;
}
@@ -615,38 +599,41 @@ int vm_jump_up(vm_t *vm) {
}
int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid) {
- DVDDomain_t old_domain = vm->state.domain;
+ domain_t old_domain = (vm->state).domain;
- switch (vm->state.domain) {
- case DVD_DOMAIN_FirstPlay: /* FIXME XXX $$$ What should we do here? */
- break;
- case DVD_DOMAIN_VTSTitle:
- set_RSMinfo(vm, 0, vm->state.blockN);
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ set_RSMinfo(vm, 0, (vm->state).blockN);
/* FALL THROUGH */
- case DVD_DOMAIN_VTSMenu:
- case DVD_DOMAIN_VMGM:
+ case VTSM_DOMAIN:
+ case VMGM_DOMAIN:
switch(menuid) {
case DVD_MENU_Title:
case DVD_MENU_Escape:
- if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL)
+ if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
return 0;
- vm->state.domain = DVD_DOMAIN_VMGM;
+ }
+ (vm->state).domain = VMGM_DOMAIN;
break;
case DVD_MENU_Root:
case DVD_MENU_Subpicture:
case DVD_MENU_Audio:
case DVD_MENU_Angle:
case DVD_MENU_Part:
- if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL)
+ if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
return 0;
- vm->state.domain = DVD_DOMAIN_VTSMenu;
+ }
+ (vm->state).domain = VTSM_DOMAIN;
break;
}
if(get_PGCIT(vm) && set_MENU(vm, menuid)) {
process_command(vm, play_PGC(vm));
return 1; /* Jump */
- } else
- vm->state.domain = old_domain;
+ } else {
+ (vm->state).domain = old_domain;
+ }
+ break;
+ case FP_DOMAIN: /* FIXME XXX $$$ What should we do here? */
break;
}
@@ -656,20 +643,625 @@ int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid) {
int vm_jump_resume(vm_t *vm) {
link_t link_values = { LinkRSM, 0, 0, 0 };
- if (!vm->state.rsm_vtsN) /* Do we have resume info? */
+ if (!(vm->state).rsm_vtsN) /* Do we have resume info? */
+ return 0;
+ if (!process_command(vm, link_values))
return 0;
- return !!process_command(vm, link_values);
+ return 1;
}
int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd) {
link_t link_values;
- if(vmEval_CMD(cmd, 1, &vm->state.registers, &link_values))
+ if(vmEval_CMD(cmd, 1, &(vm->state).registers, &link_values))
return process_command(vm, link_values);
else
return 0; /* It updated some state thats all... */
}
+
+/* getting information */
+
+int vm_get_current_menu(vm_t *vm, int *menuid) {
+ pgcit_t* pgcit;
+ int pgcn;
+ pgcn = (vm->state).pgcN;
+ pgcit = get_PGCIT(vm);
+ if(pgcit==NULL) return 0;
+ *menuid = pgcit->pgci_srp[pgcn - 1].entry_id & 0xf ;
+ return 1;
+}
+
+int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) {
+ vts_ptt_srpt_t *vts_ptt_srpt;
+ int title, part = 0, vts_ttn;
+ int found;
+ int16_t pgcN, pgN;
+
+ vts_ptt_srpt = vm->vtsi->vts_ptt_srpt;
+ pgcN = get_PGCN(vm);
+ pgN = vm->state.pgN;
+
+ found = 0;
+ for (vts_ttn = 0; (vts_ttn < vts_ptt_srpt->nr_of_srpts) && !found; vts_ttn++) {
+ for (part = 0; (part < vts_ptt_srpt->title[vts_ttn].nr_of_ptts) && !found; part++) {
+ if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgcn == pgcN) {
+ if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn == pgN) {
+ found = 1;
+ break;
+ }
+ if (part > 0 && vts_ptt_srpt->title[vts_ttn].ptt[part].pgn > pgN &&
+ vts_ptt_srpt->title[vts_ttn].ptt[part - 1].pgn < pgN) {
+ part--;
+ found = 1;
+ break;
+ }
+ }
+ }
+ if (found) break;
+ }
+ vts_ttn++;
+ part++;
+
+ if (!found) {
+ fprintf(MSG_OUT, "libdvdnav: chapter NOT FOUND!\n");
+ return 0;
+ }
+
+ title = get_TT(vm, vm->state.vtsN, vts_ttn);
+
+#ifdef TRACE
+ if (title) {
+ fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n");
+ fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
+ title, part,
+ vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgcn ,
+ vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgn );
+ }
+#endif
+ *title_result = title;
+ *part_result = part;
+ return 1;
+}
+
+/* Return the substream id for 'logical' audio stream audioN.
+ * 0 <= audioN < 8
+ */
+int vm_get_audio_stream(vm_t *vm, int audioN) {
+ int streamN = -1;
+
+ if((vm->state).domain != VTS_DOMAIN)
+ audioN = 0;
+
+ if(audioN < 8) {
+ /* Is there any control info for this logical stream */
+ if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
+ streamN = ((vm->state).pgc->audio_control[audioN] >> 8) & 0x07;
+ }
+ }
+
+ if((vm->state).domain != VTS_DOMAIN && streamN == -1)
+ streamN = 0;
+
+ /* FIXME: Should also check in vtsi/vmgi status what kind of stream
+ * it is (ac3/lpcm/dts/sdds...) to find the right (sub)stream id */
+ return streamN;
+}
+
+/* Return the substream id for 'logical' subpicture stream subpN and given mode.
+ * 0 <= subpN < 32
+ * mode == 0 - widescreen
+ * mode == 1 - letterbox
+ * mode == 2 - pan&scan
+ */
+int vm_get_subp_stream(vm_t *vm, int subpN, int mode) {
+ int streamN = -1;
+ int source_aspect = vm_get_video_aspect(vm);
+
+ if((vm->state).domain != VTS_DOMAIN)
+ subpN = 0;
+
+ if(subpN < 32) { /* a valid logical stream */
+ /* Is this logical stream present */
+ if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
+ if(source_aspect == 0) /* 4:3 */
+ streamN = ((vm->state).pgc->subp_control[subpN] >> 24) & 0x1f;
+ if(source_aspect == 3) /* 16:9 */
+ switch (mode) {
+ case 0:
+ streamN = ((vm->state).pgc->subp_control[subpN] >> 16) & 0x1f;
+ break;
+ case 1:
+ streamN = ((vm->state).pgc->subp_control[subpN] >> 8) & 0x1f;
+ break;
+ case 2:
+ streamN = (vm->state).pgc->subp_control[subpN] & 0x1f;
+ }
+ }
+ }
+
+ if((vm->state).domain != VTS_DOMAIN && streamN == -1)
+ streamN = 0;
+
+ /* FIXME: Should also check in vtsi/vmgi status what kind of stream it is. */
+ return streamN;
+}
+
+int vm_get_audio_active_stream(vm_t *vm) {
+ int audioN;
+ int streamN;
+ audioN = (vm->state).AST_REG ;
+ streamN = vm_get_audio_stream(vm, audioN);
+
+ /* If no such stream, then select the first one that exists. */
+ if(streamN == -1) {
+ for(audioN = 0; audioN < 8; audioN++) {
+ if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
+ if ((streamN = vm_get_audio_stream(vm, audioN)) >= 0)
+ break;
+ }
+ }
+ }
+
+ return streamN;
+}
+
+int vm_get_subp_active_stream(vm_t *vm, int mode) {
+ int subpN;
+ int streamN;
+ subpN = (vm->state).SPST_REG & ~0x40;
+ streamN = vm_get_subp_stream(vm, subpN, mode);
+
+ /* If no such stream, then select the first one that exists. */
+ if(streamN == -1) {
+ for(subpN = 0; subpN < 32; subpN++) {
+ if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
+ if ((streamN = vm_get_subp_stream(vm, subpN, mode)) >= 0)
+ break;
+ }
+ }
+ }
+
+ if((vm->state).domain == VTS_DOMAIN && !((vm->state).SPST_REG & 0x40))
+ /* Bit 7 set means hide, and only let Forced display show */
+ return (streamN | 0x80);
+ else
+ return streamN;
+}
+
+void vm_get_angle_info(vm_t *vm, int *current, int *num_avail) {
+ *num_avail = 1;
+ *current = 1;
+
+ if((vm->state).domain == VTS_DOMAIN) {
+ title_info_t *title;
+ /* TTN_REG does not allways point to the correct title.. */
+ if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
+ return;
+ title = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1];
+ if(title->title_set_nr != (vm->state).vtsN ||
+ title->vts_ttn != (vm->state).VTS_TTN_REG)
+ return;
+ *num_avail = title->nr_of_angles;
+ *current = (vm->state).AGL_REG;
+ }
+}
+
+#if 0
+/* currently unused */
+void vm_get_audio_info(vm_t *vm, int *current, int *num_avail) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ *num_avail = vm->vtsi->vtsi_mat->nr_of_vts_audio_streams;
+ *current = (vm->state).AST_REG;
+ break;
+ case VTSM_DOMAIN:
+ *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_audio_streams; /* 1 */
+ *current = 1;
+ break;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_audio_streams; /* 1 */
+ *current = 1;
+ break;
+ }
+}
+
+/* currently unused */
+void vm_get_subp_info(vm_t *vm, int *current, int *num_avail) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ *num_avail = vm->vtsi->vtsi_mat->nr_of_vts_subp_streams;
+ *current = (vm->state).SPST_REG;
+ break;
+ case VTSM_DOMAIN:
+ *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_subp_streams; /* 1 */
+ *current = 0x41;
+ break;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_subp_streams; /* 1 */
+ *current = 0x41;
+ break;
+ }
+}
+#endif
+
+void vm_get_video_res(vm_t *vm, int *width, int *height) {
+ video_attr_t attr = vm_get_video_attr(vm);
+
+ if(attr.video_format != 0)
+ *height = 576;
+ else
+ *height = 480;
+ switch(attr.picture_size) {
+ case 0:
+ *width = 720;
+ break;
+ case 1:
+ *width = 704;
+ break;
+ case 2:
+ *width = 352;
+ break;
+ case 3:
+ *width = 352;
+ *height /= 2;
+ break;
+ }
+}
+
+int vm_get_video_aspect(vm_t *vm) {
+ int aspect = vm_get_video_attr(vm).display_aspect_ratio;
+
+ assert(aspect == 0 || aspect == 3);
+ (vm->state).registers.SPRM[14] &= ~(0x3 << 10);
+ (vm->state).registers.SPRM[14] |= aspect << 10;
+
+ return aspect;
+}
+
+int vm_get_video_scale_permission(vm_t *vm) {
+ return vm_get_video_attr(vm).permitted_df;
+}
+
+video_attr_t vm_get_video_attr(vm_t *vm) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ return vm->vtsi->vtsi_mat->vts_video_attr;
+ case VTSM_DOMAIN:
+ return vm->vtsi->vtsi_mat->vtsm_video_attr;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ return vm->vmgi->vmgi_mat->vmgm_video_attr;
+ default:
+ abort();
+ }
+}
+
+audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ return vm->vtsi->vtsi_mat->vts_audio_attr[streamN];
+ case VTSM_DOMAIN:
+ return vm->vtsi->vtsi_mat->vtsm_audio_attr;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ return vm->vmgi->vmgi_mat->vmgm_audio_attr;
+ default:
+ abort();
+ }
+}
+
+subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ return vm->vtsi->vtsi_mat->vts_subp_attr[streamN];
+ case VTSM_DOMAIN:
+ return vm->vtsi->vtsi_mat->vtsm_subp_attr;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ return vm->vmgi->vmgi_mat->vmgm_subp_attr;
+ default:
+ abort();
+ }
+}
+
+
+/* Playback control */
+
+static link_t play_PGC(vm_t *vm) {
+ link_t link_values;
+
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: play_PGC:");
+ if((vm->state).domain != FP_DOMAIN) {
+ fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm));
+ } else {
+ fprintf(MSG_OUT, " first_play_pgc\n");
+ }
+#endif
+
+ /* This must be set before the pre-commands are executed because they
+ * might contain a CallSS that will save resume state */
+
+ /* FIXME: This may be only a temporary fix for something... */
+ (vm->state).pgN = 1;
+ (vm->state).cellN = 0;
+ (vm->state).blockN = 0;
+
+ /* eval -> updates the state and returns either
+ - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
+ - just play video i.e first PG
+ (This is what happens if you fall of the end of the pre_cmds)
+ - or an error (are there more cases?) */
+ if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) {
+ if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds,
+ (vm->state).pgc->command_tbl->nr_of_pre,
+ &(vm->state).registers, &link_values)) {
+ /* link_values contains the 'jump' return value */
+ return link_values;
+ } else {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n");
+#endif
+ }
+ }
+ return play_PG(vm);
+}
+
+static link_t play_PGC_PG(vm_t *vm, int pgN) {
+ link_t link_values;
+
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: play_PGC_PG:");
+ if((vm->state).domain != FP_DOMAIN) {
+ fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm));
+ } else {
+ fprintf(MSG_OUT, " first_play_pgc\n");
+ }
+#endif
+
+ /* This must be set before the pre-commands are executed because they
+ * might contain a CallSS that will save resume state */
+
+ /* FIXME: This may be only a temporary fix for something... */
+ (vm->state).pgN = pgN;
+ (vm->state).cellN = 0;
+ (vm->state).blockN = 0;
+
+ /* eval -> updates the state and returns either
+ - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
+ - just play video i.e first PG
+ (This is what happens if you fall of the end of the pre_cmds)
+ - or an error (are there more cases?) */
+ if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) {
+ if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds,
+ (vm->state).pgc->command_tbl->nr_of_pre,
+ &(vm->state).registers, &link_values)) {
+ /* link_values contains the 'jump' return value */
+ return link_values;
+ } else {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n");
+#endif
+ }
+ }
+ return play_PG(vm);
+}
+
+static link_t play_PGC_post(vm_t *vm) {
+ link_t link_values;
+
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n");
+#endif
+
+ /* eval -> updates the state and returns either
+ - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
+ - just go to next PGC
+ (This is what happens if you fall of the end of the post_cmds)
+ - or an error (are there more cases?) */
+ if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_post &&
+ vmEval_CMD((vm->state).pgc->command_tbl->post_cmds,
+ (vm->state).pgc->command_tbl->nr_of_post,
+ &(vm->state).registers, &link_values)) {
+ return link_values;
+ }
+
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n");
+#endif
+ /* Should end up in the STOP_DOMAIN if next_pgc is 0. */
+ if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) {
+ link_values.command = Exit;
+ return link_values;
+ }
+ return play_PGC(vm);
+}
+
+static link_t play_PG(vm_t *vm) {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i)\n", (vm->state).pgN);
+#endif
+
+ assert((vm->state).pgN > 0);
+ if((vm->state).pgN > (vm->state).pgc->nr_of_programs) {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i) > pgc->nr_of_programs (%i)\n",
+ (vm->state).pgN, (vm->state).pgc->nr_of_programs );
+#endif
+ assert((vm->state).pgN == (vm->state).pgc->nr_of_programs + 1);
+ return play_PGC_post(vm);
+ }
+
+ (vm->state).cellN = (vm->state).pgc->program_map[(vm->state).pgN - 1];
+
+ return play_Cell(vm);
+}
+
+static link_t play_Cell(vm_t *vm) {
+ static const link_t play_this = {PlayThis, /* Block in Cell */ 0, 0, 0};
+
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: play_Cell: (vm->state).cellN (%i)\n", (vm->state).cellN);
+#endif
+
+ assert((vm->state).cellN > 0);
+ if((vm->state).cellN > (vm->state).pgc->nr_of_cells) {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: (vm->state).cellN (%i) > pgc->nr_of_cells (%i)\n",
+ (vm->state).cellN, (vm->state).pgc->nr_of_cells );
+#endif
+ assert((vm->state).cellN == (vm->state).pgc->nr_of_cells + 1);
+ return play_PGC_post(vm);
+ }
+
+ /* Multi angle/Interleaved */
+ switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
+ case 0: /* Normal */
+ assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0);
+ break;
+ case 1: /* The first cell in the block */
+ switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) {
+ case 0: /* Not part of a block */
+ assert(0);
+ break;
+ case 1: /* Angle block */
+ /* Loop and check each cell instead? So we don't get outside the block? */
+ (vm->state).cellN += (vm->state).AGL_REG - 1;
+#ifdef DVDNAV_STRICT
+ assert((vm->state).cellN <= (vm->state).pgc->nr_of_cells);
+ assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0);
+ assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1);
+#else
+ if (!((vm->state).cellN <= (vm->state).pgc->nr_of_cells) ||
+ !((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0) ||
+ !((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1)) {
+ fprintf(MSG_OUT, "libdvdnav: Invalid angle block\n");
+ (vm->state).cellN -= (vm->state).AGL_REG - 1;
+ }
+#endif
+ break;
+ case 2: /* ?? */
+ case 3: /* ?? */
+ default:
+ fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n",
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode,
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type);
+ assert(0);
+ }
+ break;
+ case 2: /* Cell in the block */
+ case 3: /* Last cell in the block */
+ /* These might perhaps happen for RSM or LinkC commands? */
+ default:
+ fprintf(MSG_OUT, "libdvdnav: Cell is in block but did not enter at first cell!\n");
+ }
+
+ /* Updates (vm->state).pgN and PTTN_REG */
+ if(!set_PGN(vm)) {
+ /* Should not happen */
+ assert(0);
+ return play_PGC_post(vm);
+ }
+ (vm->state).cell_restart++;
+ (vm->state).blockN = 0;
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: Cell should restart here\n");
+#endif
+ return play_this;
+}
+
+static link_t play_Cell_post(vm_t *vm) {
+ cell_playback_t *cell;
+
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: play_Cell_post: (vm->state).cellN (%i)\n", (vm->state).cellN);
+#endif
+
+ cell = &(vm->state).pgc->cell_playback[(vm->state).cellN - 1];
+
+ /* Still time is already taken care of before we get called. */
+
+ /* Deal with a Cell command, if any */
+ if(cell->cell_cmd_nr != 0) {
+ link_t link_values;
+
+/* These asserts are now not needed.
+ * Some DVDs have no cell commands listed in the PGC,
+ * but the Cell itself points to a cell command that does not exist.
+ * For this situation, just ignore the cell command and continue.
+ *
+ * assert((vm->state).pgc->command_tbl != NULL);
+ * assert((vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr);
+ */
+
+ if ((vm->state).pgc->command_tbl != NULL &&
+ (vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr) {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: Cell command present, executing\n");
+#endif
+ if(vmEval_CMD(&(vm->state).pgc->command_tbl->cell_cmds[cell->cell_cmd_nr - 1], 1,
+ &(vm->state).registers, &link_values)) {
+ return link_values;
+ } else {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: Cell command didn't do a Jump, Link or Call\n");
+#endif
+ }
+ } else {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: Invalid Cell command\n");
+#endif
+ }
+ }
+
+ /* Where to continue after playing the cell... */
+ /* Multi angle/Interleaved */
+ switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
+ case 0: /* Normal */
+ assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0);
+ (vm->state).cellN++;
+ break;
+ case 1: /* The first cell in the block */
+ case 2: /* A cell in the block */
+ case 3: /* The last cell in the block */
+ default:
+ switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) {
+ case 0: /* Not part of a block */
+ assert(0);
+ break;
+ case 1: /* Angle block */
+ /* Skip the 'other' angles */
+ (vm->state).cellN++;
+ while((vm->state).cellN <= (vm->state).pgc->nr_of_cells &&
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode >= 2) {
+ (vm->state).cellN++;
+ }
+ break;
+ case 2: /* ?? */
+ case 3: /* ?? */
+ default:
+ fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n",
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode,
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type);
+ assert(0);
+ }
+ break;
+ }
+
+ /* Figure out the correct pgN for the new cell */
+ if(!set_PGN(vm)) {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: last cell in this PGC\n");
+#endif
+ return play_PGC_post(vm);
+ }
+ return play_Cell(vm);
+}
+
+
/* link processing */
static int process_command(vm_t *vm, link_t link_values) {
@@ -680,43 +1272,40 @@ static int process_command(vm_t *vm, link_t link_values) {
fprintf(MSG_OUT, "libdvdnav: Before printout starts:\n");
vm_print_link(link_values);
fprintf(MSG_OUT, "libdvdnav: Link values %i %i %i %i\n", link_values.command,
- link_values.data1, link_values.data2, link_values.data3);
+ link_values.data1, link_values.data2, link_values.data3);
vm_print_current_domain_state(vm);
fprintf(MSG_OUT, "libdvdnav: Before printout ends.\n");
#endif
switch(link_values.command) {
-
case LinkNoLink:
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
return 0; /* no actual jump */
case LinkTopC:
/* Restart playing from the beginning of the current Cell. */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
link_values = play_Cell(vm);
break;
-
case LinkNextC:
/* Link to Next Cell */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
- vm->state.cellN += 1;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
+ (vm->state).cellN += 1;
link_values = play_Cell(vm);
break;
-
case LinkPrevC:
/* Link to Previous Cell */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
- assert(vm->state.cellN > 1);
- vm->state.cellN -= 1;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
+ assert((vm->state).cellN > 1);
+ (vm->state).cellN -= 1;
link_values = play_Cell(vm);
break;
@@ -724,26 +1313,24 @@ static int process_command(vm_t *vm, link_t link_values) {
/* Link to Top of current Program */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
link_values = play_PG(vm);
break;
-
case LinkNextPG:
/* Link to Next Program */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
- vm->state.pgN += 1;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
+ (vm->state).pgN += 1;
link_values = play_PG(vm);
break;
-
case LinkPrevPG:
/* Link to Previous Program */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
- assert(vm->state.pgN > 1);
- vm->state.pgN -= 1;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
+ assert((vm->state).pgN > 1);
+ (vm->state).pgN -= 1;
link_values = play_PG(vm);
break;
@@ -751,134 +1338,130 @@ static int process_command(vm_t *vm, link_t link_values) {
/* Restart playing from beginning of current Program Chain */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
link_values = play_PGC(vm);
break;
-
case LinkNextPGC:
/* Link to Next Program Chain */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
- assert(vm->state.pgc->next_pgc_nr != 0);
- if(set_PGCN(vm, vm->state.pgc->next_pgc_nr))
- link_values = play_PGC(vm);
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
+ assert((vm->state).pgc->next_pgc_nr != 0);
+ if(set_PGCN(vm, (vm->state).pgc->next_pgc_nr))
+ link_values = play_PGC(vm);
else
- link_values.command = Exit;
+ link_values.command = Exit;
break;
-
case LinkPrevPGC:
/* Link to Previous Program Chain */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
- assert(vm->state.pgc->prev_pgc_nr != 0);
- if(set_PGCN(vm, vm->state.pgc->prev_pgc_nr))
- link_values = play_PGC(vm);
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
+ assert((vm->state).pgc->prev_pgc_nr != 0);
+ if(set_PGCN(vm, (vm->state).pgc->prev_pgc_nr))
+ link_values = play_PGC(vm);
else
- link_values.command = Exit;
+ link_values.command = Exit;
break;
-
case LinkGoUpPGC:
/* Link to GoUp Program Chain */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
- assert(vm->state.pgc->goup_pgc_nr != 0);
- if(set_PGCN(vm, vm->state.pgc->goup_pgc_nr))
- link_values = play_PGC(vm);
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
+ assert((vm->state).pgc->goup_pgc_nr != 0);
+ if(set_PGCN(vm, (vm->state).pgc->goup_pgc_nr))
+ link_values = play_PGC(vm);
else
- link_values.command = Exit;
+ link_values.command = Exit;
break;
-
case LinkTailPGC:
/* Link to Tail of Program Chain */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
link_values = play_PGC_post(vm);
break;
case LinkRSM:
- /* Check and see if there is any rsm info!! */
- if (!vm->state.rsm_vtsN) {
- fprintf(MSG_OUT, "libdvdnav: trying to resume without any resume info set\n");
- link_values.command = Exit;
- break;
- }
-
- vm->state.domain = DVD_DOMAIN_VTSTitle;
- if (!ifoOpenNewVTSI(vm, vm->dvd, vm->state.rsm_vtsN))
- assert(0);
- set_PGCN(vm, vm->state.rsm_pgcN);
-
- /* These should never be set in SystemSpace and/or MenuSpace */
- /* vm->state.TTN_REG = rsm_tt; ?? */
- /* vm->state.TT_PGCN_REG = vm->state.rsm_pgcN; ?? */
- int i;
- for(i = 0; i < 5; i++) {
- vm->state.registers.SPRM[4 + i] = vm->state.rsm_regs[i];
- }
-
- if(link_values.data1 != 0)
- vm->state.HL_BTNN_REG = link_values.data1 << 10;
-
- if(vm->state.rsm_cellN == 0) {
- assert(vm->state.cellN); /* Checking if this ever happens */
- vm->state.pgN = 1;
- link_values = play_PG(vm);
- } else {
- /* vm->state.pgN = ?? this gets the right value in set_PGN() below */
- vm->state.cellN = vm->state.rsm_cellN;
- link_values.command = PlayThis;
- link_values.data1 = vm->state.rsm_blockN & 0xffff;
- link_values.data2 = vm->state.rsm_blockN >> 16;
- if(!set_PGN(vm)) {
- /* Were at the end of the PGC, should not happen for a RSM */
- assert(0);
- link_values.command = LinkTailPGC;
- link_values.data1 = 0; /* No button */
- }
- }
+ {
+ /* Link to Resume point */
+ int i;
+
+ /* Check and see if there is any rsm info!! */
+ if (!(vm->state).rsm_vtsN) {
+ fprintf(MSG_OUT, "libdvdnav: trying to resume without any resume info set\n");
+ link_values.command = Exit;
+ break;
+ }
+
+ (vm->state).domain = VTS_DOMAIN;
+ if (!ifoOpenNewVTSI(vm, vm->dvd, (vm->state).rsm_vtsN))
+ assert(0);
+ set_PGCN(vm, (vm->state).rsm_pgcN);
+
+ /* These should never be set in SystemSpace and/or MenuSpace */
+ /* (vm->state).TTN_REG = rsm_tt; ?? */
+ /* (vm->state).TT_PGCN_REG = (vm->state).rsm_pgcN; ?? */
+ for(i = 0; i < 5; i++) {
+ (vm->state).registers.SPRM[4 + i] = (vm->state).rsm_regs[i];
+ }
+
+ if(link_values.data1 != 0)
+ (vm->state).HL_BTNN_REG = link_values.data1 << 10;
+
+ if((vm->state).rsm_cellN == 0) {
+ assert((vm->state).cellN); /* Checking if this ever happens */
+ (vm->state).pgN = 1;
+ link_values = play_PG(vm);
+ } else {
+ /* (vm->state).pgN = ?? this gets the right value in set_PGN() below */
+ (vm->state).cellN = (vm->state).rsm_cellN;
+ link_values.command = PlayThis;
+ link_values.data1 = (vm->state).rsm_blockN & 0xffff;
+ link_values.data2 = (vm->state).rsm_blockN >> 16;
+ if(!set_PGN(vm)) {
+ /* Were at the end of the PGC, should not happen for a RSM */
+ assert(0);
+ link_values.command = LinkTailPGC;
+ link_values.data1 = 0; /* No button */
+ }
+ }
+ }
break;
-
case LinkPGCN:
/* Link to Program Chain Number:data1 */
if(!set_PGCN(vm, link_values.data1))
- assert(0);
+ assert(0);
link_values = play_PGC(vm);
break;
-
case LinkPTTN:
/* Link to Part of current Title Number:data1 */
/* BUTTON number:data2 */
/* PGC Pre-Commands are not executed */
- assert(vm->state.domain == DVD_DOMAIN_VTSTitle);
+ assert((vm->state).domain == VTS_DOMAIN);
if(link_values.data2 != 0)
- vm->state.HL_BTNN_REG = link_values.data2 << 10;
- if(!set_VTS_PTT(vm, vm->state.vtsN, vm->state.VTS_TTN_REG, link_values.data1))
+ (vm->state).HL_BTNN_REG = link_values.data2 << 10;
+ if(!set_VTS_PTT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG, link_values.data1))
link_values.command = Exit;
else
link_values = play_PG(vm);
break;
-
case LinkPGN:
/* Link to Program Number:data1 */
/* BUTTON number:data2 */
if(link_values.data2 != 0)
- vm->state.HL_BTNN_REG = link_values.data2 << 10;
+ (vm->state).HL_BTNN_REG = link_values.data2 << 10;
/* Update any other state, PTTN perhaps? */
- vm->state.pgN = link_values.data1;
+ (vm->state).pgN = link_values.data1;
link_values = play_PG(vm);
break;
-
case LinkCN:
/* Link to Cell Number:data1 */
/* BUTTON number:data2 */
if(link_values.data2 != 0)
- vm->state.HL_BTNN_REG = link_values.data2 << 10;
+ (vm->state).HL_BTNN_REG = link_values.data2 << 10;
/* Update any other state, pgN, PTTN perhaps? */
- vm->state.cellN = link_values.data1;
+ (vm->state).cellN = link_values.data1;
link_values = play_Cell(vm);
break;
@@ -892,37 +1475,35 @@ static int process_command(vm_t *vm, link_t link_values) {
/* or the Video Manager domain (VMG) */
/* Stop SPRM9 Timer */
/* Set SPRM1 and SPRM2 */
- assert(vm->state.domain == DVD_DOMAIN_VMGM || vm->state.domain == DVD_DOMAIN_FirstPlay); /* ?? */
+ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
if(set_TT(vm, link_values.data1))
link_values = play_PGC(vm);
else
- link_values.command = Exit;
+ link_values.command = Exit;
break;
-
case JumpVTS_TT:
/* Jump to Title:data1 in same VTS Title Domain */
/* Only allowed from the VTS Menu Domain(VTSM) */
/* or the Video Title Set Domain(VTS) */
/* Stop SPRM9 Timer */
/* Set SPRM1 and SPRM2 */
- assert(vm->state.domain == DVD_DOMAIN_VTSMenu || vm->state.domain == DVD_DOMAIN_VTSTitle); /* ?? */
- if(!set_VTS_TT(vm, vm->state.vtsN, link_values.data1))
+ assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
+ if(!set_VTS_TT(vm, (vm->state).vtsN, link_values.data1))
link_values.command = Exit;
else
link_values = play_PGC(vm);
break;
-
case JumpVTS_PTT:
/* Jump to Part:data2 of Title:data1 in same VTS Title Domain */
/* Only allowed from the VTS Menu Domain(VTSM) */
/* or the Video Title Set Domain(VTS) */
/* Stop SPRM9 Timer */
/* Set SPRM1 and SPRM2 */
- assert(vm->state.domain == DVD_DOMAIN_VTSMenu || vm->state.domain == DVD_DOMAIN_VTSTitle); /* ?? */
- if(!set_VTS_PTT(vm, vm->state.vtsN, link_values.data1, link_values.data2))
+ assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
+ if(!set_VTS_PTT(vm, (vm->state).vtsN, link_values.data1, link_values.data2))
link_values.command = Exit;
else
- link_values = play_PGC_PG(vm, vm->state.pgN);
+ link_values = play_PGC_PG(vm, (vm->state).pgN);
break;
case JumpSS_FP:
@@ -930,27 +1511,25 @@ static int process_command(vm_t *vm, link_t link_values) {
/* Only allowed from the VTS Menu Domain(VTSM) */
/* or the Video Manager domain (VMG) */
/* Stop SPRM9 Timer and any GPRM counters */
- assert(vm->state.domain == DVD_DOMAIN_VMGM || vm->state.domain == DVD_DOMAIN_VTSMenu); /* ?? */
+ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN); /* ?? */
if (!set_FP_PGC(vm))
- assert(0);
+ assert(0);
link_values = play_PGC(vm);
break;
-
case JumpSS_VMGM_MENU:
/* Jump to Video Manager domain - Title Menu:data1 or any PGC in VMG */
/* Allowed from anywhere except the VTS Title domain */
/* Stop SPRM9 Timer and any GPRM counters */
- assert(vm->state.domain != DVD_DOMAIN_VTSTitle); /* ?? */
+ assert((vm->state).domain != VTS_DOMAIN); /* ?? */
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
- vm->state.domain = DVD_DOMAIN_VMGM;
+ (vm->state).domain = VMGM_DOMAIN;
if(!set_MENU(vm, link_values.data1))
- assert(0);
+ assert(0);
link_values = play_PGC(vm);
break;
-
case JumpSS_VTSM:
/* Jump to a menu in Video Title domain, */
/* or to a Menu is the current VTS */
@@ -959,110 +1538,109 @@ static int process_command(vm_t *vm, link_t link_values) {
/* VTS_TTN_REG:data2 */
/* get_MENU:data3 */
if(link_values.data1 != 0) {
- assert(vm->state.domain == DVD_DOMAIN_VTSMenu ||
- vm->state.domain == DVD_DOMAIN_VMGM || vm->state.domain == DVD_DOMAIN_FirstPlay); /* ?? */
- if (link_values.data1 != vm->state.vtsN) {
- /* the normal case */
- assert(vm->state.domain != DVD_DOMAIN_VTSMenu);
- if (!ifoOpenNewVTSI(vm, vm->dvd, link_values.data1)) /* Also sets vm->state.vtsN */
- vm->vtsi = NULL;
- } else {
- /* This happens on some discs like "Captain Scarlet & the Mysterons" or
- * the German RC2 of "Anatomie" in VTSM. */
- }
-
- if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
- link_values.command = Exit;
- break;
- }
- vm->state.domain = DVD_DOMAIN_VTSMenu;
+ if (link_values.data1 != (vm->state).vtsN) {
+ /* the normal case */
+ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
+ if (!ifoOpenNewVTSI(vm, vm->dvd, link_values.data1)) /* Also sets (vm->state).vtsN */
+ assert(0);
+ if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
+ link_values.command = Exit;
+ break;
+ }
+ (vm->state).domain = VTSM_DOMAIN;
+ } else {
+ /* This happens on some discs like "Captain Scarlet & the Mysterons" or
+ * the German RC2 of "Anatomie" in VTSM. */
+ assert((vm->state).domain == VTSM_DOMAIN ||
+ (vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
+ if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
+ link_values.command = Exit;
+ break;
+ }
+ (vm->state).domain = VTSM_DOMAIN;
+ }
} else {
- /* This happens on 'The Fifth Element' region 2. */
- assert(vm->state.domain == DVD_DOMAIN_VTSMenu);
+ /* This happens on 'The Fifth Element' region 2. */
+ assert((vm->state).domain == VTSM_DOMAIN);
}
/* I don't know what title is supposed to be used for. */
/* Alien or Aliens has this != 1, I think. */
/* assert(link_values.data2 == 1); */
- vm->state.VTS_TTN_REG = link_values.data2;
+ (vm->state).VTS_TTN_REG = link_values.data2;
/* TTN_REG (SPRM4), VTS_TTN_REG (SPRM5), TT_PGCN_REG (SPRM6) are linked, */
/* so if one changes, the others must change to match it. */
- vm->state.TTN_REG = get_TT(vm, vm->state.vtsN, vm->state.VTS_TTN_REG);
+ (vm->state).TTN_REG = get_TT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG);
if(!set_MENU(vm, link_values.data3))
- assert(0);
+ assert(0);
link_values = play_PGC(vm);
break;
-
case JumpSS_VMGM_PGC:
/* set_PGCN:data1 */
/* Stop SPRM9 Timer and any GPRM counters */
- assert(vm->state.domain != DVD_DOMAIN_VTSTitle); /* ?? */
+ assert((vm->state).domain != VTS_DOMAIN); /* ?? */
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
- vm->state.domain = DVD_DOMAIN_VMGM;
+ (vm->state).domain = VMGM_DOMAIN;
if(!set_PGCN(vm, link_values.data1))
- assert(0);
+ assert(0);
link_values = play_PGC(vm);
break;
case CallSS_FP:
/* set_RSMinfo:data1 */
- assert(vm->state.domain == DVD_DOMAIN_VTSTitle); /* ?? */
+ assert((vm->state).domain == VTS_DOMAIN); /* ?? */
/* Must be called before domain is changed */
set_RSMinfo(vm, link_values.data1, /* We dont have block info */ 0);
set_FP_PGC(vm);
link_values = play_PGC(vm);
break;
-
case CallSS_VMGM_MENU:
/* set_MENU:data1 */
/* set_RSMinfo:data2 */
- assert(vm->state.domain == DVD_DOMAIN_VTSTitle); /* ?? */
+ assert((vm->state).domain == VTS_DOMAIN); /* ?? */
/* Must be called before domain is changed */
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
- vm->state.domain = DVD_DOMAIN_VMGM;
+ (vm->state).domain = VMGM_DOMAIN;
if(!set_MENU(vm, link_values.data1))
- assert(0);
+ assert(0);
link_values = play_PGC(vm);
break;
-
case CallSS_VTSM:
/* set_MENU:data1 */
/* set_RSMinfo:data2 */
- assert(vm->state.domain == DVD_DOMAIN_VTSTitle); /* ?? */
+ assert((vm->state).domain == VTS_DOMAIN); /* ?? */
/* Must be called before domain is changed */
if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
- vm->state.domain = DVD_DOMAIN_VTSMenu;
+ (vm->state).domain = VTSM_DOMAIN;
if(!set_MENU(vm, link_values.data1))
- assert(0);
+ assert(0);
link_values = play_PGC(vm);
break;
-
case CallSS_VMGM_PGC:
/* set_PGC:data1 */
/* set_RSMinfo:data2 */
- assert(vm->state.domain == DVD_DOMAIN_VTSTitle); /* ?? */
+ assert((vm->state).domain == VTS_DOMAIN); /* ?? */
/* Must be called before domain is changed */
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
- vm->state.domain = DVD_DOMAIN_VMGM;
+ (vm->state).domain = VMGM_DOMAIN;
if(!set_PGCN(vm, link_values.data1))
- assert(0);
+ assert(0);
link_values = play_PGC(vm);
break;
-
case PlayThis:
/* Should never happen. */
assert(0);
@@ -1076,23 +1654,352 @@ static int process_command(vm_t *vm, link_t link_values) {
#endif
}
+ (vm->state).blockN = link_values.data1 | (link_values.data2 << 16);
+ return 1;
+}
+
+
+/* Set functions */
+
+static int set_TT(vm_t *vm, int tt) {
+ return set_PTT(vm, tt, 1);
+}
+
+static int set_PTT(vm_t *vm, int tt, int ptt) {
+ assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
+ return set_VTS_PTT(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
+ vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, ptt);
+}
+
+static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn) {
+ return set_VTS_PTT(vm, vtsN, vts_ttn, 1);
+}
+
+static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) {
+ int pgcN, pgN, res;
+
+ (vm->state).domain = VTS_DOMAIN;
+
+ if (vtsN != (vm->state).vtsN)
+ if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
+ return 0;
+
+ if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts) ||
+ (part < 1) || (part > vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts) ) {
+ return 0;
+ }
+
+ pgcN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn;
+ pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn;
- vm->state.blockN = link_values.data1 | (link_values.data2 << 16);
+ (vm->state).TT_PGCN_REG = pgcN;
+ (vm->state).PTTN_REG = part;
+ (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
+ if( (vm->state.TTN_REG) == 0 )
+ return 0;
+
+ (vm->state).VTS_TTN_REG = vts_ttn;
+ (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
+ /* Any other registers? */
+
+ res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
+ (vm->state).pgN = pgN;
+ return res;
+}
+
+static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn) {
+ assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
+ return set_VTS_PROG(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
+ vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, pgcn, pgn);
+}
+
+static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn) {
+ int pgcN, pgN, res, title, part = 0;
+
+ (vm->state).domain = VTS_DOMAIN;
+
+ if (vtsN != (vm->state).vtsN)
+ if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
+ return 0;
+
+ if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts)) {
+ return 0;
+ }
+
+ pgcN = pgcn;
+ pgN = pgn;
+
+ (vm->state).TT_PGCN_REG = pgcN;
+ (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
+ assert( (vm->state.TTN_REG) != 0 );
+ (vm->state).VTS_TTN_REG = vts_ttn;
+ (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
+ /* Any other registers? */
+
+ res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
+ (vm->state).pgN = pgN;
+ vm_get_current_title_part(vm, &title, &part);
+ (vm->state).PTTN_REG = part;
+ return res;
+}
+
+static int set_FP_PGC(vm_t *vm) {
+ (vm->state).domain = FP_DOMAIN;
+ if (!vm->vmgi->first_play_pgc) {
+ return set_PGCN(vm, 1);
+ }
+ (vm->state).pgc = vm->vmgi->first_play_pgc;
+ (vm->state).pgcN = vm->vmgi->vmgi_mat->first_play_pgc;
return 1;
}
+
+static int set_MENU(vm_t *vm, int menu) {
+ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN);
+ return set_PGCN(vm, get_ID(vm, menu));
+}
+
+static int set_PGCN(vm_t *vm, int pgcN) {
+ pgcit_t *pgcit;
+
+ pgcit = get_PGCIT(vm);
+ if (pgcit == NULL)
+ return 0;
+
+ if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: ** No such pgcN = %d\n", pgcN);
+#endif
+ return 0;
+ }
+
+ (vm->state).pgc = pgcit->pgci_srp[pgcN - 1].pgc;
+ (vm->state).pgcN = pgcN;
+ (vm->state).pgN = 1;
+
+ if((vm->state).domain == VTS_DOMAIN)
+ (vm->state).TT_PGCN_REG = pgcN;
+
+ return 1;
+}
+
+/* Figure out the correct pgN from the cell and update (vm->state). */
+static int set_PGN(vm_t *vm) {
+ int new_pgN = 0;
+ int dummy, part = 0;
+
+ while(new_pgN < (vm->state).pgc->nr_of_programs
+ && (vm->state).cellN >= (vm->state).pgc->program_map[new_pgN])
+ new_pgN++;
+
+ if(new_pgN == (vm->state).pgc->nr_of_programs) /* We are at the last program */
+ if((vm->state).cellN > (vm->state).pgc->nr_of_cells)
+ return 0; /* We are past the last cell */
+
+ (vm->state).pgN = new_pgN;
+
+ if((vm->state).domain == VTS_DOMAIN) {
+ playback_type_t *pb_ty;
+ if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
+ return 0; /* ?? */
+ pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;
+ vm_get_current_title_part(vm, &dummy, &part);
+ (vm->state).PTTN_REG = part;
+ }
+ return 1;
+}
+
+/* Must be called before domain is changed (set_PGCN()) */
+static void set_RSMinfo(vm_t *vm, int cellN, int blockN) {
+ int i;
+
+ if(cellN) {
+ (vm->state).rsm_cellN = cellN;
+ (vm->state).rsm_blockN = blockN;
+ } else {
+ (vm->state).rsm_cellN = (vm->state).cellN;
+ (vm->state).rsm_blockN = blockN;
+ }
+ (vm->state).rsm_vtsN = (vm->state).vtsN;
+ (vm->state).rsm_pgcN = get_PGCN(vm);
+
+ /* assert((vm->state).rsm_pgcN == (vm->state).TT_PGCN_REG); for VTS_DOMAIN */
+
+ for(i = 0; i < 5; i++) {
+ (vm->state).rsm_regs[i] = (vm->state).registers.SPRM[4 + i];
+ }
+}
+
+
+/* Get functions */
+
+/* Searches the TT tables, to find the current TT.
+ * returns the current TT.
+ * returns 0 if not found.
+ */
+static int get_TT(vm_t *vm, int vtsN, int vts_ttn) {
+ int i;
+ int tt=0;
+
+ for(i = 1; i <= vm->vmgi->tt_srpt->nr_of_srpts; i++) {
+ if( vm->vmgi->tt_srpt->title[i - 1].title_set_nr == vtsN &&
+ vm->vmgi->tt_srpt->title[i - 1].vts_ttn == vts_ttn) {
+ tt=i;
+ break;
+ }
+ }
+ return tt;
+}
+
+/* Search for entry_id match of the PGC Category in the current VTS PGCIT table.
+ * Return pgcN based on entry_id match.
+ */
+static int get_ID(vm_t *vm, int id) {
+ int pgcN, i;
+ pgcit_t *pgcit;
+
+ /* Relies on state to get the correct pgcit. */
+ pgcit = get_PGCIT(vm);
+ assert(pgcit != NULL);
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: ** Searching for menu (0x%x) entry PGC\n", id);
+#endif
+
+ /* Force high bit set. */
+ id |=0x80;
+
+ /* Get menu/title */
+ for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
+ if( (pgcit->pgci_srp[i].entry_id) == id) {
+ pgcN = i + 1;
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: Found menu.\n");
+#endif
+ return pgcN;
+ }
+ }
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: ** No such id/menu (0x%02x) entry PGC\n", id & 0x7f);
+ for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
+ if ( (pgcit->pgci_srp[i].entry_id & 0x80) == 0x80) {
+ fprintf(MSG_OUT, "libdvdnav: Available menus: 0x%x\n",
+ pgcit->pgci_srp[i].entry_id & 0x7f);
+ }
+ }
+#endif
+ return 0; /* error */
+}
+
+/* FIXME: we have a pgcN member in the vm's state now, so this should be obsolete */
+static int get_PGCN(vm_t *vm) {
+ pgcit_t *pgcit;
+ int pgcN = 1;
+
+ pgcit = get_PGCIT(vm);
+
+ if (pgcit) {
+ while(pgcN <= pgcit->nr_of_pgci_srp) {
+ if(pgcit->pgci_srp[pgcN - 1].pgc == (vm->state).pgc) {
+ assert((vm->state).pgcN == pgcN);
+ return pgcN;
+ }
+ pgcN++;
+ }
+ }
+ fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n",
+ (vm->state).domain);
+ return 0; /* error */
+}
+
+static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang) {
+ int i;
+
+ if(h == NULL || h->pgci_ut == NULL) {
+ fprintf(MSG_OUT, "libdvdnav: *** pgci_ut handle is NULL ***\n");
+ return NULL; /* error? */
+ }
+
+ i = 0;
+ while(i < h->pgci_ut->nr_of_lus
+ && h->pgci_ut->lu[i].lang_code != lang)
+ i++;
+ if(i == h->pgci_ut->nr_of_lus) {
+ fprintf(MSG_OUT, "libdvdnav: Language '%c%c' not found, using '%c%c' instead\n",
+ (char)(lang >> 8), (char)(lang & 0xff),
+ (char)(h->pgci_ut->lu[0].lang_code >> 8),
+ (char)(h->pgci_ut->lu[0].lang_code & 0xff));
+ fprintf(MSG_OUT, "libdvdnav: Menu Languages available: ");
+ for(i = 0; i < h->pgci_ut->nr_of_lus; i++) {
+ fprintf(MSG_OUT, "%c%c ",
+ (char)(h->pgci_ut->lu[i].lang_code >> 8),
+ (char)(h->pgci_ut->lu[i].lang_code & 0xff));
+ }
+ fprintf(MSG_OUT, "\n");
+ i = 0; /* error? */
+ }
+
+ return h->pgci_ut->lu[i].pgcit;
+}
+
+/* Uses state to decide what to return */
+static pgcit_t* get_PGCIT(vm_t *vm) {
+ pgcit_t *pgcit = NULL;
+
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ if(!vm->vtsi) return NULL;
+ pgcit = vm->vtsi->vts_pgcit;
+ break;
+ case VTSM_DOMAIN:
+ if(!vm->vtsi) return NULL;
+ pgcit = get_MENU_PGCIT(vm, vm->vtsi, (vm->state).registers.SPRM[0]);
+ break;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ pgcit = get_MENU_PGCIT(vm, vm->vmgi, (vm->state).registers.SPRM[0]);
+ break;
+ default:
+ abort();
+ }
+
+ return pgcit;
+}
+
//return the ifo_handle_t describing required title, used to
//identify chapters
ifo_handle_t *vm_get_title_ifo(vm_t *vm, uint32_t title)
{
+ ifo_handle_t *ifo = NULL;
uint8_t titleset_nr;
if((title < 1) || (title > vm->vmgi->tt_srpt->nr_of_srpts))
return NULL;
titleset_nr = vm->vmgi->tt_srpt->title[title-1].title_set_nr;
- return ifoOpen(vm->dvd, titleset_nr);
+ ifo = ifoOpen(vm->dvd, titleset_nr);
+ return ifo;
}
void vm_ifo_close(ifo_handle_t *ifo)
{
ifoClose(ifo);
}
+
+/* Debug functions */
+
+#ifdef TRACE
+void vm_position_print(vm_t *vm, vm_position_t *position) {
+ fprintf(MSG_OUT, "libdvdnav: But=%x Spu=%x Aud=%x Ang=%x Hop=%x vts=%x dom=%x cell=%x cell_restart=%x cell_start=%x still=%x block=%x\n",
+ position->button,
+ position->spu_channel,
+ position->audio_channel,
+ position->angle_channel,
+ position->hop_channel,
+ position->vts,
+ position->domain,
+ position->cell,
+ position->cell_restart,
+ position->cell_start,
+ position->still,
+ position->block);
+}
+#endif
+
diff --git a/src/vm/vm.h b/src/vm/vm.h
index d911202..303946a 100644
--- a/src/vm/vm.h
+++ b/src/vm/vm.h
@@ -23,13 +23,22 @@
#ifndef LIBDVDNAV_VM_H
#define LIBDVDNAV_VM_H
+/* DOMAIN enum */
+
+typedef enum {
+ FP_DOMAIN = 1,
+ VTS_DOMAIN = 2,
+ VMGM_DOMAIN = 4,
+ VTSM_DOMAIN = 8
+} domain_t;
+
/**
* State: SPRM, GPRM, Domain, pgc, pgN, cellN, ?
*/
typedef struct {
registers_t registers;
- DVDDomain_t domain;
+ domain_t domain;
int vtsN; /* 0 is vmgm? */
pgc_t *pgc; /* either this or 'int pgcN' is enough? */
int pgcN; /* but provide pgcN for quick lookup */
@@ -49,7 +58,7 @@ typedef struct {
typedef struct vm_position_s {
int16_t button; /* Button highlighted */
int32_t vts; /* vts number to use */
- DVDDomain_t domain; /* domain to use */
+ domain_t domain; /* domain to use */
int32_t spu_channel; /* spu channel to use */
int32_t angle_channel; /* angle channel to use */
int32_t audio_channel; /* audio channel to use */
@@ -168,7 +177,5 @@ void vm_ifo_close(ifo_handle_t *ifo);
void vm_position_print(vm_t *vm, vm_position_t *position);
#endif
-int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN);
-
#endif /* LIBDVDNAV_VM_H */
diff --git a/src/vm/vmcmd.c b/src/vm/vmcmd.c
index 9f07877..bca3a1d 100644
--- a/src/vm/vmcmd.c
+++ b/src/vm/vmcmd.c
@@ -269,11 +269,11 @@ static void print_special_instruction(command_t* command) {
break;
case 3: /* Parental level */
fprintf(MSG_OUT, "SetTmpPML %" PRIu8 ", Goto %" PRIu8,
- vm_getbits(command, 11, 4), vm_getbits(command, 7, 8));
+ vm_getbits(command, 11, 4), vm_getbits(command, 7, 8));
break;
default:
fprintf(MSG_OUT, "WARNING: Unknown special instruction (%i)",
- vm_getbits(command, 51, 4));
+ vm_getbits(command, 51, 4));
}
}
@@ -306,15 +306,15 @@ static void print_link_instruction(command_t* command, int optional) {
break;
case 5:
fprintf(MSG_OUT, "LinkPTT %" PRIu16 " (button %" PRIu8 ")",
- vm_getbits(command, 9, 10), vm_getbits(command, 15, 6));
+ vm_getbits(command, 9, 10), vm_getbits(command, 15, 6));
break;
case 6:
fprintf(MSG_OUT, "LinkPGN %" PRIu8 " (button %" PRIu8 ")",
- vm_getbits(command, 6, 7), vm_getbits(command, 15, 6));
+ vm_getbits(command, 6, 7), vm_getbits(command, 15, 6));
break;
case 7:
fprintf(MSG_OUT, "LinkCN %" PRIu8 " (button %" PRIu8 ")",
- vm_getbits(command, 7, 8), vm_getbits(command, 15, 6));
+ vm_getbits(command, 7, 8), vm_getbits(command, 15, 6));
break;
default:
fprintf(MSG_OUT, "WARNING: Unknown link instruction");
@@ -334,7 +334,7 @@ static void print_jump_instruction(command_t* command) {
break;
case 5:
fprintf(MSG_OUT, "JumpVTS_PTT %" PRIu8 ":%" PRIu16,
- vm_getbits(command, 22, 7), vm_getbits(command, 41, 10));
+ vm_getbits(command, 22, 7), vm_getbits(command, 41, 10));
break;
case 6:
switch(vm_getbits(command, 23, 2)) {
@@ -346,7 +346,7 @@ static void print_jump_instruction(command_t* command) {
break;
case 2:
fprintf(MSG_OUT, "JumpSS VTSM (vts %" PRIu8 ", title %" PRIu8
- ", menu %" PRIu8 ")", vm_getbits(command, 30, 7), vm_getbits(command, 38, 7), vm_getbits(command, 19, 4));
+ ", menu %" PRIu8 ")", vm_getbits(command, 30, 7), vm_getbits(command, 38, 7), vm_getbits(command, 19, 4));
break;
case 3:
fprintf(MSG_OUT, "JumpSS VMGM (pgc %" PRIu8 ")", vm_getbits(command, 46, 15));
@@ -361,15 +361,15 @@ static void print_jump_instruction(command_t* command) {
break;
case 1:
fprintf(MSG_OUT, "CallSS VMGM (menu %" PRIu8
- ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8));
+ ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8));
break;
case 2:
fprintf(MSG_OUT, "CallSS VTSM (menu %" PRIu8
- ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8));
+ ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8));
break;
case 3:
fprintf(MSG_OUT, "CallSS VMGM (pgc %" PRIu8 ", rsm_cell %" PRIu8 ")",
- vm_getbits(command, 46, 15), vm_getbits(command, 31, 8));
+ vm_getbits(command, 46, 15), vm_getbits(command, 31, 8));
break;
}
break;
@@ -405,9 +405,9 @@ static void print_system_set(command_t* command) {
case 3: /* Mode: Counter / Register + Set */
fprintf(MSG_OUT, "SetMode ");
if(vm_getbits(command, 23, 1))
- fprintf(MSG_OUT, "Counter ");
+ fprintf(MSG_OUT, "Counter ");
else
- fprintf(MSG_OUT, "Register ");
+ fprintf(MSG_OUT, "Register ");
print_g_reg(vm_getbits(command, 19, 4));
print_set_op(0x1); /* '=' */
print_reg_or_data(command, vm_getbits(command, 60, 1), 47);
@@ -421,7 +421,7 @@ static void print_system_set(command_t* command) {
break;
default:
fprintf(MSG_OUT, "WARNING: Unknown system set instruction (%i)",
- vm_getbits(command, 59, 4));
+ vm_getbits(command, 59, 4));
}
}
diff --git a/src/vm/vmget.c b/src/vm/vmget.c
deleted file mode 100644
index 6155a9b..0000000
--- a/src/vm/vmget.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Håkan Hjort
- * Copyright (C) 2001 Rich Wareham <richwareham at users.sourceforge.net>
- * 2002-2004 the dvdnav project
- *
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- *
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with libdvdnav; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <assert.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <dvdread/nav_types.h>
-#include <dvdread/ifo_types.h>
-#include <dvdread/ifo_read.h>
-#include "dvdnav/dvdnav.h"
-
-#include "decoder.h"
-#include "remap.h"
-#include "vm.h"
-#include "getset.h"
-#include "dvdnav_internal.h"
-
-/* getting information */
-
-int vm_get_current_menu(vm_t *vm, int *menuid) {
- pgcit_t* pgcit;
- int pgcn;
- pgcn = (vm->state).pgcN;
- pgcit = get_PGCIT(vm);
- if(pgcit==NULL) return 0;
- *menuid = pgcit->pgci_srp[pgcn - 1].entry_id & 0xf ;
- return 1;
-}
-
-int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) {
- vts_ptt_srpt_t *vts_ptt_srpt;
- int title, part = 0, vts_ttn;
- int found;
- int16_t pgcN, pgN;
-
- vts_ptt_srpt = vm->vtsi->vts_ptt_srpt;
- pgcN = get_PGCN(vm);
- pgN = vm->state.pgN;
-
- found = 0;
- for (vts_ttn = 0; (vts_ttn < vts_ptt_srpt->nr_of_srpts) && !found; vts_ttn++) {
- for (part = 0; (part < vts_ptt_srpt->title[vts_ttn].nr_of_ptts) && !found; part++) {
- if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgcn == pgcN) {
- if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn == pgN) {
- found = 1;
- break;
- }
- if (part > 0 && vts_ptt_srpt->title[vts_ttn].ptt[part].pgn > pgN &&
- vts_ptt_srpt->title[vts_ttn].ptt[part - 1].pgn < pgN) {
- part--;
- found = 1;
- break;
- }
- }
- }
- if (found) break;
- }
- vts_ttn++;
- part++;
-
- if (!found) {
- fprintf(MSG_OUT, "libdvdnav: chapter NOT FOUND!\n");
- return 0;
- }
-
- title = get_TT(vm, vm->state.vtsN, vts_ttn);
-
-#ifdef TRACE
- if (title) {
- fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n");
- fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
- title, part,
- vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgcn ,
- vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgn );
- }
-#endif
- *title_result = title;
- *part_result = part;
- return 1;
-}
-
-/* Return the substream id for 'logical' audio stream audioN.
- * 0 <= audioN < 8
- */
-int vm_get_audio_stream(vm_t *vm, int audioN) {
- int streamN = -1;
-
- if((vm->state).domain != DVD_DOMAIN_VTSTitle)
- audioN = 0;
-
- if(audioN < 8) {
- /* Is there any control info for this logical stream */
- if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
- streamN = ((vm->state).pgc->audio_control[audioN] >> 8) & 0x07;
- }
- }
-
- if((vm->state).domain != DVD_DOMAIN_VTSTitle && streamN == -1)
- streamN = 0;
-
- /* FIXME: Should also check in vtsi/vmgi status what kind of stream
- * it is (ac3/lpcm/dts/sdds...) to find the right (sub)stream id */
- return streamN;
-}
-
-/* Return the substream id for 'logical' subpicture stream subpN and given mode.
- * 0 <= subpN < 32
- * mode == 0 - widescreen
- * mode == 1 - letterbox
- * mode == 2 - pan&scan
- */
-int vm_get_subp_stream(vm_t *vm, int subpN, int mode) {
- int streamN = -1;
- int source_aspect = vm_get_video_aspect(vm);
-
- if((vm->state).domain != DVD_DOMAIN_VTSTitle)
- subpN = 0;
-
- if(subpN < 32) { /* a valid logical stream */
- /* Is this logical stream present */
- if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
- if(source_aspect == 0) /* 4:3 */
- streamN = ((vm->state).pgc->subp_control[subpN] >> 24) & 0x1f;
- if(source_aspect == 3) /* 16:9 */
- switch (mode) {
- case 0:
- streamN = ((vm->state).pgc->subp_control[subpN] >> 16) & 0x1f;
- break;
- case 1:
- streamN = ((vm->state).pgc->subp_control[subpN] >> 8) & 0x1f;
- break;
- case 2:
- streamN = (vm->state).pgc->subp_control[subpN] & 0x1f;
- }
- }
- }
-
- if((vm->state).domain != DVD_DOMAIN_VTSTitle && streamN == -1)
- streamN = 0;
-
- /* FIXME: Should also check in vtsi/vmgi status what kind of stream it is. */
- return streamN;
-}
-
-int vm_get_audio_active_stream(vm_t *vm) {
- int audioN;
- int streamN;
- audioN = (vm->state).AST_REG ;
- streamN = vm_get_audio_stream(vm, audioN);
-
- /* If no such stream, then select the first one that exists. */
- if(streamN == -1) {
- for(audioN = 0; audioN < 8; audioN++) {
- if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
- if ((streamN = vm_get_audio_stream(vm, audioN)) >= 0)
- break;
- }
- }
- }
-
- return streamN;
-}
-
-int vm_get_subp_active_stream(vm_t *vm, int mode) {
- int subpN;
- int streamN;
- subpN = (vm->state).SPST_REG & ~0x40;
- streamN = vm_get_subp_stream(vm, subpN, mode);
-
- /* If no such stream, then select the first one that exists. */
- if(streamN == -1) {
- for(subpN = 0; subpN < 32; subpN++) {
- if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
- if ((streamN = vm_get_subp_stream(vm, subpN, mode)) >= 0)
- break;
- }
- }
- }
-
- if((vm->state).domain == DVD_DOMAIN_VTSTitle && !((vm->state).SPST_REG & 0x40))
- /* Bit 7 set means hide, and only let Forced display show */
- return (streamN | 0x80);
- else
- return streamN;
-}
-
-void vm_get_angle_info(vm_t *vm, int *current, int *num_avail) {
- *num_avail = 1;
- *current = 1;
-
- if((vm->state).domain == DVD_DOMAIN_VTSTitle) {
- title_info_t *title;
- /* TTN_REG does not allways point to the correct title.. */
- if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
- return;
- title = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1];
- if(title->title_set_nr != (vm->state).vtsN ||
- title->vts_ttn != (vm->state).VTS_TTN_REG)
- return;
- *num_avail = title->nr_of_angles;
- *current = (vm->state).AGL_REG;
- }
-}
-
-#if 0
-/* currently unused */
-void vm_get_audio_info(vm_t *vm, int *current, int *num_avail) {
- switch ((vm->state).domain) {
- case DVD_DOMAIN_VTSTitle:
- *num_avail = vm->vtsi->vtsi_mat->nr_of_vts_audio_streams;
- *current = (vm->state).AST_REG;
- break;
- case DVD_DOMAIN_VTSMenu:
- *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_audio_streams; /* 1 */
- *current = 1;
- break;
- case DVD_DOMAIN_VMGM:
- case DVD_DOMAIN_FirstPlay:
- *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_audio_streams; /* 1 */
- *current = 1;
- break;
- }
-}
-
-/* currently unused */
-void vm_get_subp_info(vm_t *vm, int *current, int *num_avail) {
- switch ((vm->state).domain) {
- case DVD_DOMAIN_VTSTitle:
- *num_avail = vm->vtsi->vtsi_mat->nr_of_vts_subp_streams;
- *current = (vm->state).SPST_REG;
- break;
- case DVD_DOMAIN_VTSMenu:
- *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_subp_streams; /* 1 */
- *current = 0x41;
- break;
- case DVD_DOMAIN_VMGM:
- case DVD_DOMAIN_FirstPlay:
- *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_subp_streams; /* 1 */
- *current = 0x41;
- break;
- }
-}
-#endif
-
-void vm_get_video_res(vm_t *vm, int *width, int *height) {
- video_attr_t attr = vm_get_video_attr(vm);
-
- if(attr.video_format != 0)
- *height = 576;
- else
- *height = 480;
- switch(attr.picture_size) {
- case 0:
- *width = 720;
- break;
- case 1:
- *width = 704;
- break;
- case 2:
- *width = 352;
- break;
- case 3:
- *width = 352;
- *height /= 2;
- break;
- }
-}
-
-int vm_get_video_aspect(vm_t *vm) {
- int aspect = vm_get_video_attr(vm).display_aspect_ratio;
-
- assert(aspect == 0 || aspect == 3);
- (vm->state).registers.SPRM[14] &= ~(0x3 << 10);
- (vm->state).registers.SPRM[14] |= aspect << 10;
-
- return aspect;
-}
-
-int vm_get_video_scale_permission(vm_t *vm) {
- return vm_get_video_attr(vm).permitted_df;
-}
-
-video_attr_t vm_get_video_attr(vm_t *vm) {
- switch ((vm->state).domain) {
- case DVD_DOMAIN_VTSTitle:
- return vm->vtsi->vtsi_mat->vts_video_attr;
- case DVD_DOMAIN_VTSMenu:
- return vm->vtsi->vtsi_mat->vtsm_video_attr;
- case DVD_DOMAIN_VMGM:
- case DVD_DOMAIN_FirstPlay:
- return vm->vmgi->vmgi_mat->vmgm_video_attr;
- default:
- assert(0);
- }
-}
-
-audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN) {
- switch ((vm->state).domain) {
- case DVD_DOMAIN_VTSTitle:
- return vm->vtsi->vtsi_mat->vts_audio_attr[streamN];
- case DVD_DOMAIN_VTSMenu:
- return vm->vtsi->vtsi_mat->vtsm_audio_attr;
- case DVD_DOMAIN_VMGM:
- case DVD_DOMAIN_FirstPlay:
- return vm->vmgi->vmgi_mat->vmgm_audio_attr;
- default:
- assert(0);
- }
-}
-
-subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN) {
- switch ((vm->state).domain) {
- case DVD_DOMAIN_VTSTitle:
- return vm->vtsi->vtsi_mat->vts_subp_attr[streamN];
- case DVD_DOMAIN_VTSMenu:
- return vm->vtsi->vtsi_mat->vtsm_subp_attr;
- case DVD_DOMAIN_VMGM:
- case DVD_DOMAIN_FirstPlay:
- return vm->vmgi->vmgi_mat->vmgm_subp_attr;
- default:
- assert(0);
- }
-}
diff --git a/version.sh b/version.sh
new file mode 100755
index 0000000..b774a8d
--- /dev/null
+++ b/version.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+svn_revision=`cd "$1" && LC_ALL=C svn info 2> /dev/null | grep Revision | cut -d' ' -f2`
+test $svn_revision || svn_revision=`cd "$1" && grep revision .svn/entries 2>/dev/null | \
+ cut -d '"' -f2 2> /dev/null`
+test $svn_revision || svn_revision=UNKNOWN
+
+if test "$svn_revision" = UNKNOWN && test -n "$2"; then
+ NEW_REVISION="#define VERSION \"$2\""
+else
+ NEW_REVISION="#define VERSION \"SVN-r$svn_revision\""
+fi
+OLD_REVISION=`cat version.h 2> /dev/null`
+
+# Update version.h only on revision changes to avoid spurious rebuilds
+if test "$NEW_REVISION" != "$OLD_REVISION"; then
+ echo "$NEW_REVISION" > version.h
+fi
--
libdvdnav packaging
More information about the pkg-multimedia-commits
mailing list