Commit 495436e7 authored by Sam Hocevar's avatar Sam Hocevar

  * Exported the CSS part of the dvd plugin into a library.
parent 106079bc
...@@ -249,6 +249,9 @@ snapshot: Makefile.opts ...@@ -249,6 +249,9 @@ snapshot: Makefile.opts
cp share/$$icon.xpm share/$$icon.png \ cp share/$$icon.xpm share/$$icon.png \
/tmp/vlc-${PROGRAM_VERSION}/share/ ; done /tmp/vlc-${PROGRAM_VERSION}/share/ ; done
# make distclean
(cd /tmp/vlc-${PROGRAM_VERSION} ; ./configure ; make distclean )
# build css-enabled archives # build css-enabled archives
(cd /tmp ; tar cf vlc-${PROGRAM_VERSION}.tar vlc-${PROGRAM_VERSION} ; \ (cd /tmp ; tar cf vlc-${PROGRAM_VERSION}.tar vlc-${PROGRAM_VERSION} ; \
bzip2 -f -9 < vlc-${PROGRAM_VERSION}.tar \ bzip2 -f -9 < vlc-${PROGRAM_VERSION}.tar \
...@@ -348,3 +351,9 @@ builtins: Makefile.modules Makefile.opts Makefile.dep Makefile $(BUILTIN_OBJ) ...@@ -348,3 +351,9 @@ builtins: Makefile.modules Makefile.opts Makefile.dep Makefile $(BUILTIN_OBJ)
$(BUILTIN_OBJ): FORCE $(BUILTIN_OBJ): FORCE
cd $(shell echo " "$(PLUGINS_TARGETS)" " | sed -e 's@.* \([^/]*/\)'$(@:lib/%.a=%)' .*@plugins/\1@' -e 's@^ .*@@') && $(MAKE) $(@:%=../../%) cd $(shell echo " "$(PLUGINS_TARGETS)" " | sed -e 's@.* \([^/]*/\)'$(@:lib/%.a=%)' .*@plugins/\1@' -e 's@^ .*@@') && $(MAKE) $(@:%=../../%)
#
# libdvdcss target
#
libdvdcss:
cd extras/libdvdcss && $(MAKE)
...@@ -62,6 +62,7 @@ libdir = @libdir@ ...@@ -62,6 +62,7 @@ libdir = @libdir@
LIB_ALSA = @LIB_ALSA@ LIB_ALSA = @LIB_ALSA@
LIB_BEOS = @LIB_BEOS@ LIB_BEOS = @LIB_BEOS@
LIB_DARWIN = @LIB_DARWIN@ LIB_DARWIN = @LIB_DARWIN@
LIB_DVD = @LIB_DVD@
LIB_ESD = @LIB_ESD@ LIB_ESD = @LIB_ESD@
LIB_GGI = @LIB_GGI@ LIB_GGI = @LIB_GGI@
LIB_GLIDE = @LIB_GLIDE@ LIB_GLIDE = @LIB_GLIDE@
...@@ -81,6 +82,7 @@ LIB_YUV = @LIB_YUV@ ...@@ -81,6 +82,7 @@ LIB_YUV = @LIB_YUV@
# #
# CFLAGS for special cases # CFLAGS for special cases
# #
CFLAGS_DVD = @CFLAGS_DVD@
CFLAGS_GTK = @CFLAGS_GTK@ CFLAGS_GTK = @CFLAGS_GTK@
CFLAGS_SDL = @CFLAGS_SDL@ CFLAGS_SDL = @CFLAGS_SDL@
CFLAGS_X11 = @CFLAGS_X11@ CFLAGS_X11 = @CFLAGS_X11@
......
...@@ -3357,21 +3357,23 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then ...@@ -3357,21 +3357,23 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
EOF EOF
BUILTINS="${BUILTINS} dvd" BUILTINS="${BUILTINS} dvd"
LIB_DVD="${LIB_DVD} -Llib -L../../lib -ldvdcss"
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
for ac_hdr in sys/cdio.h sys/dvdio.h linux/cdrom.h for ac_hdr in sys/cdio.h sys/dvdio.h linux/cdrom.h
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:3365: checking for $ac_hdr" >&5 echo "configure:3367: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3370 "configure" #line 3372 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:3375: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:3377: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -3399,7 +3401,7 @@ done ...@@ -3399,7 +3401,7 @@ done
BSD_DVD_STRUCT=0 BSD_DVD_STRUCT=0
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3403 "configure" #line 3405 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/dvdio.h> #include <sys/dvdio.h>
EOF EOF
...@@ -3417,7 +3419,7 @@ fi ...@@ -3417,7 +3419,7 @@ fi
rm -f conftest* rm -f conftest*
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3421 "configure" #line 3423 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/cdio.h> #include <sys/cdio.h>
EOF EOF
...@@ -3441,7 +3443,7 @@ EOF ...@@ -3441,7 +3443,7 @@ EOF
fi fi
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3445 "configure" #line 3447 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <linux/cdrom.h> #include <linux/cdrom.h>
EOF EOF
...@@ -3593,7 +3595,7 @@ if test "${enable_esd+set}" = set; then ...@@ -3593,7 +3595,7 @@ if test "${enable_esd+set}" = set; then
# Extract the first word of "esd-config", so it can be a program name with args. # Extract the first word of "esd-config", so it can be a program name with args.
set dummy esd-config; ac_word=$2 set dummy esd-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:3597: checking for $ac_word" >&5 echo "configure:3599: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_ESD_CONFIG'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_ESD_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -3658,17 +3660,17 @@ else ...@@ -3658,17 +3660,17 @@ else
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:3662: checking for $ac_hdr" >&5 echo "configure:3664: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3667 "configure" #line 3669 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:3672: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:3674: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -3739,17 +3741,17 @@ if test "${with_sdl+set}" = set; then ...@@ -3739,17 +3741,17 @@ if test "${with_sdl+set}" = set; then
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:3743: checking for $ac_hdr" >&5 echo "configure:3745: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3748 "configure" #line 3750 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:3753: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:3755: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -3787,17 +3789,17 @@ fi ...@@ -3787,17 +3789,17 @@ fi
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:3791: checking for $ac_hdr" >&5 echo "configure:3793: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3796 "configure" #line 3798 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:3801: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:3803: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -3841,17 +3843,17 @@ if test "${with_directx+set}" = set; then ...@@ -3841,17 +3843,17 @@ if test "${with_directx+set}" = set; then
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:3845: checking for $ac_hdr" >&5 echo "configure:3847: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3850 "configure" #line 3852 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:3855: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:3857: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -3889,17 +3891,17 @@ fi ...@@ -3889,17 +3891,17 @@ fi
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:3893: checking for $ac_hdr" >&5 echo "configure:3895: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3898 "configure" #line 3900 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:3903: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:3905: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -3999,7 +4001,7 @@ if test x$enable_gtk != xno; then ...@@ -3999,7 +4001,7 @@ if test x$enable_gtk != xno; then
# Extract the first word of "gtk-config", so it can be a program name with args. # Extract the first word of "gtk-config", so it can be a program name with args.
set dummy gtk-config; ac_word=$2 set dummy gtk-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:4003: checking for $ac_word" >&5 echo "configure:4005: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -4059,17 +4061,17 @@ if test x$enable_x11 != xno; then ...@@ -4059,17 +4061,17 @@ if test x$enable_x11 != xno; then
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:4063: checking for $ac_hdr" >&5 echo "configure:4065: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4068 "configure" #line 4070 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4073: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:4075: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -4121,17 +4123,17 @@ if test x$enable_xvideo != xno; then ...@@ -4121,17 +4123,17 @@ if test x$enable_xvideo != xno; then
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:4125: checking for $ac_hdr" >&5 echo "configure:4127: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4130 "configure" #line 4132 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4135: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:4137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -4169,17 +4171,17 @@ if test "${enable_alsa+set}" = set; then ...@@ -4169,17 +4171,17 @@ if test "${enable_alsa+set}" = set; then
enableval="$enable_alsa" enableval="$enable_alsa"
if test x$enable_alsa = xyes; then ac_safe=`echo "sys/asoundlib.h" | sed 'y%./+-%__p_%'` if test x$enable_alsa = xyes; then ac_safe=`echo "sys/asoundlib.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for sys/asoundlib.h""... $ac_c" 1>&6 echo $ac_n "checking for sys/asoundlib.h""... $ac_c" 1>&6
echo "configure:4173: checking for sys/asoundlib.h" >&5 echo "configure:4175: checking for sys/asoundlib.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4178 "configure" #line 4180 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/asoundlib.h> #include <sys/asoundlib.h>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4183: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:4185: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -4196,7 +4198,7 @@ fi ...@@ -4196,7 +4198,7 @@ fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6 echo "$ac_t""yes" 1>&6
echo $ac_n "checking for main in -lasound""... $ac_c" 1>&6 echo $ac_n "checking for main in -lasound""... $ac_c" 1>&6
echo "configure:4200: checking for main in -lasound" >&5 echo "configure:4202: checking for main in -lasound" >&5
ac_lib_var=`echo asound'_'main | sed 'y%./+-%__p_%'` ac_lib_var=`echo asound'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -4204,14 +4206,14 @@ else ...@@ -4204,14 +4206,14 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lasound $LIBS" LIBS="-lasound $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4208 "configure" #line 4210 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
main() main()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
...@@ -4284,6 +4286,8 @@ fi ...@@ -4284,6 +4286,8 @@ fi
...@@ -4456,6 +4460,7 @@ s%@LIB@%$LIB%g ...@@ -4456,6 +4460,7 @@ s%@LIB@%$LIB%g
s%@LIB_ALSA@%$LIB_ALSA%g s%@LIB_ALSA@%$LIB_ALSA%g
s%@LIB_BEOS@%$LIB_BEOS%g s%@LIB_BEOS@%$LIB_BEOS%g
s%@LIB_DARWIN@%$LIB_DARWIN%g s%@LIB_DARWIN@%$LIB_DARWIN%g
s%@LIB_DVD@%$LIB_DVD%g
s%@LIB_ESD@%$LIB_ESD%g s%@LIB_ESD@%$LIB_ESD%g
s%@LIB_GGI@%$LIB_GGI%g s%@LIB_GGI@%$LIB_GGI%g
s%@LIB_GLIDE@%$LIB_GLIDE%g s%@LIB_GLIDE@%$LIB_GLIDE%g
...@@ -4472,6 +4477,7 @@ s%@LIB_X11@%$LIB_X11%g ...@@ -4472,6 +4477,7 @@ s%@LIB_X11@%$LIB_X11%g
s%@LIB_XVIDEO@%$LIB_XVIDEO%g s%@LIB_XVIDEO@%$LIB_XVIDEO%g
s%@LIB_YUV@%$LIB_YUV%g s%@LIB_YUV@%$LIB_YUV%g
s%@CFLAGS_VLC@%$CFLAGS_VLC%g s%@CFLAGS_VLC@%$CFLAGS_VLC%g
s%@CFLAGS_DVD@%$CFLAGS_DVD%g
s%@CFLAGS_GTK@%$CFLAGS_GTK%g s%@CFLAGS_GTK@%$CFLAGS_GTK%g
s%@CFLAGS_SDL@%$CFLAGS_SDL%g s%@CFLAGS_SDL@%$CFLAGS_SDL%g
s%@CFLAGS_X11@%$CFLAGS_X11%g s%@CFLAGS_X11@%$CFLAGS_X11%g
...@@ -4696,20 +4702,27 @@ test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 ...@@ -4696,20 +4702,27 @@ test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
echo " echo "
global configuration
--------------------
system : ${SYS}
architecture : ${ARCH}
optimizations : ${OPTIMS}
vlc configuration vlc configuration
----------------- -----------------
vlc version : ${VLC_VERSION} vlc version : ${VLC_VERSION}
system : ${SYS}
architecture : ${ARCH}
debug mode : ${DEBUG} debug mode : ${DEBUG}
statistics : ${STATS} statistics : ${STATS}
trace mode : ${TRACE} trace mode : ${TRACE}
optimizations : ${OPTIMS}
CSS decryption : ${CSS}
need builtin getopt : ${GETOPT} need builtin getopt : ${GETOPT}
built-in modules :${BUILTINS} built-in modules :${BUILTINS}
plugin modules :${PLUGINS} plugin modules :${PLUGINS}
vlc aliases :${ALIASES} vlc aliases :${ALIASES}
You may now tune Makefile.opts at your convenience." libdvdcss configuration
-----------------------
CSS decryption : ${CSS}
You may now tune Makefile.opts at your convenience. To build vlc, type
\`make vlc'. To build libdvdcss only, type \`make libdvdcss'."
...@@ -180,6 +180,8 @@ dnl DVD module: check for DVD ioctls ...@@ -180,6 +180,8 @@ dnl DVD module: check for DVD ioctls
dnl dnl
AC_CHECK_HEADERS(sys/ioctl.h,[ AC_CHECK_HEADERS(sys/ioctl.h,[
BUILTINS="${BUILTINS} dvd" BUILTINS="${BUILTINS} dvd"
LIB_DVD="${LIB_DVD} -Llib -L../../lib -ldvdcss"
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
AC_CHECK_HEADERS(sys/cdio.h sys/dvdio.h linux/cdrom.h) AC_CHECK_HEADERS(sys/cdio.h sys/dvdio.h linux/cdrom.h)
BSD_DVD_STRUCT=0 BSD_DVD_STRUCT=0
dnl dnl
...@@ -592,6 +594,7 @@ AC_SUBST(LIB) ...@@ -592,6 +594,7 @@ AC_SUBST(LIB)
AC_SUBST(LIB_ALSA) AC_SUBST(LIB_ALSA)
AC_SUBST(LIB_BEOS) AC_SUBST(LIB_BEOS)
AC_SUBST(LIB_DARWIN) AC_SUBST(LIB_DARWIN)
AC_SUBST(LIB_DVD)
AC_SUBST(LIB_ESD) AC_SUBST(LIB_ESD)
AC_SUBST(LIB_GGI) AC_SUBST(LIB_GGI)
AC_SUBST(LIB_GLIDE) AC_SUBST(LIB_GLIDE)
...@@ -609,6 +612,7 @@ AC_SUBST(LIB_XVIDEO) ...@@ -609,6 +612,7 @@ AC_SUBST(LIB_XVIDEO)
AC_SUBST(LIB_YUV) AC_SUBST(LIB_YUV)
AC_SUBST(CFLAGS_VLC) AC_SUBST(CFLAGS_VLC)
AC_SUBST(CFLAGS_DVD)
AC_SUBST(CFLAGS_GTK) AC_SUBST(CFLAGS_GTK)
AC_SUBST(CFLAGS_SDL) AC_SUBST(CFLAGS_SDL)
AC_SUBST(CFLAGS_X11) AC_SUBST(CFLAGS_X11)
...@@ -616,20 +620,27 @@ AC_SUBST(CFLAGS_X11) ...@@ -616,20 +620,27 @@ AC_SUBST(CFLAGS_X11)
AC_OUTPUT([Makefile.opts include/config.h]) AC_OUTPUT([Makefile.opts include/config.h])
echo " echo "
global configuration
--------------------
system : ${SYS}
architecture : ${ARCH}
optimizations : ${OPTIMS}
vlc configuration vlc configuration
----------------- -----------------
vlc version : ${VLC_VERSION} vlc version : ${VLC_VERSION}
system : ${SYS}
architecture : ${ARCH}
debug mode : ${DEBUG} debug mode : ${DEBUG}
statistics : ${STATS} statistics : ${STATS}
trace mode : ${TRACE} trace mode : ${TRACE}
optimizations : ${OPTIMS}
CSS decryption : ${CSS}
need builtin getopt : ${GETOPT} need builtin getopt : ${GETOPT}
built-in modules :${BUILTINS} built-in modules :${BUILTINS}
plugin modules :${PLUGINS} plugin modules :${PLUGINS}
vlc aliases :${ALIASES} vlc aliases :${ALIASES}
You may now tune Makefile.opts at your convenience." libdvdcss configuration
-----------------------
CSS decryption : ${CSS}
You may now tune Makefile.opts at your convenience. To build vlc, type
\`make vlc'. To build libdvdcss only, type \`make libdvdcss'."
###############################################################################
# vlc (VideoLAN Client) dvd module Makefile
# (c)2001 VideoLAN
###############################################################################
include ../../Makefile.opts
#
# Objects
#
LIBDVDCSS_O = libdvdcss.o css.o ioctl.o
ALL_OBJ = $(LIBDVDCSS_O)
include ../../Makefile.modules
$(LIBDVDCSS_O): %.o: .dep/%.d
$(LIBDVDCSS_O): %.o: %.c
$(CC) $(CFLAGS) $(PCFLAGS) -c -o $@ $<
../../lib/libdvdcss.so: $(LIBDVDCSS_O)
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
../../lib/libdvdcss.a: $(LIBDVDCSS_O)
ar r $@ $^
$(RANLIB) $@
#all: ../../lib/libdvdcss.so ../../lib/libdvdcss.a
all: ../../lib/libdvdcss.a
/***************************************************************************** /*****************************************************************************
* dvd_css.c: Functions for DVD authentification and unscrambling * css.c: Functions for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_css.c,v 1.33 2001/06/07 22:25:42 sam Exp $ * $Id: css.c,v 1.1 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -47,27 +47,20 @@ ...@@ -47,27 +47,20 @@
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
#include "threads.h"
#include "mtime.h"
#include "intf_msg.h" #include "videolan/dvdcss.h"
#include "libdvdcss.h"
#include "input_dvd.h"
#include "dvd_css.h"
#ifdef HAVE_CSS #ifdef HAVE_CSS
# include "dvd_csstables.h" # include "csstables.h"
#endif /* HAVE_CSS */ #endif /* HAVE_CSS */
#include "dvd_ioctl.h" #include "ioctl.h"
#include "modules.h"
#include "modules_export.h"
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
#ifdef HAVE_CSS #ifdef HAVE_CSS
static int CSSGetASF ( int i_fd ); static int CSSGetASF ( dvdcss_handle dvdcss );
static void CSSCryptKey ( int i_key_type, int i_varient, static void CSSCryptKey ( int i_key_type, int i_varient,
u8 const * pi_challenge, u8* pi_key ); u8 const * pi_challenge, u8* pi_key );
static int CSSCracker ( int i_start, unsigned char * p_crypted, static int CSSCracker ( int i_start, unsigned char * p_crypted,
...@@ -78,16 +71,16 @@ static int CSSCracker ( int i_start, unsigned char * p_crypted, ...@@ -78,16 +71,16 @@ static int CSSCracker ( int i_start, unsigned char * p_crypted,
/***************************************************************************** /*****************************************************************************
* CSSTest : check if the disc is encrypted or not * CSSTest : check if the disc is encrypted or not
*****************************************************************************/ *****************************************************************************/
int CSSTest( int i_fd ) int CSSTest( dvdcss_handle dvdcss )
{ {
int i_ret, i_copyright; int i_ret, i_copyright;
i_ret = ioctl_ReadCopyright( i_fd, 0 /* i_layer */, &i_copyright ); i_ret = ioctl_ReadCopyright( dvdcss->i_fd, 0 /* i_layer */, &i_copyright );
if( i_ret < 0 ) if( i_ret < 0 )
{ {
/* Since it's the first ioctl we try to issue, we add a notice */ /* Since it's the first ioctl we try to issue, we add a notice */
intf_ErrMsg( "css error: ioctl_ReadCopyright failed, " _dvdcss_error( dvdcss, "css error: ioctl_ReadCopyright failed, "
"make sure DVD ioctls were compiled in" ); "make sure DVD ioctls were compiled in" );
return i_ret; return i_ret;
...@@ -103,35 +96,37 @@ int CSSTest( int i_fd ) ...@@ -103,35 +96,37 @@ int CSSTest( int i_fd )
* Since we don't need the disc key to find the title key, we just run the * Since we don't need the disc key to find the title key, we just run the
* basic unavoidable commands to authenticate device and disc. * basic unavoidable commands to authenticate device and disc.
*****************************************************************************/ *****************************************************************************/
int CSSInit( int i_fd, css_t * p_css ) int CSSInit( dvdcss_handle dvdcss )
{ {
#ifdef HAVE_CSS #ifdef HAVE_CSS
/* structures defined in cdrom.h or dvdio.h */ /* structures defined in cdrom.h or dvdio.h */
char p_buffer[2048 + 4 + 1]; char p_buffer[2048 + 4 + 1];
char psz_warning[32];
int i_agid = 0; int i_agid = 0;
int i_ret = -1; int i_ret = -1;
int i; int i;
/* Test authentication success */ /* Test authentication success */
switch( CSSGetASF( i_fd ) ) switch( CSSGetASF( dvdcss ) )
{ {
case -1: case -1:
return -1; return -1;
case 1: case 1:
intf_WarnMsg( 2, "css info: already authenticated" ); _dvdcss_debug( dvdcss, "already authenticated" );
return 0; return 0;
case 0: case 0:
intf_WarnMsg( 2, "css info: need to authenticate" ); _dvdcss_debug( dvdcss, "need to authenticate" );
} }
/* Init sequence, request AGID */ /* Init sequence, request AGID */
for( i = 1; i < 4 ; ++i ) for( i = 1; i < 4 ; ++i )
{ {
intf_WarnMsg( 2, "css info: requesting AGID %d", i ); sprintf( psz_warning, "requesting AGID %d", i );
_dvdcss_debug( dvdcss, psz_warning );
i_ret = ioctl_ReportAgid( i_fd, &i_agid ); i_ret = ioctl_ReportAgid( dvdcss->i_fd, &i_agid );
if( i_ret != -1 ) if( i_ret != -1 )
{ {
...@@ -139,108 +134,113 @@ int CSSInit( int i_fd, css_t * p_css ) ...@@ -139,108 +134,113 @@ int CSSInit( int i_fd, css_t * p_css )
break; break;
} }
intf_ErrMsg( "css error: ioctl_ReportAgid failed, invalidating" ); _dvdcss_error( dvdcss, "ioctl_ReportAgid failed, invalidating" );
i_agid = 0; i_agid = 0;
ioctl_InvalidateAgid( i_fd, &i_agid ); ioctl_InvalidateAgid( dvdcss->i_fd, &i_agid );
} }
/* Unable to authenticate without AGID */ /* Unable to authenticate without AGID */
if( i_ret == -1 ) if( i_ret == -1 )
{ {
intf_ErrMsg( "css error: ioctl_ReportAgid failed, fatal" ); _dvdcss_error( dvdcss, "ioctl_ReportAgid failed, fatal" );
return -1; return -1;
} }
for( i = 0 ; i < 10; ++i ) for( i = 0 ; i < 10; ++i )
{ {
p_css->disc.pi_challenge[i] = i; dvdcss->css.disc.pi_challenge[i] = i;
} }
/* Get challenge from host */ /* Get challenge from host */
for( i = 0 ; i < 10 ; ++i ) for( i = 0 ; i < 10 ; ++i )
{ {
p_buffer[9-i] = p_css->disc.pi_challenge[i]; p_buffer[9-i] = dvdcss->css.disc.pi_challenge[i];
} }
/* Send challenge to LU */ /* Send challenge to LU */
if( ioctl_SendChallenge( i_fd, &i_agid, p_buffer ) < 0 ) if( ioctl_SendChallenge( dvdcss->i_fd, &i_agid, p_buffer ) < 0 )
{ {
intf_ErrMsg( "css error: ioctl_SendChallenge failed" ); _dvdcss_error( dvdcss, "ioctl_SendChallenge failed" );
return -1; return -1;
} }
/* Get key1 from LU */ /* Get key1 from LU */
if( ioctl_ReportKey1( i_fd, &i_agid, p_buffer ) < 0) if( ioctl_ReportKey1( dvdcss->i_fd, &i_agid, p_buffer ) < 0)
{ {
intf_ErrMsg( "css error: ioctl_ReportKey1 failed" ); _dvdcss_error( dvdcss, "ioctl_ReportKey1 failed" );
return -1; return -1;
} }
/* Send key1 to host */ /* Send key1 to host */
for( i = 0 ; i < KEY_SIZE ; i++ ) for( i = 0 ; i < KEY_SIZE ; i++ )
{ {
p_css->disc.pi_key1[i] = p_buffer[4-i]; dvdcss->css.disc.pi_key1[i] = p_buffer[4-i];
} }
for( i = 0 ; i < 32 ; ++i ) for( i = 0 ; i < 32 ; ++i )
{ {
CSSCryptKey( 0, i, p_css->disc.pi_challenge, CSSCryptKey( 0, i, dvdcss->css.disc.pi_challenge,
p_css->disc.pi_key_check ); dvdcss->css.disc.pi_key_check );
if( memcmp( p_css->disc.pi_key_check, if( memcmp( dvdcss->css.disc.pi_key_check,
p_css->disc.pi_key1, KEY_SIZE ) == 0 ) dvdcss->css.disc.pi_key1, KEY_SIZE ) == 0 )
{ {
intf_WarnMsg( 2, "css info: drive authentic, using variant %d", i); sprintf( psz_warning, "drive authentic, using variant %d", i );
p_css->disc.i_varient = i; _dvdcss_debug( dvdcss, psz_warning );
dvdcss->css.disc.i_varient = i;
break; break;
} }
} }
if( i == 32 ) if( i == 32 )
{ {
intf_ErrMsg( "css error: drive would not authenticate" ); _dvdcss_error( dvdcss, "drive would not authenticate" );
return -1; return -1;
} }
/* Get challenge from LU */ /* Get challenge from LU */
if( ioctl_ReportChallenge( i_fd, &i_agid, p_buffer ) < 0 ) if( ioctl_ReportChallenge( dvdcss->i_fd, &i_agid, p_buffer ) < 0 )
{ {
intf_ErrMsg( "css error: ioctl_ReportKeyChallenge failed" ); _dvdcss_error( dvdcss, "ioctl_ReportKeyChallenge failed" );
return -1; return -1;
} }
/* Send challenge to host */ /* Send challenge to host */
for( i = 0 ; i < 10 ; ++i ) for( i = 0 ; i < 10 ; ++i )
{ {
p_css->disc.pi_challenge[i] = p_buffer[9-i]; dvdcss->css.disc.pi_challenge[i] = p_buffer[9-i];
} }
CSSCryptKey( 1, p_css->disc.i_varient, p_css->disc.pi_challenge, CSSCryptKey( 1, dvdcss->css.disc.i_varient,
p_css->disc.pi_key2 ); dvdcss->css.disc.pi_challenge,
dvdcss->css.disc.pi_key2 );
/* Get key2 from host */ /* Get key2 from host */
for( i = 0 ; i < KEY_SIZE ; ++i ) for( i = 0 ; i < KEY_SIZE ; ++i )
{ {
p_buffer[4-i] = p_css->disc.pi_key2[i]; p_buffer[4-i] = dvdcss->css.disc.pi_key2[i];
} }
/* Send key2 to LU */ /* Send key2 to LU */
if( ioctl_SendKey2( i_fd, &i_agid, p_buffer ) < 0 ) if( ioctl_SendKey2( dvdcss->i_fd, &i_agid, p_buffer ) < 0 )
{ {
intf_ErrMsg( "css error: ioctl_SendKey2 failed" ); _dvdcss_error( dvdcss, "ioctl_SendKey2 failed" );
return -1; return -1;
} }
intf_WarnMsg( 2, "css info: authentication established" ); _dvdcss_debug( dvdcss, "authentication established" );
memcpy( p_css->disc.pi_challenge, p_css->disc.pi_key1, KEY_SIZE ); memcpy( dvdcss->css.disc.pi_challenge,
memcpy( p_css->disc.pi_challenge+KEY_SIZE, p_css->disc.pi_key2, KEY_SIZE ); dvdcss->css.disc.pi_key1, KEY_SIZE );
memcpy( dvdcss->css.disc.pi_challenge+KEY_SIZE,
dvdcss->css.disc.pi_key2, KEY_SIZE );
CSSCryptKey( 2, p_css->disc.i_varient, p_css->disc.pi_challenge, CSSCryptKey( 2, dvdcss->css.disc.i_varient,
p_css->disc.pi_key_check ); dvdcss->css.disc.pi_challenge,
dvdcss->css.disc.pi_key_check );
intf_WarnMsg( 2, "css info: received session key" ); _dvdcss_debug( dvdcss, "received session key" );
if( i_agid < 0 ) if( i_agid < 0 )
{ {
...@@ -248,56 +248,56 @@ int CSSInit( int i_fd, css_t * p_css ) ...@@ -248,56 +248,56 @@ int CSSInit( int i_fd, css_t * p_css )
} }
/* Test authentication success */ /* Test authentication success */
switch( CSSGetASF( i_fd ) ) switch( CSSGetASF( dvdcss ) )
{ {
case -1: case -1:
return -1; return -1;
case 1: case 1:
intf_WarnMsg( 2, "css info: already authenticated" ); _dvdcss_debug( dvdcss, "already authenticated" );
return 0; return 0;
case 0: case 0:
intf_WarnMsg( 2, "css info: need to get disc key" ); _dvdcss_debug( dvdcss, "need to get disc key" );
} }
/* Get encrypted disc key */ /* Get encrypted disc key */
if( ioctl_ReadKey( i_fd, &i_agid, p_buffer ) < 0 ) if( ioctl_ReadKey( dvdcss->i_fd, &i_agid, p_buffer ) < 0 )
{ {
intf_ErrMsg( "css error: ioctl_ReadKey failed" ); _dvdcss_error( dvdcss, "ioctl_ReadKey failed" );
return -1; return -1;
} }
/* Unencrypt disc key using bus key */ /* Unencrypt disc key using bus key */
for( i = 0 ; i < 2048 ; i++ ) for( i = 0 ; i < 2048 ; i++ )
{ {
p_buffer[ i ] ^= p_css->disc.pi_key_check[ 4 - (i % KEY_SIZE) ]; p_buffer[ i ] ^= dvdcss->css.disc.pi_key_check[ 4 - (i % KEY_SIZE) ];
} }
memcpy( p_css->disc.pi_key_check, p_buffer, 2048 ); memcpy( dvdcss->css.disc.pi_key_check, p_buffer, 2048 );
/* initialize title key to know it empty */ /* initialize title key to know it empty */
for( i = 0 ; i < KEY_SIZE ; i++ ) for( i = 0 ; i < KEY_SIZE ; i++ )
{ {
p_css->pi_title_key[i] = 0; dvdcss->css.pi_title_key[i] = 0;
} }
/* Test authentication success */ /* Test authentication success */
switch( CSSGetASF( i_fd ) ) switch( CSSGetASF( dvdcss ) )
{ {
case -1: case -1:
return -1; return -1;
case 1: case 1:
intf_WarnMsg( 2, "css info: successfully authenticated" ); _dvdcss_debug( dvdcss, "successfully authenticated" );
return 0; return 0;
case 0: case 0:
intf_ErrMsg( "css error: no way to authenticate" ); _dvdcss_error( dvdcss, "no way to authenticate" );
return -1; return -1;
} }
#else /* HAVE_CSS */ #else /* HAVE_CSS */
intf_ErrMsg( "css error: CSS decryption is disabled in this module" ); _dvdcss_error( dvdcss, "CSS decryption is disabled in this module" );
#endif /* HAVE_CSS */ #endif /* HAVE_CSS */
return -1; return -1;
...@@ -309,7 +309,7 @@ int CSSInit( int i_fd, css_t * p_css ) ...@@ -309,7 +309,7 @@ int CSSInit( int i_fd, css_t * p_css )
***************************************************************************** *****************************************************************************
* The DVD should have been opened and authenticated before. * The DVD should have been opened and authenticated before.
*****************************************************************************/ *****************************************************************************/
int CSSGetKey( int i_fd, css_t * p_css ) int CSSGetKey( dvdcss_handle dvdcss )
{ {
#ifdef HAVE_CSS #ifdef HAVE_CSS
/* /*
...@@ -336,15 +336,15 @@ int CSSGetKey( int i_fd, css_t * p_css ) ...@@ -336,15 +336,15 @@ int CSSGetKey( int i_fd, css_t * p_css )
b_stop_scanning = 0; b_stop_scanning = 0;
/* Position of the title on the disc */ /* Position of the title on the disc */
i_pos = p_css->i_title_pos; i_pos = (off_t)DVDCSS_BLOCK_SIZE * (off_t)dvdcss->css.i_title_pos;
do { do {
#if !defined( WIN32 ) #if !defined( WIN32 )
i_pos = lseek( i_fd, i_pos, SEEK_SET ); i_pos = lseek( dvdcss->i_fd, i_pos, SEEK_SET );
i_bytes_read = read( i_fd, pi_buf, 0x800 ); i_bytes_read = read( dvdcss->i_fd, pi_buf, 0x800 );
#else #else
i_pos = SetFilePointer( (HANDLE) i_fd, i_pos, 0, FILE_BEGIN ); i_pos = SetFilePointer( (HANDLE) dvdcss->i_fd, i_pos, 0, FILE_BEGIN );
ReadFile( (HANDLE) i_fd, pi_buf, 0x800, &i_bytes_read, NULL ); ReadFile( (HANDLE) dvdcss->i_fd, pi_buf, 0x800, &i_bytes_read, NULL );
#endif #endif
/* PES_scrambling_control */ /* PES_scrambling_control */
...@@ -382,22 +382,22 @@ int CSSGetKey( int i_fd, css_t * p_css ) ...@@ -382,22 +382,22 @@ int CSSGetKey( int i_fd, css_t * p_css )
if( b_stop_scanning) if( b_stop_scanning)
{ {
memcpy( p_css->pi_title_key, memcpy( dvdcss->css.pi_title_key,
&pi_key, sizeof(dvd_key_t) ); &pi_key, sizeof(dvd_key_t) );
intf_WarnMsg( 2, "css info: vts key initialized" ); _dvdcss_debug( dvdcss, "vts key initialized" );
return 0; return 0;
} }
if( !b_encrypted ) if( !b_encrypted )
{ {
intf_WarnMsg( 2, "css warning: this file was _NOT_ encrypted!" ); _dvdcss_debug( dvdcss, "this file was _NOT_ encrypted!" );
return 0; return 0;
} }
return -1; return -1;
#else /* HAVE_CSS */ #else /* HAVE_CSS */
intf_ErrMsg( "css error: css decryption unavailable" ); _dvdcss_error( dvdcss, "css decryption unavailable" );
return -1; return -1;
#endif /* HAVE_CSS */ #endif /* HAVE_CSS */
...@@ -465,24 +465,30 @@ int CSSDescrambleSector( dvd_key_t pi_key, u8* pi_sec ) ...@@ -465,24 +465,30 @@ int CSSDescrambleSector( dvd_key_t pi_key, u8* pi_sec )
* 0 if the device needs to be authenticated, * 0 if the device needs to be authenticated,
* 1 either. * 1 either.
*****************************************************************************/ *****************************************************************************/
static int CSSGetASF( int i_fd ) static int CSSGetASF( dvdcss_handle dvdcss )
{ {
int i_agid; int i_agid;
int i_asf = 0; int i_asf = 0;
for( i_agid = 0 ; i_agid < 4 ; i_agid++ ) for( i_agid = 0 ; i_agid < 4 ; i_agid++ )
{ {
if( ioctl_ReportASF( i_fd, &i_agid, &i_asf ) == 0 ) if( ioctl_ReportASF( dvdcss->i_fd, &i_agid, &i_asf ) == 0 )
{
if( i_asf )
{ {
intf_WarnMsg( 3, "css info: GetASF %sauthenticated", _dvdcss_debug( dvdcss, "GetASF authenticated" );
i_asf ? "":"not " ); }
else
{
_dvdcss_debug( dvdcss, "GetASF not authenticated" );
}
return i_asf; return i_asf;
} }
} }
/* The ioctl process has failed */ /* The ioctl process has failed */
intf_ErrMsg( "css error: GetASF fatal error" ); _dvdcss_error( dvdcss, "GetASF fatal error" );
return -1; return -1;
} }
......
/***************************************************************************** /*****************************************************************************
* dvd_css.h: Structures for DVD authentification and unscrambling * css.h: Structures for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_css.h,v 1.8 2001/05/19 00:39:29 stef Exp $ * $Id: css.h,v 1.1 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -60,7 +60,8 @@ typedef struct css_s ...@@ -60,7 +60,8 @@ typedef struct css_s
*****************************************************************************/ *****************************************************************************/
struct css_s; struct css_s;
int CSSTest ( int ); int CSSTest ( dvdcss_handle );
int CSSInit ( int, struct css_s * ); int CSSInit ( dvdcss_handle );
int CSSGetKey ( int, struct css_s * ); int CSSGetKey ( dvdcss_handle );
int CSSDescrambleSector ( u8 * , u8 * ); int CSSDescrambleSector ( u8 * , u8 * );
/***************************************************************************** /*****************************************************************************
* dvd_csstables.h: CSS Tables for DVD unscrambling * csstables.h: CSS Tables for DVD unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_csstables.h,v 1.1 2001/03/02 13:47:01 sam Exp $ * $Id: csstables.h,v 1.1 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
......
/***************************************************************************** /*****************************************************************************
* dvd_ioctl.c: DVD ioctl replacement function * ioctl.c: DVD ioctl replacement function
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ioctl.c,v 1.17 2001/06/03 12:47:21 sam Exp $ * $Id: ioctl.c,v 1.1 2001/06/12 22:14:44 sam Exp $
* *
* Authors: Markus Kuespert <ltlBeBoy@beosmail.com> * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -55,20 +55,12 @@ ...@@ -55,20 +55,12 @@
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
#include "threads.h"
#include "mtime.h"
#include "intf_msg.h"
#ifdef SYS_DARWIN1_3 #ifdef SYS_DARWIN1_3
# include "DVDioctl/DVDioctl.h" # include "DVDioctl/DVDioctl.h"
#endif #endif
#include "dvd_css.h" #include "ioctl.h"
#include "dvd_ioctl.h"
#include "modules.h"
#include "modules_export.h"
/***************************************************************************** /*****************************************************************************
* Local prototypes, BeOS specific * Local prototypes, BeOS specific
...@@ -115,8 +107,8 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright ) ...@@ -115,8 +107,8 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
*pi_copyright = p_buffer[ 4 ]; *pi_copyright = p_buffer[ 4 ];
#elif defined( SYS_DARWIN1_3 ) #elif defined( SYS_DARWIN1_3 )
intf_ErrMsg( "css error: DVD ioctls not fully functional yet" ); _dvd_error( dvdcss, "DVD ioctls not fully functional yet, "
intf_ErrMsg( "css error: assuming disc is encrypted" ); "assuming disc is encrypted" );
*pi_copyright = 1; *pi_copyright = 1;
...@@ -159,8 +151,8 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright ) ...@@ -159,8 +151,8 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
else else
{ {
/* TODO: add WNASPI support for Win9x */ /* TODO: add WNASPI support for Win9x */
intf_ErrMsg( "css error: DVD ioctls not functional yet" ); _dvd_error( dvdcss, "DVD ioctls not functional yet, "
intf_ErrMsg( "css error: assuming disc is unencrypted" ); "assuming disc is unencrypted" );
*pi_copyright = 0; *pi_copyright = 0;
i_ret = 0; i_ret = 0;
} }
...@@ -228,8 +220,8 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -228,8 +220,8 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key )
memcpy( p_key, p_buffer + 4, 2048 ); memcpy( p_key, p_buffer + 4, 2048 );
#elif defined( SYS_DARWIN1_3 ) #elif defined( SYS_DARWIN1_3 )
intf_ErrMsg( "css error: DVD ioctls not fully functional yet" ); _dvd_error( dvdcss, "DVD ioctls not fully functional yet, "
intf_ErrMsg( "css error: sending an empty key" ); "sending an empty key" );
i_ret = 0; i_ret = 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ioctl.h: DVD ioctl replacement function * dvd_ioctl.h: DVD ioctl replacement function
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ioctl.h,v 1.10 2001/05/31 03:57:54 sam Exp $ * $Id: ioctl.h,v 1.1 2001/06/12 22:14:44 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
......
/*****************************************************************************
* libdvdcss.c: DVD reading library.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: libdvdcss.c,v 1.1 2001/06/12 22:14:44 sam Exp $
*
* Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#if defined( WIN32 )
# include <io.h>
# include "input_iovec.h"
#else
# include <sys/uio.h> /* struct iovec */
#endif
#include "config.h"
#include "common.h"
#include "videolan/dvdcss.h"
#include "libdvdcss.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int _dvdcss_open ( dvdcss_handle, char *psz_target );
static int _dvdcss_close ( dvdcss_handle );
static int _dvdcss_seek ( dvdcss_handle, int i_blocks );
static int _dvdcss_read ( dvdcss_handle, void *p_buffer, int i_blocks );
static int _dvdcss_readv ( dvdcss_handle, struct iovec *p_iovec, int i_blocks );
/*****************************************************************************
* dvdcss_init: initialize libdvdcss
*****************************************************************************/
extern dvdcss_handle dvdcss_init ( int i_flags )
{
dvdcss_handle dvdcss;
/* Allocate the library structure */
dvdcss = malloc( sizeof( struct dvdcss_s ) );
if( dvdcss == NULL )
{
if( ! (i_flags & DVDCSS_INIT_QUIET) )
{
DVDCSS_ERROR( "could not initialize library" );
}
return NULL;
}
/* Initialize structure */
dvdcss->i_status = DVDCSS_STATUS_NONE;
dvdcss->b_debug = i_flags & DVDCSS_INIT_DEBUG;
dvdcss->b_errors = !(i_flags & DVDCSS_INIT_QUIET);
dvdcss->psz_error = "no error";
/* XXX: additional initialization stuff might come here */
dvdcss->i_status |= DVDCSS_STATUS_INIT;
return dvdcss;
}
/*****************************************************************************
* dvdcss_error: return the last libdvdcss error message
*****************************************************************************/
extern char * dvdcss_error ( dvdcss_handle dvdcss )
{
return dvdcss->psz_error;
}
/*****************************************************************************
* dvdcss_open: open a DVD device, crack CSS key if disc is encrypted
*****************************************************************************/
extern int dvdcss_open ( dvdcss_handle dvdcss, char *psz_target )
{
int i_ret;
if( ! (dvdcss->i_status & DVDCSS_STATUS_INIT) )
{
_dvdcss_error( dvdcss, "library not initialized" );
return -1;
}
if( dvdcss->i_status & DVDCSS_STATUS_OPEN )
{
_dvdcss_error( dvdcss, "a device is already opened" );
return -1;
}
i_ret = _dvdcss_open( dvdcss, psz_target );
if( i_ret < 0 )
{
return i_ret;
}
i_ret = CSSTest( dvdcss );
if( i_ret < 0 )
{
_dvdcss_error( dvdcss, "css test failed" );
_dvdcss_close( dvdcss );
return i_ret;
}
dvdcss->b_encrypted = i_ret;
/* If drive is encrypted, crack its key */
if( dvdcss->b_encrypted )
{
i_ret = CSSInit( dvdcss );
if( i_ret < 0 )
{
_dvdcss_close( dvdcss );
return i_ret;
}
}
dvdcss->i_status |= DVDCSS_STATUS_OPEN;
return 0;
}
/*****************************************************************************
* dvdcss_seek: seek into the device
*****************************************************************************/
extern int dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks )
{
if( ! (dvdcss->i_status & DVDCSS_STATUS_OPEN) )
{
_dvdcss_error( dvdcss, "no device opened" );
return -1;
}
return _dvdcss_seek( dvdcss, i_blocks );
}
/*****************************************************************************
* dvdcss_crack: crack the current title key
*****************************************************************************/
extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_title, int i_block )
{
int i_ret;
if( ! (dvdcss->i_status & DVDCSS_STATUS_OPEN) )
{
_dvdcss_error( dvdcss, "no device opened" );
return -1;
}
if( ! dvdcss->b_encrypted )
{
return 0;
}
/* Crack CSS title key for current VTS */
dvdcss->css.i_title = i_title;
dvdcss->css.i_title_pos = i_block;
i_ret = CSSGetKey( dvdcss );
if( i_ret < 0 )
{
_dvdcss_error( dvdcss, "fatal error in vts css key" );
return i_ret;
}
else if( i_ret > 0 )
{
_dvdcss_error( dvdcss, "decryption unavailable" );
return -1;
}
return 0;
}
/*****************************************************************************
* dvdcss_read: read data from the device, decrypt if requested
*****************************************************************************/
extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer,
int i_blocks,
int i_flags )
{
int i_ret;
if( ! (dvdcss->i_status & DVDCSS_STATUS_OPEN) )
{
_dvdcss_error( dvdcss, "no device opened" );
return -1;
}
i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks );
if( i_ret != i_blocks
|| !dvdcss->b_encrypted
|| !(i_flags & DVDCSS_READ_DECRYPT) )
{
return i_ret;
}
while( i_ret )
{
CSSDescrambleSector( dvdcss->css.pi_title_key, p_buffer );
((u8*)p_buffer)[0x14] &= 0x8f;
(u8*)p_buffer += DVDCSS_BLOCK_SIZE;
i_ret--;
}
return i_blocks;
}
/*****************************************************************************
* dvdcss_readv: read data to an iovec structure, decrypt if reaquested
*****************************************************************************/
extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
int i_blocks,
int i_flags )
{
#define P_IOVEC ((struct iovec*)p_iovec)
int i_ret;
void *iov_base;
size_t iov_len;
if( ! (dvdcss->i_status & DVDCSS_STATUS_OPEN) )
{
_dvdcss_error( dvdcss, "no device opened" );
return -1;
}
i_ret = _dvdcss_readv( dvdcss, P_IOVEC, i_blocks );
if( i_ret != i_blocks
|| !dvdcss->b_encrypted
|| !(i_flags & DVDCSS_READ_DECRYPT) )
{
return i_ret;
}
/* Initialize loop for decryption */
iov_base = P_IOVEC->iov_base;
iov_len = P_IOVEC->iov_len;
while( i_ret )
{
/* Check that iov_len is a multiple of 2048 */
if( iov_len & 0x7ff )
{
return -1;
}
while( iov_len == 0 )
{
P_IOVEC++;
iov_base = P_IOVEC->iov_base;
iov_len = P_IOVEC->iov_len;
}
CSSDescrambleSector( dvdcss->css.pi_title_key, iov_base );
((u8*)iov_base)[0x14] &= 0x8f;
(u8*)iov_base += DVDCSS_BLOCK_SIZE;
(u8*)iov_len -= DVDCSS_BLOCK_SIZE;
i_ret--;
}
return i_blocks;
#undef P_IOVEC
}
/*****************************************************************************
* dvdcss_close: close the DVD device
*****************************************************************************/
extern int dvdcss_close ( dvdcss_handle dvdcss )
{
int i_ret;
if( ! (dvdcss->i_status & DVDCSS_STATUS_OPEN) )
{
_dvdcss_error( dvdcss, "no device opened" );
return -1;
}
i_ret = _dvdcss_close( dvdcss );
if( i_ret < 0 )
{
return i_ret;
}
dvdcss->i_status &= ~DVDCSS_STATUS_OPEN;
return 0;
}
/*****************************************************************************
* dvdcss_end: clean up the library
*****************************************************************************/
extern int dvdcss_end ( dvdcss_handle dvdcss )
{
if( dvdcss->i_status & DVDCSS_STATUS_OPEN )
{
_dvdcss_error( dvdcss, "a device is still open" );
return -1;
}
free( dvdcss );
return 0;
}
/* Following functions are local */
static int _dvdcss_open ( dvdcss_handle dvdcss, char *psz_target )
{
#if defined( WIN32 )
snprintf( buf, 7, "\\\\.\\%c:", psz_target[0] );
(HANDLE) dvdcss->i_fd =
CreateFile( psz_target, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL );
if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE )
{
_dvdcss_error( dvdcss, "failed opening device" );
return -1;
}
#else
dvdcss->i_fd = open( psz_target, 0 );
if( dvdcss->i_fd == -1 )
{
_dvdcss_error( dvdcss, "failed opening device" );
return -1;
}
#endif
return 0;
}
static int _dvdcss_close ( dvdcss_handle dvdcss )
{
#if defined( WIN32 )
CloseHandle( (HANDLE) dvdcss->i_fd );
#else
close( dvdcss->i_fd );
#endif
return 0;
}
static int _dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks )
{
off_t i_read;
#if defined( WIN32 )
i_read = SetFilePointer( (HANDLE) dvdcss->i_fd,
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE,
NULL, FILE_BEGIN );
#else
i_read = lseek( dvdcss->i_fd,
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE, SEEK_SET );
#endif
return i_read / DVDCSS_BLOCK_SIZE;
}
static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks )
{
#if defined( WIN32 )
DWORD i_read;
if( ReadFile( (HANDLE) dvdcss->i_fd, p_buffer,
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE,
&i_read, NULL ) == -1 )
{
return 0;
}
#else
off_t i_read;
i_read = read( dvdcss->i_fd, p_buffer,
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE );
#endif
return i_read / DVDCSS_BLOCK_SIZE;
}
static int _dvdcss_readv ( dvdcss_handle dvdcss, struct iovec *p_iovec, int i_blocks )
{
off_t i_read;
i_read = readv( dvdcss->i_fd, p_iovec, i_blocks );
return i_read / DVDCSS_BLOCK_SIZE;
}
/*****************************************************************************
* private.h: private DVD reading library data
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: libdvdcss.h,v 1.1 2001/06/12 22:14:44 sam Exp $
*
* Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Needed headers
*****************************************************************************/
#include "css.h"
/*****************************************************************************
* The libdvdcss structure
*****************************************************************************/
struct dvdcss_s
{
/* Status */
int i_status;
/* File descriptor */
int i_fd;
/* Decryption stuff */
css_t css;
boolean_t b_encrypted;
/* Error management */
char *psz_error;
boolean_t b_errors;
boolean_t b_debug;
};
/*****************************************************************************
* Flags
*****************************************************************************/
#define DVDCSS_STATUS_NONE 0
#define DVDCSS_STATUS_INIT 1 << 0
#define DVDCSS_STATUS_OPEN 1 << 1
/*****************************************************************************
* Error management
*****************************************************************************/
#define DVDCSS_ERROR( x... ) fprintf( stderr, "libdvdcss error: %s\n", ##x );
#define DVDCSS_DEBUG( x... ) fprintf( stderr, "libdvdcss debug: %s\n", ##x );
static __inline__ void _dvdcss_error( dvdcss_handle dvdcss, char *psz_string )
{
if( dvdcss->b_errors )
{
DVDCSS_ERROR( psz_string );
}
dvdcss->psz_error = psz_string;
}
static __inline__ void _dvdcss_debug( dvdcss_handle dvdcss, char *psz_string )
{
if( dvdcss->b_debug )
{
DVDCSS_DEBUG( psz_string );
}
}
/*****************************************************************************
* libdvdcss.h: DVD reading library, exported functions.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: dvdcss.h,v 1.1 2001/06/12 22:14:44 sam Exp $
*
* Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* The libdvdcss structure
*****************************************************************************/
typedef struct dvdcss_s* dvdcss_handle;
/*****************************************************************************
* Flags
*****************************************************************************/
#define DVDCSS_NOFLAGS 0
#define DVDCSS_INIT_QUIET 1 << 0
#define DVDCSS_INIT_DEBUG 1 << 1
#define DVDCSS_READ_DECRYPT 1 << 0
#define DVDCSS_BLOCK_SIZE 2048
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
extern dvdcss_handle dvdcss_init ( int i_flags );
extern int dvdcss_end ( dvdcss_handle );
extern int dvdcss_open ( dvdcss_handle,
char *psz_target );
extern int dvdcss_close ( dvdcss_handle );
extern int dvdcss_crack ( dvdcss_handle,
int i_title,
int i_block );
extern int dvdcss_seek ( dvdcss_handle,
int i_blocks );
extern int dvdcss_read ( dvdcss_handle,
void *p_buffer,
int i_blocks,
int i_flags );
extern int dvdcss_readv ( dvdcss_handle,
void *p_iovec,
int i_blocks,
int i_flags );
extern char * dvdcss_error ( dvdcss_handle );
...@@ -30,7 +30,6 @@ struct iovec ...@@ -30,7 +30,6 @@ struct iovec
size_t iov_len; /* Length of data. */ size_t iov_len; /* Length of data. */
}; };
#if defined( WIN32 )
/***************************************************************************** /*****************************************************************************
* readv: readv() replacement for iovec-impaired C libraries * readv: readv() replacement for iovec-impaired C libraries
*****************************************************************************/ *****************************************************************************/
...@@ -86,4 +85,3 @@ static __inline int readv( int i_fd, struct iovec *p_iovec, int i_count ) ...@@ -86,4 +85,3 @@ static __inline int readv( int i_fd, struct iovec *p_iovec, int i_count )
return i_total; return i_total;
} }
#endif
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
# Objects # Objects
# #
PLUGIN_C = dvd.o input_dvd.o dvd_netlist.o dvd_ioctl.o dvd_ifo.o dvd_udf.o dvd_css.o dvd_summary.o PLUGIN_DVD = dvd.o input_dvd.o dvd_netlist.o dvd_ifo.o dvd_udf.o dvd_summary.o
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o) BUILTIN_DVD = $(PLUGIN_DVD:%.o=BUILTIN_%.o)
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C) ALL_OBJ = $(PLUGIN_DVD) $(BUILTIN_DVD)
# #
# Virtual targets # Virtual targets
...@@ -18,14 +18,25 @@ ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C) ...@@ -18,14 +18,25 @@ ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C)
include ../../Makefile.modules include ../../Makefile.modules
$(PLUGIN_DVD): %.o: .dep/%.d
$(PLUGIN_DVD): %.o: %.c
$(CC) $(CFLAGS) $(PCFLAGS) $(CFLAGS_DVD) -DPLUGIN -c -o $@ $<
$(BUILTIN_DVD): BUILTIN_%.o: .dep/%.d
$(BUILTIN_DVD): BUILTIN_%.o: %.c
$(CC) $(CFLAGS) $(CFLAGS_DVD) -DBUILTIN -c -o $@ $<
# #
# Real targets # Real targets
# #
../../lib/dvd.so: $(PLUGIN_C) ../../lib/dvd.so: libdvdcss $(PLUGIN_DVD)
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) $(CC) $(PCFLAGS) -o $@ $(PLUGIN_DVD) $(PLCFLAGS) $(LIB_DVD)
../../lib/dvd.a: $(BUILTIN_C) ../../lib/dvd.a: libdvdcss $(BUILTIN_DVD)
ar r $@ $^ ar r $@ $(BUILTIN_DVD)
$(RANLIB) $@ $(RANLIB) $@
libdvdcss:
cd ../../ && $(MAKE) libdvdcss
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ifo.c: Functions for ifo parsing * dvd_ifo.c: Functions for ifo parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.c,v 1.32 2001/06/07 22:25:42 sam Exp $ * $Id: dvd_ifo.c,v 1.33 2001/06/12 22:14:44 sam Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* German Tischler <tanis@gaspode.franken.de> * German Tischler <tanis@gaspode.franken.de>
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
#include <string.h> #include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include <videolan/dvdcss.h>
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
#include "threads.h" #include "threads.h"
...@@ -63,183 +65,30 @@ ...@@ -63,183 +65,30 @@
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
void CommandRead ( command_desc_t ); void CommandRead ( command_desc_t );
static int ReadTitle ( ifo_t * , title_t *, off_t ); static int ReadTitle ( ifo_t * , title_t *, int, int );
static int FreeTitle ( title_t * ); static int FreeTitle ( title_t * );
static int ReadUnitInf ( ifo_t * , unit_inf_t *, off_t ); static int ReadUnitInf ( ifo_t * , unit_inf_t *, int, int );
static int FreeUnitInf ( unit_inf_t * ); static int FreeUnitInf ( unit_inf_t * );
static int ReadTitleUnit ( ifo_t * , title_unit_t *, off_t ); static int ReadTitleUnit ( ifo_t * , title_unit_t *, int );
static int FreeTitleUnit ( title_unit_t * ); static int FreeTitleUnit ( title_unit_t * );
static int ReadVobuMap ( ifo_t * , vobu_map_t *, off_t ); static int ReadVobuMap ( ifo_t * , vobu_map_t *, int );
static int FreeVobuMap ( vobu_map_t * ); static int FreeVobuMap ( vobu_map_t * );
static int ReadCellInf ( ifo_t * , cell_inf_t *, off_t ); static int ReadCellInf ( ifo_t * , cell_inf_t *, int );
static int FreeCellInf ( cell_inf_t * ); static int FreeCellInf ( cell_inf_t * );
static int FreeTitleSet ( vts_t * ); static int FreeTitleSet ( vts_t * );
/***************************************************************************** static u8* FillBuffer ( ifo_t *, u8 *, int );
* ReadByte and so static u8 ReadByte ( ifo_t *, u8 *, u8 ** );
*****************************************************************************/ static void ReadBytes ( ifo_t *, u8 *, u8 **, u8 *, int );
static __inline__ u8* FillBuffer( ifo_t* p_ifo, u8* pi_buffer, off_t i_pos ) static void DumpBytes ( ifo_t *, u8 *, u8 **, int );
{ static u16 ReadWord ( ifo_t *, u8 *, u8 ** );
#if defined( WIN32 ) static u32 ReadDouble ( ifo_t *, u8 *, u8 ** );
DWORD tmp; static u64 ReadQuad ( ifo_t *, u8 *, u8 ** );
#endif
memset( pi_buffer, 0, DVD_LB_SIZE );
#if defined( WIN32 )
p_ifo->i_pos = SetFilePointer( (HANDLE) p_ifo->i_fd, i_pos,
NULL, FILE_BEGIN );
ReadFile( (HANDLE) p_ifo->i_fd, pi_buffer, DVD_LB_SIZE, &tmp, NULL );
#elif defined(__FreeBSD__)
if ( i_pos & ( DVD_LB_SIZE - 1 ) )
{
off_t i_relpos = i_pos & ( DVD_LB_SIZE - 1 );
off_t i_newpos = i_pos & ~( DVD_LB_SIZE - 1 );
if ( lseek(p_ifo->i_fd, i_newpos, SEEK_SET) == -1 )
{
intf_WarnMsg( 2, "input warning: seek failure" );
p_ifo->i_pos = -1;
return pi_buffer;
}
if ( read(p_ifo->i_fd, p_ifo->p_remap, DVD_LB_SIZE) == -1 )
{
intf_WarnMsg( 2, "input warning: first chunk read failure" );
p_ifo->i_pos = -1;
return pi_buffer;
}
if ( lseek(p_ifo->i_fd, i_newpos + DVD_LB_SIZE, SEEK_SET) == -1 )
{
intf_WarnMsg( 2, "input warning: seek failure" );
p_ifo->i_pos = -1;
return pi_buffer;
}
if ( read(p_ifo->i_fd, (p_ifo->p_remap + DVD_LB_SIZE),
DVD_LB_SIZE) == -1 )
{
intf_WarnMsg( 2, "input warning: second chunk read failure" );
p_ifo->i_pos = -1;
return pi_buffer;
}
memcpy( pi_buffer, p_ifo->p_remap + i_relpos,
( DVD_LB_SIZE - i_relpos ) );
memcpy( pi_buffer + ( DVD_LB_SIZE - i_relpos ),
( p_ifo->p_remap + DVD_LB_SIZE ), i_relpos );
p_ifo->i_pos = i_pos;
}
else
{
p_ifo->i_pos = lseek( p_ifo->i_fd, i_pos, SEEK_SET );
read( p_ifo->i_fd, pi_buffer, DVD_LB_SIZE );
}
#else
p_ifo->i_pos = lseek( p_ifo->i_fd, i_pos, SEEK_SET );
read( p_ifo->i_fd, pi_buffer, DVD_LB_SIZE );
#endif
return pi_buffer;
}
static __inline__ u8 ReadByte( ifo_t * p_ifo, u8* pi_buffer, u8** pp_current )
{
u8 i_ret;
if( *pp_current > pi_buffer + DVD_LB_SIZE )
{
*pp_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_pos + DVD_LB_SIZE );
}
i_ret = *(*pp_current)++;
return i_ret;
}
static __inline__ u16 ReadWord( ifo_t* p_ifo, u8* pi_buffer, u8** pp_current )
{
u16 i_ret;
if( *pp_current > pi_buffer + DVD_LB_SIZE - 2 )
{
*pp_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_pos + DVD_LB_SIZE );
}
i_ret = U16_AT(*pp_current);
(*pp_current) += 2;
return i_ret;
}
static __inline__ u32 ReadDouble( ifo_t * p_ifo, u8* pi_buffer,
u8** pp_current )
{
u32 i_ret;
if( *pp_current > pi_buffer + DVD_LB_SIZE - 4 )
{
*pp_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_pos + DVD_LB_SIZE);
// intf_WarnMsg( 1, "new buffer in double @ %lld", p_ifo->i_pos );
}
i_ret = U32_AT(*pp_current);
(*pp_current) += 4;
return i_ret;
}
static __inline__ u64 ReadQuad( ifo_t* p_ifo, u8* pi_buffer, u8** pp_current )
{
u64 i_ret;
if( *pp_current > pi_buffer + DVD_LB_SIZE - 8 )
{
*pp_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_pos + DVD_LB_SIZE );
}
i_ret = U64_AT(*pp_current);
(*pp_current) += 8;
return i_ret;
}
static __inline__ void ReadBits( ifo_t* p_ifo, u8* pi_buffer, u8** pp_current,
u8* pi_dest, int i_nb )
{
if( *pp_current > pi_buffer + DVD_LB_SIZE - i_nb )
{
*pp_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_pos + DVD_LB_SIZE );
}
memcpy( pi_dest, *pp_current, i_nb );
*pp_current += i_nb;
return;
}
static __inline__ void DumpBits( ifo_t* p_ifo, u8* pi_buffer,
u8** pp_current, int i_nb )
{
if( *pp_current > pi_buffer + DVD_LB_SIZE - i_nb )
{
*pp_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_pos + DVD_LB_SIZE );
}
*pp_current += i_nb;
return;
}
/* /*
* IFO Management. * IFO Management.
*/ */
/***************************************************************************** /*****************************************************************************
* IfoCreate : Creates an ifo structure and prepares for parsing directly * IfoCreate : Creates an ifo structure and prepares for parsing directly
* on DVD device * on DVD device
...@@ -254,7 +103,7 @@ int IfoCreate( thread_dvd_data_t * p_dvd ) ...@@ -254,7 +103,7 @@ int IfoCreate( thread_dvd_data_t * p_dvd )
} }
/* if we are here the dvd device has already been opened */ /* if we are here the dvd device has already been opened */
p_dvd->p_ifo->i_fd = p_dvd->i_fd; p_dvd->p_ifo->dvdhandle = p_dvd->dvdhandle;
return 0; return 0;
} }
...@@ -264,77 +113,79 @@ int IfoCreate( thread_dvd_data_t * p_dvd ) ...@@ -264,77 +113,79 @@ int IfoCreate( thread_dvd_data_t * p_dvd )
*****************************************************************************/ *****************************************************************************/
int IfoInit( ifo_t * p_ifo ) int IfoInit( ifo_t * p_ifo )
{ {
u8 pi_buffer[DVD_LB_SIZE]; u8 p_buf[DVD_LB_SIZE];
u8* p_current; u8* p_tmp;
u64 i_temp; u64 i_temp;
u32 i_lba;
int i, j, k; int i, j, k;
off_t i_start; int i_start;
/* find the start sector of video information on the dvd */ /* find the start sector of video information on the dvd */
i_lba = UDFFindFile( p_ifo->i_fd, "/VIDEO_TS/VIDEO_TS.IFO"); p_ifo->i_start = UDFFindFile( p_ifo->dvdhandle, "/VIDEO_TS/VIDEO_TS.IFO" );
p_ifo->i_off = (off_t)(i_lba) * DVD_LB_SIZE; p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start );
//i_start = p_ifo->i_pos;
p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_off );
//i_start = p_ifo->i_pos;
/* /*
* read the video manager information table * read the video manager information table
*/ */
#define manager_inf p_ifo->vmg.manager_inf #define MGINF p_ifo->vmg.manager_inf
//fprintf( stderr, "VMGI\n" ); //fprintf( stderr, "VMGI\n" );
ReadBits( p_ifo, pi_buffer, &p_current, manager_inf.psz_id, 12 ); ReadBytes( p_ifo, p_buf, &p_tmp, MGINF.psz_id, 12 );
manager_inf.psz_id[12] = '\0'; MGINF.psz_id[12] = '\0';
manager_inf.i_vmg_end_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_vmg_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 12 ); DumpBytes( p_ifo, p_buf, &p_tmp, 12 );
manager_inf.i_vmg_inf_end_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_vmg_inf_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
manager_inf.i_spec_ver = ReadByte( p_ifo, pi_buffer, &p_current ); MGINF.i_spec_ver = ReadByte( p_ifo, p_buf, &p_tmp );
manager_inf.i_cat = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_cat = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_volume_nb = ReadWord( p_ifo, pi_buffer, &p_current ); MGINF.i_volume_nb = ReadWord( p_ifo, p_buf, &p_tmp );
manager_inf.i_volume = ReadWord( p_ifo, pi_buffer, &p_current ); MGINF.i_volume = ReadWord( p_ifo, p_buf, &p_tmp );
manager_inf.i_disc_side = ReadByte( p_ifo, pi_buffer, &p_current ); MGINF.i_disc_side = ReadByte( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 19 ); DumpBytes( p_ifo, p_buf, &p_tmp, 19 );
manager_inf.i_title_set_nb = ReadWord( p_ifo, pi_buffer, &p_current ); MGINF.i_title_set_nb = ReadWord( p_ifo, p_buf, &p_tmp );
ReadBits( p_ifo, pi_buffer, &p_current, manager_inf.ps_provider_id, 32 ); ReadBytes( p_ifo, p_buf, &p_tmp, MGINF.ps_provider_id, 32 );
manager_inf.i_pos_code = ReadQuad( p_ifo, pi_buffer, &p_current ); MGINF.i_pos_code = ReadQuad( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 24 ); DumpBytes( p_ifo, p_buf, &p_tmp, 24 );
manager_inf.i_vmg_inf_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_vmg_inf_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_first_play_title_start_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_first_play_title_start_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 56 ); DumpBytes( p_ifo, p_buf, &p_tmp, 56 );
manager_inf.i_vob_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_vob_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_title_inf_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_title_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_title_unit_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_title_unit_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_parental_inf_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_parental_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_vts_inf_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_vts_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_text_data_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_text_data_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_cell_inf_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_cell_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_vobu_map_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_vobu_map_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 32 ); DumpBytes( p_ifo, p_buf, &p_tmp, 32 );
// GETS( &manager_inf.video_atrt ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); MGINF.i_audio_nb = ReadByte( p_ifo, p_buf, &p_tmp );
manager_inf.i_audio_nb = ReadByte( p_ifo, pi_buffer, &p_current ); //fprintf( stderr, "vmgi audio nb : %d\n", MGINF.i_audio_nb );
//fprintf( stderr, "vmgi audio nb : %d\n", manager_inf.i_audio_nb );
for( i=0 ; i < 8 ; i++ ) for( i = 0 ; i < 8 ; i++ )
{ {
i_temp = ReadQuad( p_ifo, pi_buffer, &p_current ); i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );
} }
DumpBits( p_ifo, pi_buffer, &p_current, 17 );
manager_inf.i_spu_nb = ReadByte( p_ifo, pi_buffer, &p_current ); DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
//fprintf( stderr, "vmgi subpic nb : %d\n", manager_inf.i_spu_nb ); MGINF.i_spu_nb = ReadByte( p_ifo, p_buf, &p_tmp );
for( i=0 ; i < manager_inf.i_spu_nb ; i++ ) //fprintf( stderr, "vmgi subpic nb : %d\n", MGINF.i_spu_nb );
{
ReadBits( p_ifo, pi_buffer, &p_current, (u8*)(&i_temp), 6 ); for( i = 0 ; i < MGINF.i_spu_nb ; i++ )
{
ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
/* FIXME : take care of endianness */ /* FIXME : take care of endianness */
} }
/* /*
* read first play title. * read first play title.
*/ */
if( ReadTitle( p_ifo, &p_ifo->vmg.title, p_ifo->i_off + //fprintf(stderr,"readtitle %i\n", MGINF.i_first_play_title_start_byte & 0x7ff );
manager_inf.i_first_play_title_start_byte ) < 0 ) if( ReadTitle( p_ifo, &p_ifo->vmg.title, p_ifo->i_start
+ OFF2LB( MGINF.i_first_play_title_start_byte ),
MGINF.i_first_play_title_start_byte & 0x7ff ) < 0 )
{ {
return -1; return -1;
} }
...@@ -342,51 +193,51 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 ); ...@@ -342,51 +193,51 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 );
/* /*
* fills the title information structure. * fills the title information structure.
*/ */
#define title_inf p_ifo->vmg.title_inf #define TITINF p_ifo->vmg.title_inf
if( manager_inf.i_title_inf_start_sector ) if( MGINF.i_title_inf_start_sector )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_off + p_tmp = FillBuffer( p_ifo, p_buf,
manager_inf.i_title_inf_start_sector *DVD_LB_SIZE ); p_ifo->i_start + MGINF.i_title_inf_start_sector );
//fprintf( stderr, "title inf %lld\n", p_ifo->i_pos ); //fprintf( stderr, "title inf %d\n", p_ifo->i_pos );
title_inf.i_title_nb = ReadWord( p_ifo, pi_buffer, &p_current ); TITINF.i_title_nb = ReadWord( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "title_inf: TTU nb %d\n", title_inf.i_title_nb ); //fprintf( stderr, "title_inf: TTU nb %d\n", TITINF.i_title_nb );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
title_inf.i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); TITINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
/* parsing of title attributes */ /* parsing of title attributes */
title_inf.p_attr = malloc( title_inf.i_title_nb *sizeof(title_attr_t) ); TITINF.p_attr = malloc( TITINF.i_title_nb *sizeof(title_attr_t) );
if( title_inf.p_attr == NULL ) if( TITINF.p_attr == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoInit" ); intf_ErrMsg( "ifo error: out of memory in IfoInit" );
return -1; return -1;
} }
for( i = 0 ; i < title_inf.i_title_nb ; i++ ) for( i = 0 ; i < TITINF.i_title_nb ; i++ )
{ {
title_inf.p_attr[i].i_play_type = ReadByte( p_ifo, pi_buffer, &p_current ); TITINF.p_attr[i].i_play_type = ReadByte( p_ifo, p_buf, &p_tmp );
title_inf.p_attr[i].i_angle_nb = ReadByte( p_ifo, pi_buffer, &p_current ); TITINF.p_attr[i].i_angle_nb = ReadByte( p_ifo, p_buf, &p_tmp );
title_inf.p_attr[i].i_chapter_nb = ReadWord( p_ifo, pi_buffer, &p_current ); TITINF.p_attr[i].i_chapter_nb = ReadWord( p_ifo, p_buf, &p_tmp );
title_inf.p_attr[i].i_parental_id = ReadWord( p_ifo, pi_buffer, &p_current ); TITINF.p_attr[i].i_parental_id = ReadWord( p_ifo, p_buf, &p_tmp );
title_inf.p_attr[i].i_title_set_num = ReadByte( p_ifo, pi_buffer, &p_current ); TITINF.p_attr[i].i_title_set_num = ReadByte( p_ifo, p_buf, &p_tmp );
title_inf.p_attr[i].i_title_num = ReadByte( p_ifo, pi_buffer, &p_current ); TITINF.p_attr[i].i_title_num = ReadByte( p_ifo, p_buf, &p_tmp );
title_inf.p_attr[i].i_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); TITINF.p_attr[i].i_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "title_inf: %d %d %d\n",title_inf.p_attr[i].i_chapter_nb ,title_inf.p_attr[i].i_title_set_num,title_inf.p_attr[i].i_title_num ); //fprintf( stderr, "title_inf: %d %d %d\n", TITINF.p_attr[i].i_chapter_nb, TITINF.p_attr[i].i_title_set_num, TITINF.p_attr[i].i_title_num );
} }
} }
else else
{ {
title_inf.p_attr = NULL; TITINF.p_attr = NULL;
} }
#undef title_inf #undef TITINF
/* /*
* fills the title unit structure. * fills the title unit structure.
*/ */
if( manager_inf.i_title_unit_start_sector ) if( MGINF.i_title_unit_start_sector )
{ {
if( ReadTitleUnit( p_ifo, &p_ifo->vmg.title_unit, p_ifo->i_off + if( ReadTitleUnit( p_ifo, &p_ifo->vmg.title_unit, p_ifo->i_start
manager_inf.i_title_unit_start_sector *DVD_LB_SIZE ) < 0 ) + MGINF.i_title_unit_start_sector ) < 0 )
{ {
return -1; return -1;
} }
...@@ -395,159 +246,175 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 ); ...@@ -395,159 +246,175 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 );
/* /*
* fills the structure about parental information. * fills the structure about parental information.
*/ */
#define parental p_ifo->vmg.parental_inf #define PARINF p_ifo->vmg.parental_inf
if( manager_inf.i_parental_inf_start_sector ) if( MGINF.i_parental_inf_start_sector )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_off + p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start +
manager_inf.i_parental_inf_start_sector *DVD_LB_SIZE ); MGINF.i_parental_inf_start_sector );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "PTL\n" ); //fprintf( stderr, "PTL\n" );
parental.i_country_nb = ReadWord( p_ifo, pi_buffer, &p_current ); PARINF.i_country_nb = ReadWord( p_ifo, p_buf, &p_tmp );
parental.i_vts_nb = ReadWord( p_ifo, pi_buffer, &p_current ); PARINF.i_vts_nb = ReadWord( p_ifo, p_buf, &p_tmp );
parental.i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); PARINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
parental.p_parental_desc = malloc( parental.i_country_nb * PARINF.p_parental_desc = malloc( PARINF.i_country_nb
sizeof(parental_desc_t) ); * sizeof(parental_desc_t) );
if( parental.p_parental_desc == NULL ) if( PARINF.p_parental_desc == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoInit" ); intf_ErrMsg( "ifo error: out of memory in IfoInit" );
return -1; return -1;
} }
for( i = 0 ; i < parental.i_country_nb ; i++ ) for( i = 0 ; i < PARINF.i_country_nb ; i++ )
{ {
ReadBits( p_ifo, pi_buffer, &p_current, ReadBytes( p_ifo, p_buf, &p_tmp,
parental.p_parental_desc[i].ps_country_code, 2 ); PARINF.p_parental_desc[i].ps_country_code, 2 );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
parental.p_parental_desc[i].i_parental_mask_start_byte = PARINF.p_parental_desc[i].i_parental_mask_start_byte =
ReadWord( p_ifo, pi_buffer, &p_current ); ReadWord( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
} }
parental.p_parental_mask = malloc( parental.i_country_nb * PARINF.p_parental_mask = malloc( PARINF.i_country_nb
sizeof(parental_mask_t) ); * sizeof(parental_mask_t) );
if( parental.p_parental_mask == NULL ) if( PARINF.p_parental_mask == NULL )
{ {
intf_ErrMsg( "ifo erro: out of memory in IfoInit" ); intf_ErrMsg( "ifo erro: out of memory in IfoInit" );
return -1; return -1;
} }
for( i = 0 ; i < parental.i_country_nb ; i++ ) for( i = 0 ; i < PARINF.i_country_nb ; i++ )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, i_start + p_tmp = FillBuffer( p_ifo, p_buf, LB2OFF( i_start ) +
parental.p_parental_desc[i].i_parental_mask_start_byte ); PARINF.p_parental_desc[i].i_parental_mask_start_byte );
for( j = 0 ; j < 8 ; j++ ) for( j = 0 ; j < 8 ; j++ )
{ {
parental.p_parental_mask[i].ppi_mask[j] = PARINF.p_parental_mask[i].ppi_mask[j] =
malloc( ( parental.i_vts_nb + 1 ) *sizeof(u16) ); malloc( ( PARINF.i_vts_nb + 1 ) * sizeof(u16) );
if( parental.p_parental_mask[i].ppi_mask[j] == NULL )
if( PARINF.p_parental_mask[i].ppi_mask[j] == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoInit" ); intf_ErrMsg( "ifo error: out of memory in IfoInit" );
return -1; return -1;
} }
for( k = 0 ; k < parental.i_vts_nb + 1 ; k++ )
for( k = 0 ; k < PARINF.i_vts_nb + 1 ; k++ )
{ {
parental.p_parental_mask[i].ppi_mask[j][k] = PARINF.p_parental_mask[i].ppi_mask[j][k] =
ReadWord( p_ifo, pi_buffer, &p_current ); ReadWord( p_ifo, p_buf, &p_tmp );
} }
} }
} }
} }
#undef parental #undef PARINF
/* /*
* information and attributes about for each vts. * information and attributes about for each vts.
*/ */
#define vts_inf p_ifo->vmg.vts_inf #define VTSINF p_ifo->vmg.vts_inf
if( manager_inf.i_vts_inf_start_sector ) if( MGINF.i_vts_inf_start_sector )
{ {
u64 i_temp; u64 i_temp;
p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_off + p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start +
manager_inf.i_vts_inf_start_sector *DVD_LB_SIZE ); MGINF.i_vts_inf_start_sector );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "VTS ATTR\n" ); //fprintf( stderr, "VTS ATTR\n" );
vts_inf.i_vts_nb = ReadWord( p_ifo, pi_buffer, &p_current );; VTSINF.i_vts_nb = ReadWord( p_ifo, p_buf, &p_tmp );;
//fprintf( stderr, "VTS ATTR Nb: %d\n", vts_inf.i_vts_nb ); //fprintf( stderr, "VTS ATTR Nb: %d\n", VTSINF.i_vts_nb );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
vts_inf.i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); VTSINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
vts_inf.pi_vts_attr_start_byte = VTSINF.pi_vts_attr_start_byte =
malloc( vts_inf.i_vts_nb *sizeof(u32) ); malloc( VTSINF.i_vts_nb * sizeof(u32) );
if( vts_inf.pi_vts_attr_start_byte == NULL ) if( VTSINF.pi_vts_attr_start_byte == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoInit" ); intf_ErrMsg( "ifo error: out of memory in IfoInit" );
return -1; return -1;
} }
for( i = 0 ; i < vts_inf.i_vts_nb ; i++ ) for( i = 0 ; i < VTSINF.i_vts_nb ; i++ )
{ {
vts_inf.pi_vts_attr_start_byte[i] = ReadDouble( p_ifo, pi_buffer, &p_current ); VTSINF.pi_vts_attr_start_byte[i] =
ReadDouble( p_ifo, p_buf, &p_tmp );
} }
vts_inf.p_vts_attr = malloc( vts_inf.i_vts_nb *sizeof(vts_attr_t) ); VTSINF.p_vts_attr = malloc( VTSINF.i_vts_nb * sizeof(vts_attr_t) );
if( vts_inf.p_vts_attr == NULL ) if( VTSINF.p_vts_attr == NULL )
{ {
intf_ErrMsg( "ifo erro: out of memory in IfoInit" ); intf_ErrMsg( "ifo erro: out of memory in IfoInit" );
return -1; return -1;
} }
for( i = 0 ; i < vts_inf.i_vts_nb ; i++ ) for( i = 0 ; i < VTSINF.i_vts_nb ; i++ )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, i_start + p_tmp = FillBuffer( p_ifo, p_buf, i_start +
vts_inf.pi_vts_attr_start_byte[i] ); OFF2LB( VTSINF.pi_vts_attr_start_byte[i] ) )
vts_inf.p_vts_attr[i].i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); + ( VTSINF.pi_vts_attr_start_byte[i] & 0x7ff );
vts_inf.p_vts_attr[i].i_cat_app_type = ReadDouble( p_ifo, pi_buffer, &p_current );
// GETS( &vts_inf.p_vts_attr[i].vts_menu_video_attr ); VTSINF.p_vts_attr[i].i_end_byte =
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); VTSINF.p_vts_attr[i].i_cat_app_type =
vts_inf.p_vts_attr[i].i_vts_menu_audio_nb = ReadByte( p_ifo, pi_buffer, &p_current ); ReadDouble( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "m audio nb : %d\n", vts_inf.p_vts_attr[i].i_vts_menu_audio_nb ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
VTSINF.p_vts_attr[i].i_vts_menu_audio_nb =
ReadByte( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "m audio nb : %d\n", VTSINF.p_vts_attr[i].i_vts_menu_audio_nb );
for( j = 0 ; j < 8 ; j++ ) for( j = 0 ; j < 8 ; j++ )
{ {
i_temp = ReadQuad( p_ifo, pi_buffer, &p_current );; i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );
} }
DumpBits( p_ifo, pi_buffer, &p_current, 17 );
vts_inf.p_vts_attr[i].i_vts_menu_spu_nb = ReadByte( p_ifo, pi_buffer, &p_current ); DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
//fprintf( stderr, "m subp nb : %d\n", vts_inf.p_vts_attr[i].i_vts_menu_spu_nb ); VTSINF.p_vts_attr[i].i_vts_menu_spu_nb =
ReadByte( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "m subp nb : %d\n", VTSINF.p_vts_attr[i].i_vts_menu_spu_nb );
for( j = 0 ; j < 28 ; j++ ) for( j = 0 ; j < 28 ; j++ )
{ {
ReadBits( p_ifo, pi_buffer, &p_current, (u8*)(&i_temp), 6 ); ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
/* FIXME : Fix endianness issue here */ /* FIXME : Fix endianness issue here */
} }
DumpBits( p_ifo, pi_buffer, &p_current, 2 );
// GETS( &vts_inf.p_vts_attr[i].vtstt_video_vts_inf ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
vts_inf.p_vts_attr[i].i_vts_title_audio_nb = VTSINF.p_vts_attr[i].i_vts_title_audio_nb =
ReadDouble( p_ifo, pi_buffer, &p_current ); ReadDouble( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "tt audio nb : %d\n", vts_inf.p_vts_attr[i].i_vts_title_audio_nb ); //fprintf( stderr, "tt audio nb : %d\n", VTSINF.p_vts_attr[i].i_vts_title_audio_nb );
for( j = 0 ; j < 8 ; j++ ) for( j = 0 ; j < 8 ; j++ )
{ {
i_temp = ReadQuad( p_ifo, pi_buffer, &p_current );; i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );;
} }
DumpBits( p_ifo, pi_buffer, &p_current, 17 );
vts_inf.p_vts_attr[i].i_vts_title_spu_nb = ReadByte( p_ifo, pi_buffer, &p_current ); DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
//fprintf( stderr, "tt subp nb : %d\n", vts_inf.p_vts_attr[i].i_vts_title_spu_nb ); VTSINF.p_vts_attr[i].i_vts_title_spu_nb =
for( j=0 ; j<28/*vts_inf.p_vts_vts_inf[i].i_vtstt_subpic_nb*/ ; j++ ) ReadByte( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "tt subp nb : %d\n", VTSINF.p_vts_attr[i].i_vts_title_spu_nb );
for( j = 0 ; j < 28 /*VTSINF.p_vts_vts_inf[i].i_vtstt_subpic_nb*/ ; j++ )
{ {
ReadBits( p_ifo, pi_buffer, &p_current, (u8*)(&i_temp), 6 ); ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
/* FIXME : Fix endianness issue here */ /* FIXME : Fix endianness issue here */
} }
} }
} }
#undef vts_inf #undef VTSINF
/* /*
* global cell map. * global cell map.
*/ */
if( manager_inf.i_cell_inf_start_sector ) if( MGINF.i_cell_inf_start_sector )
{ {
if( ReadCellInf( p_ifo, &p_ifo->vmg.cell_inf, p_ifo->i_off + if( ReadCellInf( p_ifo, &p_ifo->vmg.cell_inf, p_ifo->i_start +
manager_inf.i_cell_inf_start_sector *DVD_LB_SIZE ) < 0 ) MGINF.i_cell_inf_start_sector ) < 0 )
{ {
return -1; return -1;
} }
...@@ -556,15 +423,15 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 ); ...@@ -556,15 +423,15 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 );
/* /*
* global vob unit map. * global vob unit map.
*/ */
if( manager_inf.i_vobu_map_start_sector ) if( MGINF.i_vobu_map_start_sector )
{ {
if( ReadVobuMap( p_ifo, &p_ifo->vmg.vobu_map, p_ifo->i_off + if( ReadVobuMap( p_ifo, &p_ifo->vmg.vobu_map, p_ifo->i_start +
manager_inf.i_vobu_map_start_sector *DVD_LB_SIZE ) < 0 ) MGINF.i_vobu_map_start_sector ) < 0 )
{ {
return -1; return -1;
} }
} }
#undef manager_inf #undef MGINF
p_ifo->vts.b_initialized = 0; p_ifo->vts.b_initialized = 0;
...@@ -578,10 +445,10 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 ); ...@@ -578,10 +445,10 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 );
*****************************************************************************/ *****************************************************************************/
int IfoTitleSet( ifo_t * p_ifo ) int IfoTitleSet( ifo_t * p_ifo )
{ {
u8 pi_buffer[DVD_LB_SIZE]; u8 p_buf[DVD_LB_SIZE];
u8 * p_current; u8 * p_tmp;
off_t i_off; int i_off;
off_t i_start; int i_start;
u64 i_temp; u64 i_temp;
u16 i_short; u16 i_short;
int i, j; int i, j;
...@@ -591,190 +458,196 @@ int IfoTitleSet( ifo_t * p_ifo ) ...@@ -591,190 +458,196 @@ int IfoTitleSet( ifo_t * p_ifo )
FreeTitleSet( &p_ifo->vts ); FreeTitleSet( &p_ifo->vts );
} }
i_off = i_off = p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_start_sector
(off_t)( p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_start_sector ) + p_ifo->i_start;
* DVD_LB_SIZE
+ p_ifo->i_off;
//fprintf(stderr, "offset: %lld\n" , i_off ); //fprintf(stderr, "offset: %d\n" , i_off );
p_current = FillBuffer( p_ifo, pi_buffer, i_off ); p_tmp = FillBuffer( p_ifo, p_buf, i_off );
//i_start = p_ifo->i_pos; //i_start = p_ifo->i_pos;
p_ifo->vts.i_pos = p_ifo->i_pos; p_ifo->vts.i_pos = p_ifo->i_pos;
#define manager_inf p_ifo->vts.manager_inf #define MGINF p_ifo->vts.manager_inf
/* /*
* reads manager information * reads manager information
*/ */
//fprintf( stderr, "VTSI\n" ); //fprintf( stderr, "VTSI\n" );
ReadBits( p_ifo, pi_buffer, &p_current, manager_inf.psz_id , 12 ); ReadBytes( p_ifo, p_buf, &p_tmp, MGINF.psz_id , 12 );
manager_inf.psz_id[12] = '\0'; MGINF.psz_id[12] = '\0';
manager_inf.i_end_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 12 ); DumpBytes( p_ifo, p_buf, &p_tmp, 12 );
manager_inf.i_inf_end_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_inf_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
manager_inf.i_spec_ver = ReadByte( p_ifo, pi_buffer, &p_current ); MGINF.i_spec_ver = ReadByte( p_ifo, p_buf, &p_tmp );
manager_inf.i_cat = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_cat = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 90 ); DumpBytes( p_ifo, p_buf, &p_tmp, 90 );
manager_inf.i_inf_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_inf_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 60 ); DumpBytes( p_ifo, p_buf, &p_tmp, 60 );
manager_inf.i_menu_vob_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_menu_vob_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_title_vob_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_title_vob_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_title_inf_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_title_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_title_unit_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_title_unit_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_menu_unit_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_menu_unit_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_time_inf_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_time_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_menu_cell_inf_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_menu_cell_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_menu_vobu_map_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_menu_vobu_map_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_cell_inf_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_cell_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
manager_inf.i_vobu_map_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); MGINF.i_vobu_map_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 24 ); DumpBytes( p_ifo, p_buf, &p_tmp, 24 );
// GETS( &manager_inf.m_video_atrt ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); MGINF.i_menu_audio_nb = ReadByte( p_ifo, p_buf, &p_tmp );
manager_inf.i_menu_audio_nb = ReadByte( p_ifo, pi_buffer, &p_current );
for( i = 0 ; i < 8 ; i++ ) for( i = 0 ; i < 8 ; i++ )
{ {
i_temp = ReadQuad( p_ifo, pi_buffer, &p_current ); i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );
} }
DumpBits( p_ifo, pi_buffer, &p_current, 17 );
manager_inf.i_menu_spu_nb = ReadByte( p_ifo, pi_buffer, &p_current ); DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
MGINF.i_menu_spu_nb = ReadByte( p_ifo, p_buf, &p_tmp );
for( i = 0 ; i < 28 ; i++ ) for( i = 0 ; i < 28 ; i++ )
{ {
ReadBits( p_ifo, pi_buffer, &p_current, (u8*)(&i_temp), 6 ); ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
/* FIXME : take care of endianness */ /* FIXME : take care of endianness */
} }
DumpBits( p_ifo, pi_buffer, &p_current, 2 );
i_short = ReadWord( p_ifo, pi_buffer, &p_current ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
i_short = ReadWord( p_ifo, p_buf, &p_tmp );
i_short >>= 2; i_short >>= 2;
manager_inf.video_attr.i_mode = i_short & 0x1; MGINF.video_attr.i_mode = i_short & 0x1;
i_short >>= 1; i_short >>= 1;
manager_inf.video_attr.i_letterboxed = i_short & 0x1; MGINF.video_attr.i_letterboxed = i_short & 0x1;
i_short >>= 1; i_short >>= 1;
manager_inf.video_attr.i_source_res = i_short & 0x3; MGINF.video_attr.i_source_res = i_short & 0x3;
i_short >>= 2; i_short >>= 2;
manager_inf.video_attr.i_line21_2 = i_short & 0x1; MGINF.video_attr.i_line21_2 = i_short & 0x1;
i_short >>= 1; i_short >>= 1;
manager_inf.video_attr.i_line21_1 = i_short & 0x1; MGINF.video_attr.i_line21_1 = i_short & 0x1;
i_short >>= 1; i_short >>= 1;
manager_inf.video_attr.i_perm_displ = i_short & 0x3; MGINF.video_attr.i_perm_displ = i_short & 0x3;
i_short >>= 2; i_short >>= 2;
manager_inf.video_attr.i_ratio = i_short & 0x3; MGINF.video_attr.i_ratio = i_short & 0x3;
i_short >>= 2; i_short >>= 2;
manager_inf.video_attr.i_system = i_short & 0x3; MGINF.video_attr.i_system = i_short & 0x3;
i_short >>= 2; i_short >>= 2;
manager_inf.video_attr.i_compression = i_short & 0x3; MGINF.video_attr.i_compression = i_short & 0x3;
DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
MGINF.i_audio_nb = ReadByte( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "vtsi audio nb : %d\n", MGINF.i_audio_nb );
DumpBits( p_ifo, pi_buffer, &p_current, 1 );
manager_inf.i_audio_nb = ReadByte( p_ifo, pi_buffer, &p_current );
//fprintf( stderr, "vtsi audio nb : %d\n", manager_inf.i_audio_nb );
for( i = 0 ; i < 8 ; i++ ) for( i = 0 ; i < 8 ; i++ )
{ {
i_temp = ReadQuad( p_ifo, pi_buffer, &p_current ); i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "Audio %d: %llx\n", i, i_temp ); //fprintf( stderr, "Audio %d: %llx\n", i, i_temp );
i_temp >>= 8; i_temp >>= 8;
manager_inf.p_audio_attr[i].i_bar = i_temp & 0xff; MGINF.p_audio_attr[i].i_bar = i_temp & 0xff;
i_temp >>= 8; i_temp >>= 8;
manager_inf.p_audio_attr[i].i_caption = i_temp & 0xff; MGINF.p_audio_attr[i].i_caption = i_temp & 0xff;
i_temp >>= 8; i_temp >>= 8;
manager_inf.p_audio_attr[i].i_foo = i_temp & 0xff; MGINF.p_audio_attr[i].i_foo = i_temp & 0xff;
i_temp >>= 8; i_temp >>= 8;
manager_inf.p_audio_attr[i].i_lang_code = i_temp & 0xffff; MGINF.p_audio_attr[i].i_lang_code = i_temp & 0xffff;
i_temp >>= 16; i_temp >>= 16;
manager_inf.p_audio_attr[i].i_num_channels = i_temp & 0x7; MGINF.p_audio_attr[i].i_num_channels = i_temp & 0x7;
i_temp >>= 3; i_temp >>= 3;
manager_inf.p_audio_attr[i].i_test = i_temp & 0x1; MGINF.p_audio_attr[i].i_test = i_temp & 0x1;
i_temp >>= 1; i_temp >>= 1;
manager_inf.p_audio_attr[i].i_sample_freq = i_temp & 0x3; MGINF.p_audio_attr[i].i_sample_freq = i_temp & 0x3;
i_temp >>= 2; i_temp >>= 2;
manager_inf.p_audio_attr[i].i_quantization = i_temp & 0x3; MGINF.p_audio_attr[i].i_quantization = i_temp & 0x3;
i_temp >>= 2; i_temp >>= 2;
manager_inf.p_audio_attr[i].i_appl_mode = i_temp & 0x3; MGINF.p_audio_attr[i].i_appl_mode = i_temp & 0x3;
i_temp >>= 2; i_temp >>= 2;
manager_inf.p_audio_attr[i].i_type = i_temp & 0x3; MGINF.p_audio_attr[i].i_type = i_temp & 0x3;
i_temp >>= 2; i_temp >>= 2;
manager_inf.p_audio_attr[i].i_multichannel_extension = i_temp & 0x1; MGINF.p_audio_attr[i].i_multichannel_extension = i_temp & 0x1;
i_temp >>= 1; i_temp >>= 1;
manager_inf.p_audio_attr[i].i_coding_mode = i_temp & 0x7; MGINF.p_audio_attr[i].i_coding_mode = i_temp & 0x7;
} }
DumpBits( p_ifo, pi_buffer, &p_current, 17 );
manager_inf.i_spu_nb = ReadByte( p_ifo, pi_buffer, &p_current ); DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
//fprintf( stderr, "vtsi subpic nb : %d\n", manager_inf.i_spu_nb ); MGINF.i_spu_nb = ReadByte( p_ifo, p_buf, &p_tmp );
for( i=0 ; i<manager_inf.i_spu_nb ; i++ ) //fprintf( stderr, "vtsi subpic nb : %d\n", MGINF.i_spu_nb );
for( i=0 ; i<MGINF.i_spu_nb ; i++ )
{ {
ReadBits( p_ifo, pi_buffer, &p_current, (u8*)(&i_temp), 6 ); ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
i_temp = hton64( i_temp ) >> 16; i_temp = hton64( i_temp ) >> 16;
//fprintf( stderr, "Subpic %d: %llx\n", i, i_temp ); //fprintf( stderr, "Subpic %d: %llx\n", i, i_temp );
manager_inf.p_spu_attr[i].i_caption = i_temp & 0xff; MGINF.p_spu_attr[i].i_caption = i_temp & 0xff;
i_temp >>= 8; i_temp >>= 8;
manager_inf.p_spu_attr[i].i_foo = i_temp & 0xff; MGINF.p_spu_attr[i].i_foo = i_temp & 0xff;
i_temp >>= 8; i_temp >>= 8;
manager_inf.p_spu_attr[i].i_lang_code = i_temp & 0xffff; MGINF.p_spu_attr[i].i_lang_code = i_temp & 0xffff;
i_temp >>= 16; i_temp >>= 16;
manager_inf.p_spu_attr[i].i_prefix = i_temp & 0xffff; MGINF.p_spu_attr[i].i_prefix = i_temp & 0xffff;
} }
/* /*
* reads title information: set of pointers to title * reads title information: set of pointers to title
*/ */
#define title_inf p_ifo->vts.title_inf #define TITINF p_ifo->vts.title_inf
if( manager_inf.i_title_inf_start_sector ) if( MGINF.i_title_inf_start_sector )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->vts.i_pos + p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->vts.i_pos +
manager_inf.i_title_inf_start_sector *DVD_LB_SIZE ); MGINF.i_title_inf_start_sector );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "VTS PTR\n" ); //fprintf( stderr, "VTS PTR\n" );
title_inf.i_title_nb = ReadWord( p_ifo, pi_buffer, &p_current ); TITINF.i_title_nb = ReadWord( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "VTS title_inf nb: %d\n", title_inf.i_title_nb ); //fprintf( stderr, "VTS title_inf nb: %d\n", TITINF.i_title_nb );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
title_inf.i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); TITINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
title_inf.pi_start_byte = malloc( title_inf.i_title_nb *sizeof(u32) ); TITINF.pi_start_byte = malloc( TITINF.i_title_nb * sizeof(u32) );
if( title_inf.pi_start_byte == NULL ) if( TITINF.pi_start_byte == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" ); intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
return -1; return -1;
} }
for( i = 0 ; i < title_inf.i_title_nb ; i++ ) for( i = 0 ; i < TITINF.i_title_nb ; i++ )
{ {
title_inf.pi_start_byte[i] = ReadDouble( p_ifo, pi_buffer, &p_current ); TITINF.pi_start_byte[i] = ReadDouble( p_ifo, p_buf, &p_tmp );
} }
/* Parsing of tts */ /* Parsing of tts */
title_inf.p_title_start = malloc( title_inf.i_title_nb TITINF.p_title_start = malloc( TITINF.i_title_nb
*sizeof(title_start_t) ); * sizeof(title_start_t) );
if( title_inf.p_title_start == NULL ) if( TITINF.p_title_start == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" ); intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
return -1; return -1;
} }
for( i = 0 ; i < title_inf.i_title_nb ; i++ ) for( i = 0 ; i < TITINF.i_title_nb ; i++ )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, i_start + p_tmp = FillBuffer( p_ifo, p_buf, i_start +
title_inf.pi_start_byte[i] ); OFF2LB( TITINF.pi_start_byte[i] ) )
+ TITINF.pi_start_byte[i];
title_inf.p_title_start[i].i_title_id = TITINF.p_title_start[i].i_title_id =
ReadWord( p_ifo, pi_buffer, &p_current ); ReadWord( p_ifo, p_buf, &p_tmp );
title_inf.p_title_start[i].i_chapter = ReadWord( p_ifo, pi_buffer, &p_current ); TITINF.p_title_start[i].i_chapter =
//fprintf( stderr, "VTS %d title_inf Pgc: %d Prg: %d\n", i,title_inf.p_title_start[i].i_program_chain_num, title_inf.p_title_start[i].i_program_num ); ReadWord( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "VTS %d title_inf Pgc: %d Prg: %d\n", i,title_inf.p_title_start[i].i_program_chain_num, TITINF.p_title_start[i].i_program_num );
} }
} }
#undef title_inf #undef TITINF
/* /*
* menu unit information * menu unit information
*/ */
if( manager_inf.i_menu_unit_start_sector ) if( MGINF.i_menu_unit_start_sector )
{ {
if( ReadTitleUnit( p_ifo, &p_ifo->vts.menu_unit, p_ifo->vts.i_pos + if( ReadTitleUnit( p_ifo, &p_ifo->vts.menu_unit, p_ifo->vts.i_pos +
manager_inf.i_menu_unit_start_sector *DVD_LB_SIZE ) < 0 ) MGINF.i_menu_unit_start_sector ) < 0 )
{ {
return -1; return -1;
} }
...@@ -783,109 +656,110 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 ); ...@@ -783,109 +656,110 @@ DumpBits( p_ifo, pi_buffer, &p_current, 2 );
/* /*
* title unit information * title unit information
*/ */
if( manager_inf.i_title_unit_start_sector ) if( MGINF.i_title_unit_start_sector )
{ {
if( ReadUnitInf( p_ifo, &p_ifo->vts.title_unit, p_ifo->vts.i_pos + if( ReadUnitInf( p_ifo, &p_ifo->vts.title_unit, p_ifo->vts.i_pos +
manager_inf.i_title_unit_start_sector *DVD_LB_SIZE ) < 0 ) MGINF.i_title_unit_start_sector, 0 ) < 0 )
{ {
return -1; return -1;
} }
} }
/* /*
* time map inforamtion * time map information
*/ */
#define time_inf p_ifo->vts.time_inf #define TIMINF p_ifo->vts.time_inf
if( manager_inf.i_time_inf_start_sector ) if( MGINF.i_time_inf_start_sector )
{ {
u8 pi_buffer[DVD_LB_SIZE]; u8 p_buf[DVD_LB_SIZE];
p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->vts.i_pos + p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->vts.i_pos +
manager_inf.i_time_inf_start_sector *DVD_LB_SIZE ); MGINF.i_time_inf_start_sector );
//fprintf( stderr, "TMAP\n" ); //fprintf( stderr, "TMAP\n" );
time_inf.i_nb = ReadWord( p_ifo, pi_buffer, &p_current );; TIMINF.i_nb = ReadWord( p_ifo, p_buf, &p_tmp );;
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
time_inf.i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); TIMINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
time_inf.pi_start_byte = malloc( time_inf.i_nb *sizeof(u32) ); TIMINF.pi_start_byte = malloc( TIMINF.i_nb * sizeof(u32) );
if( time_inf.pi_start_byte == NULL ) if( TIMINF.pi_start_byte == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" ); intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
return -1; return -1;
} }
for( i = 0 ; i < time_inf.i_nb ; i++ ) for( i = 0 ; i < TIMINF.i_nb ; i++ )
{ {
time_inf.pi_start_byte[i] = ReadDouble( p_ifo, pi_buffer, &p_current ); TIMINF.pi_start_byte[i] = ReadDouble( p_ifo, p_buf, &p_tmp );
} }
time_inf.p_time_map = malloc( time_inf.i_nb *sizeof(time_map_t) ); TIMINF.p_time_map = malloc( TIMINF.i_nb * sizeof(time_map_t) );
if( time_inf.p_time_map == NULL ) if( TIMINF.p_time_map == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" ); intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
return -1; return -1;
} }
for( i = 0 ; i < time_inf.i_nb ; i++ ) for( i = 0 ; i < TIMINF.i_nb ; i++ )
{ {
time_inf.p_time_map[i].i_time_unit = ReadByte( p_ifo, pi_buffer, &p_current ); TIMINF.p_time_map[i].i_time_unit = ReadByte( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
time_inf.p_time_map[i].i_entry_nb = ReadWord( p_ifo, pi_buffer, &p_current ); TIMINF.p_time_map[i].i_entry_nb = ReadWord( p_ifo, p_buf, &p_tmp );
time_inf.p_time_map[i].pi_sector = TIMINF.p_time_map[i].pi_sector =
malloc( time_inf.p_time_map[i].i_entry_nb *sizeof(u32) ); malloc( TIMINF.p_time_map[i].i_entry_nb * sizeof(u32) );
if( time_inf.p_time_map[i].pi_sector == NULL ) if( TIMINF.p_time_map[i].pi_sector == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" ); intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
return -1; return -1;
} }
for( j = 0 ; j < time_inf.p_time_map[i].i_entry_nb ; j++ ) for( j = 0 ; j < TIMINF.p_time_map[i].i_entry_nb ; j++ )
{ {
time_inf.p_time_map[i].pi_sector[j] = ReadDouble( p_ifo, pi_buffer, &p_current ); TIMINF.p_time_map[i].pi_sector[j] =
ReadDouble( p_ifo, p_buf, &p_tmp );
} }
} }
} }
#undef time_inf #undef TIMINF
if( manager_inf.i_menu_cell_inf_start_sector ) if( MGINF.i_menu_cell_inf_start_sector )
{ {
if( ReadCellInf( p_ifo, &p_ifo->vts.menu_cell_inf, p_ifo->vts.i_pos + if( ReadCellInf( p_ifo, &p_ifo->vts.menu_cell_inf, p_ifo->vts.i_pos +
manager_inf.i_menu_cell_inf_start_sector *DVD_LB_SIZE ) < 0 ) MGINF.i_menu_cell_inf_start_sector ) < 0 )
{ {
return -1; return -1;
} }
} }
if( manager_inf.i_menu_vobu_map_start_sector ) if( MGINF.i_menu_vobu_map_start_sector )
{ {
if( ReadVobuMap( p_ifo, &p_ifo->vts.menu_vobu_map, p_ifo->vts.i_pos + if( ReadVobuMap( p_ifo, &p_ifo->vts.menu_vobu_map, p_ifo->vts.i_pos +
manager_inf.i_menu_vobu_map_start_sector *DVD_LB_SIZE ) < 0 ) MGINF.i_menu_vobu_map_start_sector ) < 0 )
{ {
return -1; return -1;
} }
} }
if( manager_inf.i_cell_inf_start_sector ) if( MGINF.i_cell_inf_start_sector )
{ {
if( ReadCellInf( p_ifo, &p_ifo->vts.cell_inf, p_ifo->vts.i_pos + if( ReadCellInf( p_ifo, &p_ifo->vts.cell_inf, p_ifo->vts.i_pos +
manager_inf.i_cell_inf_start_sector *DVD_LB_SIZE ) ) MGINF.i_cell_inf_start_sector ) )
{ {
return -1; return -1;
} }
} }
if( manager_inf.i_vobu_map_start_sector ) if( MGINF.i_vobu_map_start_sector )
{ {
if( ReadVobuMap( p_ifo, &p_ifo->vts.vobu_map, p_ifo->vts.i_pos + if( ReadVobuMap( p_ifo, &p_ifo->vts.vobu_map, p_ifo->vts.i_pos +
manager_inf.i_vobu_map_start_sector *DVD_LB_SIZE ) ) MGINF.i_vobu_map_start_sector ) )
{ {
return -1; return -1;
} }
} }
#undef manager_inf #undef MGINF
intf_WarnMsg( 2, "ifo info: vts %d initialized", intf_WarnMsg( 2, "ifo info: vts %d initialized",
p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_title_set_num ); p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_title_set_num );
...@@ -1010,6 +884,7 @@ void IfoDestroy( ifo_t * p_ifo ) ...@@ -1010,6 +884,7 @@ void IfoDestroy( ifo_t * p_ifo )
return; return;
} }
/* /*
* Function common to Video Manager and Video Title set Processing * Function common to Video Manager and Video Title set Processing
*/ */
...@@ -1021,39 +896,41 @@ void IfoDestroy( ifo_t * p_ifo ) ...@@ -1021,39 +896,41 @@ void IfoDestroy( ifo_t * p_ifo )
* Several title can point to the same part of the physical DVD, and give * Several title can point to the same part of the physical DVD, and give
* map to different anglesfor instance. * map to different anglesfor instance.
*****************************************************************************/ *****************************************************************************/
static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) static int ReadTitle( ifo_t * p_ifo, title_t * p_title, int i_block, int i_bytes )
{ {
u8 pi_buffer[DVD_LB_SIZE]; u8 p_buf[DVD_LB_SIZE];
u8 * p_current; u8 * p_tmp;
off_t i_start; int i_start;
u16 i_audio; u16 i_audio;
u32 i_spu; u32 i_spu;
int i; int i;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos ); p_tmp = FillBuffer( p_ifo, p_buf, i_block ) + i_bytes;
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "PGC @ %lld\n",p_ifo->i_pos ); //fprintf( stderr, "PGC @ %d + %d\n", p_ifo->i_pos, i_bytes );
DumpBytes( p_ifo, p_buf, &p_tmp, 2);
p_title->i_chapter_nb = ReadByte( p_ifo, p_buf, &p_tmp );
p_title->i_cell_nb = ReadByte( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "title: Prg: %d Cell: %d\n",p_title->i_chapter_nb,p_title->i_cell_nb );
p_title->i_play_time = ReadDouble( p_ifo, p_buf, &p_tmp );
p_title->i_prohibited_user_op = ReadDouble( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 2);
p_title->i_chapter_nb = ReadByte( p_ifo, pi_buffer, &p_current );
p_title->i_cell_nb = ReadByte( p_ifo, pi_buffer, &p_current );
//fprintf( stderr, "title: Prg: %d Cell: %d\n",p_title->i_chapter_nb,p_title->i_cell_nb );
p_title->i_play_time = ReadDouble( p_ifo, pi_buffer, &p_current );
p_title->i_prohibited_user_op = ReadDouble( p_ifo, pi_buffer, &p_current );
for( i = 0 ; i < 8 ; i++ ) for( i = 0 ; i < 8 ; i++ )
{ {
i_audio = ReadWord( p_ifo, pi_buffer, &p_current ); i_audio = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->pi_audio_status[i].i_foo = i_audio & 0xff; p_title->pi_audio_status[i].i_foo = i_audio & 0xff;
i_audio >>= 8; i_audio >>= 8;
p_title->pi_audio_status[i].i_position = i_audio & 0x07; p_title->pi_audio_status[i].i_position = i_audio & 0x07;
i_audio >>= 7; i_audio >>= 7;
p_title->pi_audio_status[i].i_available = i_audio; p_title->pi_audio_status[i].i_available = i_audio;
} }
for( i = 0 ; i < 32 ; i++ ) for( i = 0 ; i < 32 ; i++ )
{ {
i_spu = ReadDouble( p_ifo, pi_buffer, &p_current ); i_spu = ReadDouble( p_ifo, p_buf, &p_tmp );
p_title->pi_spu_status[i].i_position_pan = i_spu & 0x1f; p_title->pi_spu_status[i].i_position_pan = i_spu & 0x1f;
i_spu >>= 8; i_spu >>= 8;
p_title->pi_spu_status[i].i_position_letter = i_spu & 0x1f; p_title->pi_spu_status[i].i_position_letter = i_spu & 0x1f;
...@@ -1064,40 +941,44 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1064,40 +941,44 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
i_spu >>= 7; i_spu >>= 7;
p_title->pi_spu_status[i].i_available = i_spu; p_title->pi_spu_status[i].i_available = i_spu;
} }
p_title->i_next_title_num = ReadWord( p_ifo, pi_buffer, &p_current );
p_title->i_prev_title_num = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->i_next_title_num = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->i_go_up_title_num = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->i_prev_title_num = ReadWord( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "title: Prev: %d Next: %d Up: %d\n",pgc.i_prev_pgc_nb ,pgc.i_next_pgc_nb, pgc.i_goup_pgc_nb ); p_title->i_go_up_title_num = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->i_still_time = ReadByte( p_ifo, pi_buffer, &p_current ); //fprintf( stderr, "title: Prev: %d Next: %d Up: %d\n",pgc.i_prev_pgc_nb ,pgc.i_next_pgc_nb, pgc.i_goup_pgc_nb );
p_title->i_play_mode = ReadByte( p_ifo, pi_buffer, &p_current ); p_title->i_still_time = ReadByte( p_ifo, p_buf, &p_tmp );
p_title->i_play_mode = ReadByte( p_ifo, p_buf, &p_tmp );
for( i = 0 ; i < 16 ; i++ ) for( i = 0 ; i < 16 ; i++ )
{ {
p_title->pi_yuv_color[i] = ReadDouble( p_ifo, pi_buffer, &p_current ); p_title->pi_yuv_color[i] = ReadDouble( p_ifo, p_buf, &p_tmp );
/* FIXME : We have to erase the extra bit */ /* FIXME : We have to erase the extra bit */
} }
p_title->i_command_start_byte = ReadWord( p_ifo, pi_buffer, &p_current );
p_title->i_chapter_map_start_byte = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->i_command_start_byte = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->i_cell_play_start_byte = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->i_chapter_map_start_byte = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->i_cell_pos_start_byte = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->i_cell_play_start_byte = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->i_cell_pos_start_byte = ReadWord( p_ifo, p_buf, &p_tmp );
/* parsing of command_t */ /* parsing of command_t */
if( p_title->i_command_start_byte ) if( p_title->i_command_start_byte )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, p_tmp = FillBuffer( p_ifo, p_buf, i_start +
i_start + p_title->i_command_start_byte ); OFF2LB( p_title->i_command_start_byte + i_bytes ) )
+ ( (p_title->i_command_start_byte + i_bytes) & 0x7ff );
/* header */ /* header */
p_title->command.i_pre_command_nb = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->command.i_pre_command_nb = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->command.i_post_command_nb = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->command.i_post_command_nb = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->command.i_cell_command_nb = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->command.i_cell_command_nb = ReadWord( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
/* pre-title commands */ /* pre-title commands */
if( p_title->command.i_pre_command_nb ) if( p_title->command.i_pre_command_nb )
{ {
p_title->command.p_pre_command = p_title->command.p_pre_command =
malloc( p_title->command.i_pre_command_nb malloc( p_title->command.i_pre_command_nb
*sizeof(command_desc_t) ); * sizeof(command_desc_t) );
if( p_title->command.p_pre_command == NULL ) if( p_title->command.p_pre_command == NULL )
{ {
...@@ -1107,7 +988,8 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1107,7 +988,8 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
for( i = 0 ; i < p_title->command.i_pre_command_nb ; i++ ) for( i = 0 ; i < p_title->command.i_pre_command_nb ; i++ )
{ {
p_title->command.p_pre_command[i] = ReadQuad( p_ifo, pi_buffer, &p_current ); p_title->command.p_pre_command[i] =
ReadQuad( p_ifo, p_buf, &p_tmp );
} }
} }
else else
...@@ -1120,7 +1002,7 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1120,7 +1002,7 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
{ {
p_title->command.p_post_command = p_title->command.p_post_command =
malloc( p_title->command.i_post_command_nb malloc( p_title->command.i_post_command_nb
*sizeof(command_desc_t) ); * sizeof(command_desc_t) );
if( p_title->command.p_post_command == NULL ) if( p_title->command.p_post_command == NULL )
{ {
...@@ -1128,9 +1010,10 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1128,9 +1010,10 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
return -1; return -1;
} }
for( i=0 ; i<p_title->command.i_post_command_nb ; i++ ) for( i = 0 ; i < p_title->command.i_post_command_nb ; i++ )
{ {
p_title->command.p_post_command[i] = ReadQuad( p_ifo, pi_buffer, &p_current ); p_title->command.p_post_command[i] =
ReadQuad( p_ifo, p_buf, &p_tmp );
} }
} }
else else
...@@ -1143,7 +1026,7 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1143,7 +1026,7 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
{ {
p_title->command.p_cell_command = p_title->command.p_cell_command =
malloc( p_title->command.i_cell_command_nb malloc( p_title->command.i_cell_command_nb
*sizeof(command_desc_t) ); * sizeof(command_desc_t) );
if( p_title->command.p_cell_command == NULL ) if( p_title->command.p_cell_command == NULL )
{ {
...@@ -1151,9 +1034,10 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1151,9 +1034,10 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
return -1; return -1;
} }
for( i=0 ; i<p_title->command.i_cell_command_nb ; i++ ) for( i = 0 ; i < p_title->command.i_cell_command_nb ; i++ )
{ {
p_title->command.p_cell_command[i] = ReadQuad( p_ifo, pi_buffer, &p_current ); p_title->command.p_cell_command[i] =
ReadQuad( p_ifo, p_buf, &p_tmp );
} }
} }
else else
...@@ -1165,18 +1049,11 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1165,18 +1049,11 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
/* parsing of chapter_map_t: it gives the entry cell for each chapter */ /* parsing of chapter_map_t: it gives the entry cell for each chapter */
if( p_title->i_chapter_map_start_byte ) if( p_title->i_chapter_map_start_byte )
{ {
#if !defined( WIN32 ) p_ifo->i_pos = dvdcss_seek( p_ifo->dvdhandle,
p_ifo->i_pos = lseek( p_ifo->i_fd, OFF2LB( i_start + p_title->i_chapter_map_start_byte ) );
i_start + p_title->i_chapter_map_start_byte,
SEEK_SET );
#else
p_ifo->i_pos = SetFilePointer( (HANDLE) p_ifo->i_fd,
i_start + p_title->i_chapter_map_start_byte,
NULL, FILE_BEGIN );
#endif
p_title->chapter_map.pi_start_cell = p_title->chapter_map.pi_start_cell =
malloc( p_title->i_chapter_nb *sizeof(chapter_map_t) ); malloc( p_title->i_chapter_nb * sizeof(chapter_map_t) );
if( p_title->chapter_map.pi_start_cell == NULL ) if( p_title->chapter_map.pi_start_cell == NULL )
{ {
...@@ -1184,7 +1061,7 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1184,7 +1061,7 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
return -1; return -1;
} }
ReadBits( p_ifo, pi_buffer, &p_current, p_title->chapter_map.pi_start_cell, ReadBytes( p_ifo, p_buf, &p_tmp, p_title->chapter_map.pi_start_cell,
p_title->i_chapter_nb ); p_title->i_chapter_nb );
} }
else else
...@@ -1195,11 +1072,12 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1195,11 +1072,12 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
/* parsing of cell_play_t */ /* parsing of cell_play_t */
if( p_title->i_cell_play_start_byte ) if( p_title->i_cell_play_start_byte )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, p_tmp = FillBuffer( p_ifo, p_buf, i_start +
i_start + p_title->i_cell_play_start_byte ); OFF2LB( p_title->i_cell_play_start_byte+i_bytes ) )
+ ( (p_title->i_cell_play_start_byte+i_bytes) & 0x7ff );
p_title->p_cell_play = malloc( p_title->i_cell_nb p_title->p_cell_play = malloc( p_title->i_cell_nb
*sizeof(cell_play_t) ); * sizeof(cell_play_t) );
if( p_title->p_cell_play == NULL ) if( p_title->p_cell_play == NULL )
{ {
...@@ -1209,27 +1087,28 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1209,27 +1087,28 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
for( i = 0 ; i < p_title->i_cell_nb ; i++ ) for( i = 0 ; i < p_title->i_cell_nb ; i++ )
{ {
p_title->p_cell_play[i].i_category = ReadWord( p_ifo, pi_buffer, &p_current ); #define PLAY p_title->p_cell_play[i]
p_title->p_cell_play[i].i_still_time = ReadByte( p_ifo, pi_buffer, &p_current ); PLAY.i_category = ReadWord( p_ifo, p_buf, &p_tmp );
p_title->p_cell_play[i].i_command_nb = ReadByte( p_ifo, pi_buffer, &p_current ); PLAY.i_still_time = ReadByte( p_ifo, p_buf, &p_tmp );
p_title->p_cell_play[i].i_play_time = ReadDouble( p_ifo, pi_buffer, &p_current ); PLAY.i_command_nb = ReadByte( p_ifo, p_buf, &p_tmp );
p_title->p_cell_play[i].i_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); PLAY.i_play_time = ReadDouble( p_ifo, p_buf, &p_tmp );
p_title->p_cell_play[i].i_first_ilvu_vobu_esector = PLAY.i_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
ReadDouble( p_ifo, pi_buffer, &p_current ); PLAY.i_first_ilvu_vobu_esector = ReadDouble( p_ifo, p_buf, &p_tmp );
p_title->p_cell_play[i].i_last_vobu_start_sector = PLAY.i_last_vobu_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
ReadDouble( p_ifo, pi_buffer, &p_current ); PLAY.i_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
p_title->p_cell_play[i].i_end_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); #undef PLAY
} }
} }
/* Parsing of cell_pos_t */ /* Parsing of cell_pos_t */
if( p_title->i_cell_pos_start_byte ) if( p_title->i_cell_pos_start_byte )
{ {
p_current = FillBuffer( p_ifo, pi_buffer, p_tmp = FillBuffer( p_ifo, p_buf, i_start +
i_start + p_title->i_cell_pos_start_byte ); OFF2LB( p_title->i_cell_pos_start_byte + i_bytes ) )
+ ( (p_title->i_cell_pos_start_byte + i_bytes) & 0x7ff );
p_title->p_cell_pos = malloc( p_title->i_cell_nb p_title->p_cell_pos = malloc( p_title->i_cell_nb
*sizeof(cell_pos_t) ); * sizeof(cell_pos_t) );
if( p_title->p_cell_pos == NULL ) if( p_title->p_cell_pos == NULL )
{ {
...@@ -1239,9 +1118,9 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos ) ...@@ -1239,9 +1118,9 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
for( i = 0 ; i < p_title->i_cell_nb ; i++ ) for( i = 0 ; i < p_title->i_cell_nb ; i++ )
{ {
p_title->p_cell_pos[i].i_vob_id = ReadWord( p_ifo, pi_buffer, &p_current ); p_title->p_cell_pos[i].i_vob_id = ReadWord( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
p_title->p_cell_pos[i].i_cell_id = ReadByte( p_ifo, pi_buffer, &p_current ); p_title->p_cell_pos[i].i_cell_id = ReadByte( p_ifo, p_buf, &p_tmp );
} }
} }
...@@ -1292,25 +1171,26 @@ static int FreeTitle( title_t * p_title ) ...@@ -1292,25 +1171,26 @@ static int FreeTitle( title_t * p_title )
/***************************************************************************** /*****************************************************************************
* ReadUnitInf : Fills Menu Language Unit Table/ PGC Info Table * ReadUnitInf : Fills Menu Language Unit Table/ PGC Info Table
*****************************************************************************/ *****************************************************************************/
static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf, off_t i_pos ) static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf,
int i_block, int i_bytes )
{ {
u8 pi_buffer[DVD_LB_SIZE]; u8 p_buf[DVD_LB_SIZE];
u8 * p_current; u8 * p_tmp;
off_t i_start; int i_start;
int i; int i;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos ); p_tmp = FillBuffer( p_ifo, p_buf, i_block ) + i_bytes;
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "Unit\n" ); //fprintf( stderr, "Unit\n" );
p_unit_inf->i_title_nb = ReadWord( p_ifo, pi_buffer, &p_current ); p_unit_inf->i_title_nb = ReadWord( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "Unit nb: %d\n", p_unit_inf->i_title_nb ); //fprintf( stderr, "Unit nb: %d\n", p_unit_inf->i_title_nb );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
p_unit_inf->i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); p_unit_inf->i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
p_unit_inf->p_title = p_unit_inf->p_title =
malloc( p_unit_inf->i_title_nb *sizeof(unit_title_t) ); malloc( p_unit_inf->i_title_nb * sizeof(unit_title_t) );
if( p_unit_inf->p_title == NULL ) if( p_unit_inf->p_title == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in ReadUnit" ); intf_ErrMsg( "ifo error: out of memory in ReadUnit" );
...@@ -1319,18 +1199,21 @@ static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf, off_t i_pos ) ...@@ -1319,18 +1199,21 @@ static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf, off_t i_pos )
for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ ) for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ )
{ {
p_unit_inf->p_title[i].i_category_mask = ReadByte( p_ifo, pi_buffer, &p_current ); #define TITLE p_unit_inf->p_title[i]
p_unit_inf->p_title[i].i_category = ReadByte( p_ifo, pi_buffer, &p_current ); TITLE.i_category_mask = ReadByte( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "cat mask %d: %x cat %x\n", i, p_unit_inf->p_title[i].i_category_mask, p_unit_inf->p_title[i].i_category ); TITLE.i_category = ReadByte( p_ifo, p_buf, &p_tmp );
p_unit_inf->p_title[i].i_parental_mask = ReadWord( p_ifo, pi_buffer, &p_current ); //fprintf( stderr, "cat mask %d: %x cat %x\n", i, TITLE.i_category_mask, TITLE.i_category );
p_unit_inf->p_title[i].i_title_start_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); TITLE.i_parental_mask = ReadWord( p_ifo, p_buf, &p_tmp );
TITLE.i_title_start_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
#undef TITLE
} }
for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ ) for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ )
{ {
//fprintf( stderr, "Unit: PGC %d @ %lld\n", i, p_ifo->i_pos ); //fprintf( stderr, "Unit: PGC %d @ %d\n", i, p_ifo->i_pos );
ReadTitle( p_ifo, &p_unit_inf->p_title[i].title, i_start + ReadTitle( p_ifo, &p_unit_inf->p_title[i].title, i_start +
p_unit_inf->p_title[i].i_title_start_byte ); OFF2LB( p_unit_inf->p_title[i].i_title_start_byte + i_bytes ),
(p_unit_inf->p_title[i].i_title_start_byte+i_bytes) & 0x7ff );
} }
return 0; return 0;
...@@ -1354,24 +1237,24 @@ static int FreeUnitInf( unit_inf_t * p_unit_inf ) ...@@ -1354,24 +1237,24 @@ static int FreeUnitInf( unit_inf_t * p_unit_inf )
* ReadTitleUnit: Fills the Title Unit structure. * ReadTitleUnit: Fills the Title Unit structure.
*****************************************************************************/ *****************************************************************************/
static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit, static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit,
off_t i_pos ) int i_block )
{ {
u8 pi_buffer[DVD_LB_SIZE]; u8 p_buf[DVD_LB_SIZE];
u8 * p_current; u8 * p_tmp;
int i; int i;
off_t i_start; int i_start;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos ); p_tmp = FillBuffer( p_ifo, p_buf, i_block );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "Unit Table\n" ); //fprintf( stderr, "Unit Table\n" );
p_title_unit->i_unit_nb = ReadWord( p_ifo, pi_buffer, &p_current ); p_title_unit->i_unit_nb = ReadWord( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
p_title_unit->i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); p_title_unit->i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
//fprintf(stderr, "Unit: nb %d end %d\n", p_title_unit->i_unit_nb, p_title_unit->i_end_byte ); //fprintf(stderr, "Unit: nb %d end %d\n", p_title_unit->i_unit_nb, p_title_unit->i_end_byte );
p_title_unit->p_unit = malloc( p_title_unit->i_unit_nb *sizeof(unit_t) ); p_title_unit->p_unit = malloc( p_title_unit->i_unit_nb * sizeof(unit_t) );
if( p_title_unit->p_unit == NULL ) if( p_title_unit->p_unit == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in ReadTitleUnit" ); intf_ErrMsg( "ifo error: out of memory in ReadTitleUnit" );
...@@ -1380,17 +1263,18 @@ static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit, ...@@ -1380,17 +1263,18 @@ static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit,
for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ ) for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ )
{ {
//ReadBits( p_ifo, pi_buffer, &p_current, p_title_unit->p_unit[i].ps_lang_code, 2 ); //ReadBytes( p_ifo, p_buf, &p_tmp, p_title_unit->p_unit[i].ps_lang_code, 2 );
p_title_unit->p_unit[i].i_lang_code = ReadWord( p_ifo, pi_buffer, &p_current ); p_title_unit->p_unit[i].i_lang_code = ReadWord( p_ifo, p_buf, &p_tmp );
//fprintf( stderr, "lang %d %x\n", i,p_title_unit->p_unit[i].i_lang_code ); //fprintf( stderr, "lang %d %x\n", i,p_title_unit->p_unit[i].i_lang_code );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
p_title_unit->p_unit[i].i_existence_mask = ReadByte( p_ifo, pi_buffer, &p_current ); p_title_unit->p_unit[i].i_existence_mask =
ReadByte( p_ifo, p_buf, &p_tmp );
p_title_unit->p_unit[i].i_unit_inf_start_byte = p_title_unit->p_unit[i].i_unit_inf_start_byte =
ReadDouble( p_ifo, pi_buffer, &p_current ); ReadDouble( p_ifo, p_buf, &p_tmp );
} }
p_title_unit->p_unit_inf = p_title_unit->p_unit_inf =
malloc( p_title_unit->i_unit_nb *sizeof(unit_inf_t) ); malloc( p_title_unit->i_unit_nb * sizeof(unit_inf_t) );
if( p_title_unit->p_unit_inf == NULL ) if( p_title_unit->p_unit_inf == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in ReadTitleUnit" ); intf_ErrMsg( "ifo error: out of memory in ReadTitleUnit" );
...@@ -1400,7 +1284,8 @@ static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit, ...@@ -1400,7 +1284,8 @@ static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit,
for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ ) for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ )
{ {
ReadUnitInf( p_ifo, &p_title_unit->p_unit_inf[i], i_start + ReadUnitInf( p_ifo, &p_title_unit->p_unit_inf[i], i_start +
p_title_unit->p_unit[i].i_unit_inf_start_byte ); OFF2LB( p_title_unit->p_unit[i].i_unit_inf_start_byte ),
p_title_unit->p_unit[i].i_unit_inf_start_byte & 0x7ff );
} }
return 0; return 0;
...@@ -1429,24 +1314,24 @@ static int FreeTitleUnit( title_unit_t * p_title_unit ) ...@@ -1429,24 +1314,24 @@ static int FreeTitleUnit( title_unit_t * p_title_unit )
/***************************************************************************** /*****************************************************************************
* ReadCellInf : Fills the Cell Information structure. * ReadCellInf : Fills the Cell Information structure.
*****************************************************************************/ *****************************************************************************/
static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf, off_t i_pos ) static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf, int i_block )
{ {
u8 pi_buffer[DVD_LB_SIZE]; u8 p_buf[DVD_LB_SIZE];
u8 * p_current; u8 * p_tmp;
off_t i_start; int i_start;
int i; int i;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos ); p_tmp = FillBuffer( p_ifo, p_buf, i_block );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "CELL ADD\n" ); //fprintf( stderr, "CELL ADD\n" );
p_cell_inf->i_vob_nb = ReadWord( p_ifo, pi_buffer, &p_current ); p_cell_inf->i_vob_nb = ReadWord( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 2 ); DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
p_cell_inf->i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); p_cell_inf->i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
p_cell_inf->i_cell_nb = (p_cell_inf->i_end_byte/* - 7*/) / sizeof(cell_map_t); p_cell_inf->i_cell_nb = (p_cell_inf->i_end_byte/* - 7*/) / sizeof(cell_map_t);
//fprintf( stderr, "Cell inf: vob %d end %d cell %d\n", p_cell_inf->i_vob_nb, p_cell_inf->i_end_byte, p_cell_inf->i_cell_nb ); //fprintf( stderr, "Cell inf: vob %d end %d cell %d\n", p_cell_inf->i_vob_nb, p_cell_inf->i_end_byte, p_cell_inf->i_cell_nb );
p_cell_inf->p_cell_map = p_cell_inf->p_cell_map =
malloc( p_cell_inf->i_cell_nb *sizeof(cell_map_t) ); malloc( p_cell_inf->i_cell_nb *sizeof(cell_map_t) );
...@@ -1458,12 +1343,14 @@ static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf, off_t i_pos ) ...@@ -1458,12 +1343,14 @@ static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf, off_t i_pos )
for( i = 0 ; i < p_cell_inf->i_cell_nb ; i++ ) for( i = 0 ; i < p_cell_inf->i_cell_nb ; i++ )
{ {
p_cell_inf->p_cell_map[i].i_vob_id = ReadWord( p_ifo, pi_buffer, &p_current ); #define MAP p_cell_inf->p_cell_map[i]
p_cell_inf->p_cell_map[i].i_cell_id = ReadByte( p_ifo, pi_buffer, &p_current ); MAP.i_vob_id = ReadWord( p_ifo, p_buf, &p_tmp );
DumpBits( p_ifo, pi_buffer, &p_current, 1 ); MAP.i_cell_id = ReadByte( p_ifo, p_buf, &p_tmp );
p_cell_inf->p_cell_map[i].i_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
// fprintf(stderr, "sector[%d] %d (%lld)\n", i,ntohl(*(u32*)(p_current)), p_ifo->i_pos); MAP.i_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
p_cell_inf->p_cell_map[i].i_end_sector = ReadDouble( p_ifo, pi_buffer, &p_current ); //fprintf(stderr, "sector[%d] %d (%lld)\n", i,ntohl(*(u32*)(p_tmp)), p_ifo->i_pos);
MAP.i_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
#undef MAP
} }
return 0; return 0;
...@@ -1482,22 +1369,22 @@ static int FreeCellInf( cell_inf_t * p_cell_inf ) ...@@ -1482,22 +1369,22 @@ static int FreeCellInf( cell_inf_t * p_cell_inf )
/***************************************************************************** /*****************************************************************************
* ReadVobuMap : Fills the VOBU Map structure. * ReadVobuMap : Fills the VOBU Map structure.
*****************************************************************************/ *****************************************************************************/
static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map, off_t i_pos ) static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map, int i_block )
{ {
u8 pi_buffer[DVD_LB_SIZE]; u8 p_buf[DVD_LB_SIZE];
u8 * p_current; u8 * p_tmp;
off_t i_start; int i_start;
int i, i_max; int i, i_max;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos ); p_tmp = FillBuffer( p_ifo, p_buf, i_block );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "VOBU ADMAP\n" ); //fprintf( stderr, "VOBU ADMAP\n" );
p_vobu_map->i_end_byte = ReadDouble( p_ifo, pi_buffer, &p_current ); p_vobu_map->i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
i_max = ( i_start + p_vobu_map->i_end_byte + 1 - p_ifo->i_pos ) i_max = ( i_start + p_vobu_map->i_end_byte + 1 - p_ifo->i_pos )
/ sizeof(u32); / sizeof(u32);
p_vobu_map->pi_vobu_start_sector = malloc( i_max *sizeof(u32) ); p_vobu_map->pi_vobu_start_sector = malloc( i_max * sizeof(u32) );
if( p_vobu_map->pi_vobu_start_sector == NULL ) if( p_vobu_map->pi_vobu_start_sector == NULL )
{ {
intf_ErrMsg( "ifo error: out of memory in ReadVobuMap" ); intf_ErrMsg( "ifo error: out of memory in ReadVobuMap" );
...@@ -1506,7 +1393,7 @@ static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map, off_t i_pos ) ...@@ -1506,7 +1393,7 @@ static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map, off_t i_pos )
for( i = 0 ; i < i_max ; i++ ) for( i = 0 ; i < i_max ; i++ )
{ {
p_vobu_map->pi_vobu_start_sector[i] = ReadDouble( p_ifo, pi_buffer, &p_current ); p_vobu_map->pi_vobu_start_sector[i] = ReadDouble( p_ifo, p_buf, &p_tmp );
} }
return 0; return 0;
...@@ -2201,3 +2088,106 @@ void CommandPrint( ifo_t ifo ) ...@@ -2201,3 +2088,106 @@ void CommandPrint( ifo_t ifo )
} }
#endif #endif
/*****************************************************************************
* ReadByte and so
*****************************************************************************/
static u8* FillBuffer( ifo_t* p_ifo, u8* p_buf, int i_pos )
{
memset( p_buf, 0, DVD_LB_SIZE );
p_ifo->i_pos = dvdcss_seek( p_ifo->dvdhandle, i_pos );
dvdcss_read( p_ifo->dvdhandle, p_buf, 1, DVDCSS_NOFLAGS );
return p_buf;
}
static u8 ReadByte( ifo_t * p_ifo, u8* p_buf, u8** pp_tmp )
{
u8 i_ret;
if( *pp_tmp > p_buf + DVD_LB_SIZE )
{
*pp_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_pos + 1 );
}
i_ret = *(*pp_tmp)++;
return i_ret;
}
static void ReadBytes( ifo_t* p_ifo, u8* p_buf, u8** pp_tmp,
u8* pi_dest, int i_nb )
{
if( *pp_tmp > p_buf + DVD_LB_SIZE - i_nb )
{
*pp_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_pos + 1 );
}
memcpy( pi_dest, *pp_tmp, i_nb );
*pp_tmp += i_nb;
return;
}
static void DumpBytes( ifo_t* p_ifo, u8* p_buf,
u8** pp_tmp, int i_nb )
{
if( *pp_tmp > p_buf + DVD_LB_SIZE - i_nb )
{
*pp_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_pos + 1 );
}
*pp_tmp += i_nb;
return;
}
static u16 ReadWord( ifo_t* p_ifo, u8* p_buf, u8** pp_tmp )
{
u16 i_ret;
if( *pp_tmp > p_buf + DVD_LB_SIZE - 2 )
{
*pp_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_pos + 1 );
}
i_ret = U16_AT(*pp_tmp);
(*pp_tmp) += 2;
return i_ret;
}
static u32 ReadDouble( ifo_t * p_ifo, u8* p_buf,
u8** pp_tmp )
{
u32 i_ret;
if( *pp_tmp > p_buf + DVD_LB_SIZE - 4 )
{
*pp_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_pos + 1 );
//intf_WarnMsg( 1, "new buffer in double @ %lld", p_ifo->i_pos );
}
i_ret = U32_AT(*pp_tmp);
(*pp_tmp) += 4;
return i_ret;
}
static u64 ReadQuad( ifo_t* p_ifo, u8* p_buf, u8** pp_tmp )
{
u64 i_ret;
if( *pp_tmp > p_buf + DVD_LB_SIZE - 8 )
{
*pp_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_pos + 1 );
}
i_ret = U64_AT(*pp_tmp);
(*pp_tmp) += 8;
return i_ret;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ifo.h: Structures for ifo parsing * dvd_ifo.h: Structures for ifo parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.h,v 1.16 2001/06/07 15:27:44 sam Exp $ * $Id: dvd_ifo.h,v 1.17 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -521,7 +521,7 @@ typedef struct time_inf_s ...@@ -521,7 +521,7 @@ typedef struct time_inf_s
typedef struct vts_s typedef struct vts_s
{ {
boolean_t b_initialized; boolean_t b_initialized;
off_t i_pos; int i_pos;
vts_manager_t manager_inf; vts_manager_t manager_inf;
vts_title_t title_inf; vts_title_t title_inf;
title_unit_t menu_unit; title_unit_t menu_unit;
...@@ -538,18 +538,17 @@ typedef struct vts_s ...@@ -538,18 +538,17 @@ typedef struct vts_s
*/ */
typedef struct ifo_s typedef struct ifo_s
{ {
int i_fd; /* File descriptor for the device */ dvdcss_handle dvdhandle; /* File descriptor for the device */
off_t i_off; /* Offset to video_ts.ifo on the device */ int i_start; /* Offset to video_ts.ifo on the device */
off_t i_pos; /* Position of stream pointer */ int i_pos; /* Position of stream pointer */
boolean_t b_error; /* Error Management */ boolean_t b_error; /* Error Management */
vmg_t vmg; /* Structure described in video_ts */ vmg_t vmg; /* Structure described in video_ts */
int i_title; /* Current title number */ int i_title; /* Current title number */
vts_t vts; /* Vts ifo for current title set */ vts_t vts; /* Vts ifo for current title set */
#if defined(__FreeBSD__)
uint8_t p_remap[ 2 * DVD_LB_SIZE ];
/* Remap buffer for unaligned reads */ /* Remap buffer for unaligned reads */
#endif u8 p_remap[ 2 * DVD_LB_SIZE ];
} ifo_t; } ifo_t;
...@@ -562,3 +561,4 @@ int IfoCreate ( struct thread_dvd_data_s * ); ...@@ -562,3 +561,4 @@ int IfoCreate ( struct thread_dvd_data_s * );
int IfoInit ( struct ifo_s * ); int IfoInit ( struct ifo_s * );
int IfoTitleSet ( struct ifo_s * ); int IfoTitleSet ( struct ifo_s * );
void IfoDestroy ( struct ifo_s * ); void IfoDestroy ( struct ifo_s * );
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* found in .ifo. * found in .ifo.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_summary.c,v 1.5 2001/06/12 18:16:49 stef Exp $ * $Id: dvd_summary.c,v 1.6 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -54,6 +54,8 @@ ...@@ -54,6 +54,8 @@
#endif #endif
#include <errno.h> #include <errno.h>
#include <videolan/dvdcss.h>
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
#include "threads.h" #include "threads.h"
...@@ -260,8 +262,8 @@ char * IfoLanguage( u16 i_code ) ...@@ -260,8 +262,8 @@ char * IfoLanguage( u16 i_code )
void IfoPrintTitle( thread_dvd_data_t * p_dvd ) void IfoPrintTitle( thread_dvd_data_t * p_dvd )
{ {
intf_WarnMsg( 5, "dvd info: title: %d", p_dvd->i_title ); intf_WarnMsg( 5, "dvd info: title: %d", p_dvd->i_title );
intf_WarnMsg( 5, " vobstart at: %lld", p_dvd->i_start ); intf_WarnMsg( 5, " vobstart at: %d blocks", p_dvd->i_start );
intf_WarnMsg( 5, " stream size: %lld", p_dvd->i_size ); intf_WarnMsg( 5, " stream size: %d blocks", p_dvd->i_size );
intf_WarnMsg( 5, " number of chapters: %d", p_dvd->i_chapter_nb ); intf_WarnMsg( 5, " number of chapters: %d", p_dvd->i_chapter_nb );
intf_WarnMsg( 5, " number of angles: %d", p_dvd->i_angle_nb ); intf_WarnMsg( 5, " number of angles: %d", p_dvd->i_angle_nb );
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* contains the basic udf handling functions * contains the basic udf handling functions
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_udf.c,v 1.10 2001/06/07 22:25:42 sam Exp $ * $Id: dvd_udf.c,v 1.11 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -55,6 +55,8 @@ ...@@ -55,6 +55,8 @@
# include <strings.h> # include <strings.h>
#endif #endif
#include <videolan/dvdcss.h>
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
#include "threads.h" #include "threads.h"
...@@ -63,7 +65,6 @@ ...@@ -63,7 +65,6 @@
#include "intf_msg.h" #include "intf_msg.h"
#include "input_dvd.h" #include "input_dvd.h"
#include "dvd_css.h"
#include "dvd_ifo.h" #include "dvd_ifo.h"
#include "modules.h" #include "modules.h"
...@@ -83,7 +84,7 @@ typedef struct partition_s ...@@ -83,7 +84,7 @@ typedef struct partition_s
u32 i_access_type; u32 i_access_type;
u32 i_start; u32 i_start;
u32 i_length; u32 i_length;
int i_fd; dvdcss_handle dvdhandle;
} partition_t; } partition_t;
typedef struct ad_s typedef struct ad_s
...@@ -106,41 +107,16 @@ typedef struct ad_s ...@@ -106,41 +107,16 @@ typedef struct ad_s
***************************************************************************** *****************************************************************************
* Returns number of read bytes on success, 0 on error * Returns number of read bytes on success, 0 on error
*****************************************************************************/ *****************************************************************************/
static int UDFReadLB( int i_fd, off_t i_lba, size_t i_block_count, u8 *pi_data ) static int UDFReadLB( dvdcss_handle dvdhandle, off_t i_lba,
size_t i_block_count, u8 *pi_data )
{ {
#if !defined( WIN32 ) if( dvdcss_seek( dvdhandle, i_lba ) < 0 )
if( i_fd < 0 )
#else
DWORD read;
if( (HANDLE) i_fd == INVALID_HANDLE_VALUE )
#endif
{
return 0;
}
#if !defined( WIN32 )
if( lseek( i_fd, i_lba * (off_t) DVD_LB_SIZE, SEEK_SET ) < 0 )
#else
if( SetFilePointer( (HANDLE) i_fd, i_lba * (off_t) DVD_LB_SIZE,
NULL, FILE_BEGIN ) == -1 )
#endif
{ {
intf_ErrMsg( "UDF: Postion not found" ); intf_ErrMsg( "UDF: Postion not found" );
return 0; return 0;
} }
#if !defined( WIN32 ) return dvdcss_read( dvdhandle, pi_data, i_block_count, DVDCSS_NOFLAGS );
return read( i_fd, pi_data, i_block_count *DVD_LB_SIZE);
#else
if(!ReadFile( (HANDLE) i_fd, pi_data, i_block_count * DVD_LB_SIZE,
&read, NULL) || read != i_block_count * DVD_LB_SIZE )
{
return 0;
}
return read;
#endif
} }
...@@ -413,7 +389,7 @@ static int UDFMapICB( struct ad_s icb, u8 * pi_file_type, struct ad_s * p_file, ...@@ -413,7 +389,7 @@ static int UDFMapICB( struct ad_s icb, u8 * pi_file_type, struct ad_s * p_file,
do do
{ {
if( !UDFReadLB( partition.i_fd, i_lba++, 1, pi_lb ) ) if( !UDFReadLB( partition.dvdhandle, i_lba++, 1, pi_lb ) )
{ {
i_tag_id = 0; i_tag_id = 0;
} }
...@@ -457,7 +433,7 @@ static int UDFScanDir( struct ad_s dir, char * psz_filename, ...@@ -457,7 +433,7 @@ static int UDFScanDir( struct ad_s dir, char * psz_filename,
#if 0 #if 0
do do
{ {
if( !UDFReadLB( partition.i_fd, i_lba++, 1, pi_lb ) ) if( !UDFReadLB( partition.dvdhandle, i_lba++, 1, pi_lb ) )
{ {
i_tag_id = 0; i_tag_id = 0;
} }
...@@ -489,7 +465,7 @@ static int UDFScanDir( struct ad_s dir, char * psz_filename, ...@@ -489,7 +465,7 @@ static int UDFScanDir( struct ad_s dir, char * psz_filename,
#else #else
if( UDFReadLB( partition.i_fd, i_lba, 2, pi_lb ) <= 0 ) { if( UDFReadLB( partition.dvdhandle, i_lba, 2, pi_lb ) <= 0 ) {
return 0; return 0;
} }
...@@ -501,7 +477,7 @@ static int UDFScanDir( struct ad_s dir, char * psz_filename, ...@@ -501,7 +477,7 @@ static int UDFScanDir( struct ad_s dir, char * psz_filename,
++i_lba; ++i_lba;
p -= DVD_LB_SIZE; p -= DVD_LB_SIZE;
dir.i_length -= DVD_LB_SIZE; dir.i_length -= DVD_LB_SIZE;
if( UDFReadLB( partition.i_fd, i_lba, 2, pi_lb ) <= 0 ) if( UDFReadLB( partition.dvdhandle, i_lba, 2, pi_lb ) <= 0 )
{ {
return 0; return 0;
} }
...@@ -558,7 +534,7 @@ static int UDFFindPartition( int i_part_nb, struct partition_s *p_partition ) ...@@ -558,7 +534,7 @@ static int UDFFindPartition( int i_part_nb, struct partition_s *p_partition )
/* Search anchor loop */ /* Search anchor loop */
while( 1 ) while( 1 )
{ {
if( UDFReadLB( p_partition->i_fd, i_lba, 1, pi_anchor ) ) if( UDFReadLB( p_partition->dvdhandle, i_lba, 1, pi_anchor ) )
{ {
UDFDescriptor( pi_anchor, &i_tag_id ); UDFDescriptor( pi_anchor, &i_tag_id );
} }
...@@ -622,7 +598,7 @@ static int UDFFindPartition( int i_part_nb, struct partition_s *p_partition ) ...@@ -622,7 +598,7 @@ static int UDFFindPartition( int i_part_nb, struct partition_s *p_partition )
do do
{ {
if( !UDFReadLB( p_partition->i_fd, i_lba++, 1, pi_lb ) ) if( !UDFReadLB( p_partition->dvdhandle, i_lba++, 1, pi_lb ) )
{ {
i_tag_id = 0; i_tag_id = 0;
} }
...@@ -679,7 +655,7 @@ static int UDFFindPartition( int i_part_nb, struct partition_s *p_partition ) ...@@ -679,7 +655,7 @@ static int UDFFindPartition( int i_part_nb, struct partition_s *p_partition )
* starting with '/'. * starting with '/'.
* returns absolute LB number, or 0 on error * returns absolute LB number, or 0 on error
*****************************************************************************/ *****************************************************************************/
u32 UDFFindFile( int i_fd, char * psz_path ) u32 UDFFindFile( dvdcss_handle dvdhandle, char * psz_path )
{ {
struct partition_s partition; struct partition_s partition;
struct ad_s root_icb; struct ad_s root_icb;
...@@ -696,7 +672,7 @@ u32 UDFFindFile( int i_fd, char * psz_path ) ...@@ -696,7 +672,7 @@ u32 UDFFindFile( int i_fd, char * psz_path )
strcat( psz_tokenline, psz_path ); strcat( psz_tokenline, psz_path );
/* Init file descriptor of UDF filesystem (== DVD) */ /* Init file descriptor of UDF filesystem (== DVD) */
partition.i_fd = i_fd; partition.dvdhandle = dvdhandle;
/* Find partition 0, standard partition for DVD-Video */ /* Find partition 0, standard partition for DVD-Video */
i_partition = 0; i_partition = 0;
...@@ -711,7 +687,7 @@ u32 UDFFindFile( int i_fd, char * psz_path ) ...@@ -711,7 +687,7 @@ u32 UDFFindFile( int i_fd, char * psz_path )
do do
{ {
if( !UDFReadLB( i_fd, i_lba++, 1, pi_lb ) ) if( !UDFReadLB( dvdhandle, i_lba++, 1, pi_lb ) )
{ {
i_tag_id = 0; i_tag_id = 0;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_udf.h: structures for udf filesystem tools. * dvd_udf.h: structures for udf filesystem tools.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_udf.h,v 1.2 2001/02/18 01:42:05 stef Exp $ * $Id: dvd_udf.h,v 1.3 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stéphane Borel <stef@via.ecp.fr> * Author: Stéphane Borel <stef@via.ecp.fr>
* *
...@@ -27,4 +27,5 @@ ...@@ -27,4 +27,5 @@
/* /*
* Fonctions in dvd_udf.c * Fonctions in dvd_udf.c
*/ */
u32 UDFFindFile( int, char * ); u32 UDFFindFile( dvdcss_handle, char * );
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
* especially the 2048 bytes logical block size. * especially the 2048 bytes logical block size.
* It depends on: * It depends on:
* -input_netlist used to read packets * -input_netlist used to read packets
* -libdvdcss for access and unscrambling
* -dvd_ifo for ifo parsing and analyse * -dvd_ifo for ifo parsing and analyse
* -dvd_css for unscrambling
* -dvd_udf to find files * -dvd_udf to find files
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.70 2001/06/12 18:16:49 stef Exp $ * $Id: input_dvd.c,v 1.71 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -49,10 +49,6 @@ ...@@ -49,10 +49,6 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#if !defined( WIN32 )
# include <netinet/in.h>
#endif
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
...@@ -69,6 +65,8 @@ ...@@ -69,6 +65,8 @@
# include <sys/uio.h> /* struct iovec */ # include <sys/uio.h> /* struct iovec */
#endif #endif
#include <videolan/dvdcss.h>
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
#include "threads.h" #include "threads.h"
...@@ -88,7 +86,6 @@ ...@@ -88,7 +86,6 @@
#include "input_dvd.h" #include "input_dvd.h"
#include "dvd_netlist.h" #include "dvd_netlist.h"
#include "dvd_ifo.h" #include "dvd_ifo.h"
#include "dvd_css.h"
#include "dvd_summary.h" #include "dvd_summary.h"
#include "mpeg_system.h" #include "mpeg_system.h"
...@@ -99,10 +96,10 @@ ...@@ -99,10 +96,10 @@
/* how many blocks DVDRead will read in each loop */ /* how many blocks DVDRead will read in each loop */
#define DVD_BLOCK_READ_ONCE 64 #define DVD_BLOCK_READ_ONCE 64
#define DVD_DATA_READ_ONCE 4*DVD_BLOCK_READ_ONCE #define DVD_DATA_READ_ONCE (4 * DVD_BLOCK_READ_ONCE)
/* Size of netlist */ /* Size of netlist */
#define DVD_NETLIST_SIZE 1024 #define DVD_NETLIST_SIZE 2048
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -111,6 +108,8 @@ ...@@ -111,6 +108,8 @@
static int DVDProbe ( probedata_t *p_data ); static int DVDProbe ( probedata_t *p_data );
static void DVDInit ( struct input_thread_s * ); static void DVDInit ( struct input_thread_s * );
static void DVDEnd ( struct input_thread_s * ); static void DVDEnd ( struct input_thread_s * );
static void DVDOpen ( struct input_thread_s * );
static void DVDClose ( struct input_thread_s * );
static int DVDSetArea ( struct input_thread_s *, struct input_area_s * ); static int DVDSetArea ( struct input_thread_s *, struct input_area_s * );
static int DVDRead ( struct input_thread_s *, data_packet_t ** ); static int DVDRead ( struct input_thread_s *, data_packet_t ** );
static void DVDSeek ( struct input_thread_s *, off_t ); static void DVDSeek ( struct input_thread_s *, off_t );
...@@ -131,8 +130,8 @@ void _M( input_getfunctions )( function_list_t * p_function_list ) ...@@ -131,8 +130,8 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
#define input p_function_list->functions.input #define input p_function_list->functions.input
p_function_list->pf_probe = DVDProbe; p_function_list->pf_probe = DVDProbe;
input.pf_init = DVDInit; input.pf_init = DVDInit;
input.pf_open = NULL; /* Set in DVDInit */ input.pf_open = DVDOpen;
input.pf_close = NULL; input.pf_close = DVDClose;
input.pf_end = DVDEnd; input.pf_end = DVDEnd;
input.pf_read = DVDRead; input.pf_read = DVDRead;
input.pf_set_area = DVDSetArea; input.pf_set_area = DVDSetArea;
...@@ -216,6 +215,7 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -216,6 +215,7 @@ static void DVDInit( input_thread_t * p_input )
input_area_t * p_area; input_area_t * p_area;
int i_title; int i_title;
int i_chapter; int i_chapter;
int i_ret;
int i; int i;
p_dvd = malloc( sizeof(thread_dvd_data_t) ); p_dvd = malloc( sizeof(thread_dvd_data_t) );
...@@ -229,35 +229,45 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -229,35 +229,45 @@ static void DVDInit( input_thread_t * p_input )
p_input->p_plugin_data = (void *)p_dvd; p_input->p_plugin_data = (void *)p_dvd;
p_input->p_method_data = NULL; p_input->p_method_data = NULL;
p_dvd->i_fd = p_input->i_handle; p_dvd->dvdhandle = dvdcss_init( DVDCSS_INIT_QUIET );
/* We read DVD_BLOCK_READ_ONCE in each loop, so the input will receive if( p_dvd->dvdhandle == NULL )
* DVD_DATA_READ_ONCE at most */ {
p_dvd->i_block_once = DVD_BLOCK_READ_ONCE; free( p_dvd );
/* this value mustn't be modifed */ p_input->b_error = 1;
p_input->i_read_once = DVD_DATA_READ_ONCE; return;
}
i = CSSTest( p_input->i_handle ); /* XXX: put this shit in an access plugin */
if( strlen( p_input->p_source ) > 4
&& !strncasecmp( p_input->p_source, "dvd:", 4 ) )
{
i_ret = dvdcss_open( p_dvd->dvdhandle, p_input->p_source + 4 );
}
else
{
i_ret = dvdcss_open( p_dvd->dvdhandle, p_input->p_source );
}
if( i < 0 ) if( i_ret < 0 )
{ {
intf_ErrMsg( "dvd error: error in css" ); dvdcss_end( p_dvd->dvdhandle );
free( p_dvd ); free( p_dvd );
p_input->b_error = 1; p_input->b_error = 1;
return; return;
} }
p_dvd->b_encrypted = i; dvdcss_seek( p_dvd->dvdhandle, 0 );
#if !defined( WIN32 ) /* We read DVD_BLOCK_READ_ONCE in each loop, so the input will receive
lseek( p_input->i_handle, 0, SEEK_SET ); * DVD_DATA_READ_ONCE at most */
#else p_dvd->i_block_once = DVD_BLOCK_READ_ONCE;
SetFilePointer( (HANDLE) p_input->i_handle, 0, 0, FILE_BEGIN ); /* this value mustn't be modifed */
#endif p_input->i_read_once = DVD_DATA_READ_ONCE;
/* Reading structures initialisation */ /* Reading structures initialisation */
p_input->p_method_data = p_input->p_method_data =
DVDNetlistInit( DVD_NETLIST_SIZE, 2*DVD_NETLIST_SIZE, DVDNetlistInit( DVD_NETLIST_SIZE, 2 * DVD_NETLIST_SIZE,
DVD_NETLIST_SIZE, DVD_LB_SIZE, p_dvd->i_block_once ); DVD_NETLIST_SIZE, DVD_LB_SIZE, p_dvd->i_block_once );
intf_WarnMsg( 2, "dvd info: netlist initialized" ); intf_WarnMsg( 2, "dvd info: netlist initialized" );
...@@ -265,6 +275,9 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -265,6 +275,9 @@ static void DVDInit( input_thread_t * p_input )
if( IfoCreate( p_dvd ) < 0 ) if( IfoCreate( p_dvd ) < 0 )
{ {
intf_ErrMsg( "dvd error: allcation error in ifo" ); intf_ErrMsg( "dvd error: allcation error in ifo" );
dvdcss_close( p_dvd->dvdhandle );
dvdcss_end( p_dvd->dvdhandle );
free( p_dvd );
p_input->b_error = 1; p_input->b_error = 1;
return; return;
} }
...@@ -272,37 +285,14 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -272,37 +285,14 @@ static void DVDInit( input_thread_t * p_input )
if( IfoInit( p_dvd->p_ifo ) < 0 ) if( IfoInit( p_dvd->p_ifo ) < 0 )
{ {
intf_ErrMsg( "dvd error: fatal failure in ifo" ); intf_ErrMsg( "dvd error: fatal failure in ifo" );
IfoDestroy( p_dvd->p_ifo );
dvdcss_close( p_dvd->dvdhandle );
dvdcss_end( p_dvd->dvdhandle );
free( p_dvd ); free( p_dvd );
p_input->b_error = 1; p_input->b_error = 1;
return; return;
} }
/* CSS initialisation */
if( p_dvd->b_encrypted )
{
p_dvd->p_css = malloc( sizeof(css_t) );
if( p_dvd->p_css == NULL )
{
intf_ErrMsg( "dvd error: couldn't create css structure" );
free( p_dvd );
p_input->b_error = 1;
return;
}
p_dvd->p_css->i_agid = 0;
if( CSSInit( p_input->i_handle, p_dvd->p_css ) < 0 )
{
intf_ErrMsg( "dvd error: fatal failure in css" );
free( p_dvd->p_css );
free( p_dvd );
p_input->b_error = 1;
return;
}
intf_WarnMsg( 2, "dvd info: css initialized" );
}
/* Set stream and area data */ /* Set stream and area data */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
...@@ -340,8 +330,8 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -340,8 +330,8 @@ static void DVDInit( input_thread_t * p_input )
area[i]->i_angle = 1; area[i]->i_angle = 1;
/* Offset to vts_i_0.ifo */ /* Offset to vts_i_0.ifo */
area[i]->i_plugin_data = p_dvd->p_ifo->i_off + area[i]->i_plugin_data = p_dvd->p_ifo->i_start +
( title_inf.p_attr[i-1].i_start_sector * DVD_LB_SIZE ); title_inf.p_attr[i-1].i_start_sector;
} }
#undef area #undef area
...@@ -384,13 +374,14 @@ static void DVDEnd( input_thread_t * p_input ) ...@@ -384,13 +374,14 @@ static void DVDEnd( input_thread_t * p_input )
p_dvd = (thread_dvd_data_t*)p_input->p_plugin_data; p_dvd = (thread_dvd_data_t*)p_input->p_plugin_data;
p_netlist = (dvd_netlist_t *)p_input->p_method_data; p_netlist = (dvd_netlist_t *)p_input->p_method_data;
if( p_dvd->b_encrypted )
{
free( p_dvd->p_css );
}
IfoDestroy( p_dvd->p_ifo ); IfoDestroy( p_dvd->p_ifo );
/* Clean up libdvdcss */
dvdcss_close( p_dvd->dvdhandle );
dvdcss_end( p_dvd->dvdhandle );
free( p_dvd ); free( p_dvd );
DVDNetlistEnd( p_netlist ); DVDNetlistEnd( p_netlist );
} }
...@@ -410,7 +401,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -410,7 +401,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
int i_audio; int i_audio;
int i_spu; int i_spu;
int i; int i;
int j;
p_dvd = (thread_dvd_data_t*)p_input->p_plugin_data; p_dvd = (thread_dvd_data_t*)p_input->p_plugin_data;
...@@ -456,32 +446,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -456,32 +446,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
i_vts_title, i_vts_title,
p_dvd->i_title_id ); p_dvd->i_title_id );
/* css title key for current vts */ /*
if( p_dvd->b_encrypted ) * CSS cracking has to be done again
{ */
/* this one is vts number */ dvdcss_crack( p_dvd->dvdhandle,
p_dvd->p_css->i_title = vmg.title_inf.p_attr[p_dvd->i_title-1].i_title_set_num,
vmg.title_inf.p_attr[p_dvd->i_title-1].i_title_set_num; vts.i_pos + vts.manager_inf.i_title_vob_start_sector );
p_dvd->p_css->i_title_pos =
vts.i_pos +
vts.manager_inf.i_title_vob_start_sector * DVD_LB_SIZE;
j = CSSGetKey( p_input->i_handle, p_dvd->p_css );
if( j < 0 )
{
intf_ErrMsg( "dvd error: fatal error in vts css key" );
free( p_dvd );
p_input->b_error = 1;
return -1;
}
else if( j > 0 )
{
intf_ErrMsg( "dvd error: css decryption unavailable" );
free( p_dvd );
p_input->b_error = 1;
return -1;
}
}
/* /*
* Angle management * Angle management
...@@ -497,12 +467,13 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -497,12 +467,13 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
* Set selected title start and size * Set selected title start and size
*/ */
/* title set offset */ /* title set offset XXX: convert to block values */
p_dvd->i_title_start = vts.i_pos + DVD_LB_SIZE * p_dvd->i_title_start =
(off_t)( vts.manager_inf.i_title_vob_start_sector ); vts.i_pos + vts.manager_inf.i_title_vob_start_sector;
/* last video cell */ /* last video cell */
p_dvd->i_cell = 0; p_dvd->i_cell = 0;
intf_FlushMsg();
p_dvd->i_prg_cell = -1 + p_dvd->i_prg_cell = -1 +
vts.title_unit.p_title[p_dvd->i_title_id-1].title.i_cell_nb; vts.title_unit.p_title[p_dvd->i_title_id-1].title.i_cell_nb;
...@@ -520,10 +491,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -520,10 +491,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
} }
p_dvd->i_sector = 0; p_dvd->i_sector = 0;
p_dvd->i_size = DVD_LB_SIZE * p_dvd->i_size = vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector;
(off_t)( vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector ); intf_WarnMsg( 2, "dvd info: stream size 1: %d", p_dvd->i_size );
intf_WarnMsg( 2, "dvd info: stream size 1: %lld @ %d", p_dvd->i_size,
vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector );
if( DVDChapterSelect( p_dvd, 1 ) < 0 ) if( DVDChapterSelect( p_dvd, 1 ) < 0 )
{ {
...@@ -532,13 +501,13 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -532,13 +501,13 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
return -1; return -1;
} }
p_dvd->i_size -= (off_t)( p_dvd->i_sector + 1 ) *DVD_LB_SIZE; p_dvd->i_size -= p_dvd->i_sector + 1;
IfoPrintTitle( p_dvd ); IfoPrintTitle( p_dvd );
/* Area definition */ /* Area definition */
p_input->stream.p_selected_area->i_start = p_dvd->i_start; p_input->stream.p_selected_area->i_start = LB2OFF( p_dvd->i_start );
p_input->stream.p_selected_area->i_size = p_dvd->i_size; p_input->stream.p_selected_area->i_size = LB2OFF( p_dvd->i_size );
p_input->stream.p_selected_area->i_angle_nb = p_dvd->i_angle_nb; p_input->stream.p_selected_area->i_angle_nb = p_dvd->i_angle_nb;
p_input->stream.p_selected_area->i_angle = p_dvd->i_angle; p_input->stream.p_selected_area->i_angle = p_dvd->i_angle;
...@@ -755,8 +724,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -755,8 +724,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
return -1; return -1;
} }
p_input->stream.p_selected_area->i_tell = p_dvd->i_start - p_input->stream.p_selected_area->i_tell =
p_area->i_start; LB2OFF( p_dvd->i_start ) - p_area->i_start;
p_input->stream.p_selected_area->i_part = p_dvd->i_chapter; p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
intf_WarnMsg( 4, "dvd info: chapter %d start at: %lld", intf_WarnMsg( 4, "dvd info: chapter %d start at: %lld",
...@@ -821,7 +790,6 @@ static int DVDRead( input_thread_t * p_input, ...@@ -821,7 +790,6 @@ static int DVDRead( input_thread_t * p_input,
int i_iovec; int i_iovec;
int i_packet; int i_packet;
int i_pos; int i_pos;
int i_read_bytes;
int i_read_blocks; int i_read_blocks;
off_t i_off; off_t i_off;
boolean_t b_eof; boolean_t b_eof;
...@@ -849,9 +817,8 @@ static int DVDRead( input_thread_t * p_input, ...@@ -849,9 +817,8 @@ static int DVDRead( input_thread_t * p_input,
} }
/* Position the fd pointer on the right address */ /* Position the fd pointer on the right address */
i_off = lseek( p_dvd->i_fd, i_off = LB2OFF( dvdcss_seek( p_dvd->dvdhandle,
p_dvd->i_title_start + p_dvd->i_title_start + p_dvd->i_sector ) );
(off_t)( p_dvd->i_sector ) *DVD_LB_SIZE, SEEK_SET );
/* update chapter : it will be easier when we have navigation /* update chapter : it will be easier when we have navigation
* ES support */ * ES support */
...@@ -883,7 +850,7 @@ static int DVDRead( input_thread_t * p_input, ...@@ -883,7 +850,7 @@ static int DVDRead( input_thread_t * p_input,
i_block_once = p_dvd->i_end_sector - p_dvd->i_sector + 1; i_block_once = p_dvd->i_end_sector - p_dvd->i_sector + 1;
} }
/* the number of blocks read is the maw between the requested /* The number of blocks read is the max between the requested
* value and the leaving block in the cell */ * value and the leaving block in the cell */
if( i_block_once > p_dvd->i_block_once ) if( i_block_once > p_dvd->i_block_once )
{ {
...@@ -901,12 +868,8 @@ static int DVDRead( input_thread_t * p_input, ...@@ -901,12 +868,8 @@ static int DVDRead( input_thread_t * p_input,
} }
/* Reads from DVD */ /* Reads from DVD */
#if !defined( WIN32 ) i_read_blocks = dvdcss_readv( p_dvd->dvdhandle, p_vec,
i_read_bytes = readv( p_dvd->i_fd, p_vec, i_block_once ); i_block_once, DVDCSS_READ_DECRYPT );
#else
i_read_bytes = ReadFileV( p_dvd->i_fd, p_vec, i_block_once );
#endif
i_read_blocks = ( i_read_bytes + 0x7ff ) >> 11;
/* Update netlist indexes: we don't do it in DVDGetiovec since we /* Update netlist indexes: we don't do it in DVDGetiovec since we
* need know the real number of blocks read */ * need know the real number of blocks read */
...@@ -920,13 +883,6 @@ static int DVDRead( input_thread_t * p_input, ...@@ -920,13 +883,6 @@ static int DVDRead( input_thread_t * p_input,
/* Read headers to compute payload length */ /* Read headers to compute payload length */
for( i_iovec = 0 ; i_iovec < i_read_blocks ; i_iovec++ ) for( i_iovec = 0 ; i_iovec < i_read_blocks ; i_iovec++ )
{ {
if( p_dvd->b_encrypted )
{
CSSDescrambleSector( p_dvd->p_css->pi_title_key,
p_vec[i_iovec].iov_base );
((u8*)(p_vec[i_iovec].iov_base))[0x14] &= 0x8F;
}
i_pos = 0; i_pos = 0;
while( i_pos < p_netlist->i_buffer_size ) while( i_pos < p_netlist->i_buffer_size )
...@@ -987,8 +943,9 @@ static int DVDRead( input_thread_t * p_input, ...@@ -987,8 +943,9 @@ static int DVDRead( input_thread_t * p_input,
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell += i_read_bytes; p_input->stream.p_selected_area->i_tell += LB2OFF( i_read_blocks );
b_eot = !( p_input->stream.p_selected_area->i_tell < p_dvd->i_size ); b_eot = !( p_input->stream.p_selected_area->i_tell
< LB2OFF( p_dvd->i_size ) );
b_eof = b_eot && ( ( p_dvd->i_title + 1 ) >= p_input->stream.i_area_nb ); b_eof = b_eot && ( ( p_dvd->i_title + 1 ) >= p_input->stream.i_area_nb );
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
...@@ -1034,7 +991,6 @@ static int DVDRewind( input_thread_t * p_input ) ...@@ -1034,7 +991,6 @@ static int DVDRewind( input_thread_t * p_input )
static void DVDSeek( input_thread_t * p_input, off_t i_off ) static void DVDSeek( input_thread_t * p_input, off_t i_off )
{ {
thread_dvd_data_t * p_dvd; thread_dvd_data_t * p_dvd;
off_t i_pos;
int i_prg_cell; int i_prg_cell;
int i_cell; int i_cell;
int i_chapter; int i_chapter;
...@@ -1043,12 +999,9 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off ) ...@@ -1043,12 +999,9 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
p_dvd = ( thread_dvd_data_t * )p_input->p_plugin_data; p_dvd = ( thread_dvd_data_t * )p_input->p_plugin_data;
/* we have to take care of offset of beginning of title */ /* we have to take care of offset of beginning of title */
i_pos = i_off + p_input->stream.p_selected_area->i_start p_dvd->i_sector = OFF2LB(i_off + p_input->stream.p_selected_area->i_start)
- p_dvd->i_title_start; - p_dvd->i_title_start;
/* update navigation data */
p_dvd->i_sector = i_pos >> 11;
i_prg_cell = 0; i_prg_cell = 0;
i_chapter = 0; i_chapter = 0;
...@@ -1128,26 +1081,28 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off ) ...@@ -1128,26 +1081,28 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
p_dvd->i_chapter = i_chapter; p_dvd->i_chapter = i_chapter;
p_input->stream.p_selected_area->i_part = p_dvd->i_chapter; p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
#if !defined( WIN32 )
p_input->stream.p_selected_area->i_tell =
lseek( p_dvd->i_fd, p_dvd->i_title_start +
(off_t)( p_dvd->i_sector ) *DVD_LB_SIZE, SEEK_SET ) -
p_input->stream.p_selected_area->i_start;
#else
p_input->stream.p_selected_area->i_tell = p_input->stream.p_selected_area->i_tell =
SetFilePointer( (HANDLE) p_dvd->i_fd, p_dvd->i_title_start + LB2OFF ( dvdcss_seek( p_dvd->dvdhandle, p_dvd->i_title_start
(off_t)( p_dvd->i_sector ) *DVD_LB_SIZE, NULL, FILE_BEGIN) - + p_dvd->i_sector ) )
p_input->stream.p_selected_area->i_start; - p_input->stream.p_selected_area->i_start;
/*
#endif intf_WarnMsg( 3, "Program Cell: %d Cell: %d Chapter: %d",
/* intf_WarnMsg( 3, "Program Cell: %d Cell: %d Chapter: %d",
p_dvd->i_prg_cell, p_dvd->i_cell, p_dvd->i_chapter ); p_dvd->i_prg_cell, p_dvd->i_cell, p_dvd->i_chapter );
*/ */
return; return;
} }
static void DVDOpen ( struct input_thread_s *p_input )
{
return;
}
static void DVDClose ( struct input_thread_s *p_input )
{
return;
}
#define cell p_dvd->p_ifo->vts.cell_inf #define cell p_dvd->p_ifo->vts.cell_inf
/***************************************************************************** /*****************************************************************************
...@@ -1266,16 +1221,10 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter ) ...@@ -1266,16 +1221,10 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
} }
/* start is : beginning of vts vobs + offset to vob x */ /* start is : beginning of vts vobs + offset to vob x */
p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_sector;
DVD_LB_SIZE * (off_t)( p_dvd->i_sector );
/* Position the fd pointer on the right address */ /* Position the fd pointer on the right address */
#if !defined( WIN32 ) p_dvd->i_start = dvdcss_seek( p_dvd->dvdhandle, p_dvd->i_start );
p_dvd->i_start = lseek( p_dvd->i_fd, p_dvd->i_start, SEEK_SET );
#else
p_dvd->i_start = SetFilePointer( (HANDLE) p_dvd->i_fd,
p_dvd->i_start, NULL, FILE_BEGIN );
#endif
p_dvd->i_chapter = i_chapter; p_dvd->i_chapter = i_chapter;
return 0; return 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_dvd.h: thread structure of the DVD plugin * input_dvd.h: thread structure of the DVD plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: input_dvd.h,v 1.23 2001/06/07 22:25:42 sam Exp $ * $Id: input_dvd.h,v 1.24 2001/06/12 22:14:44 sam Exp $
* *
* Author: Stéphane Borel <stef@via.ecp.fr> * Author: Stéphane Borel <stef@via.ecp.fr>
* *
...@@ -26,14 +26,15 @@ ...@@ -26,14 +26,15 @@
*****************************************************************************/ *****************************************************************************/
/* Logical block size for DVD-VIDEO */ /* Logical block size for DVD-VIDEO */
#define DVD_LB_SIZE 2048 #define DVD_LB_SIZE 2048
#define LB2OFF(x) ((off_t)(x) * (off_t)(DVD_LB_SIZE))
#define OFF2LB(x) ((x) >> 11)
/***************************************************************************** /*****************************************************************************
* thread_dvd_data_t: extension of input_thread_t for DVD specificity. * thread_dvd_data_t: extension of input_thread_t for DVD specificity.
*****************************************************************************/ *****************************************************************************/
typedef struct thread_dvd_data_s typedef struct thread_dvd_data_s
{ {
int i_fd; // File descriptor of device dvdcss_handle dvdhandle; /* libdvdcss handle */
boolean_t b_encrypted; // CSS encryption
int i_block_once; // Nb of block read once by int i_block_once; // Nb of block read once by
// readv // readv
...@@ -55,9 +56,9 @@ typedef struct thread_dvd_data_s ...@@ -55,9 +56,9 @@ typedef struct thread_dvd_data_s
int i_sector; int i_sector;
int i_end_sector; /* last sector of current cell */ int i_end_sector; /* last sector of current cell */
off_t i_title_start; int i_title_start;
off_t i_start; int i_start;
off_t i_size; int i_size;
/* Scrambling Information */ /* Scrambling Information */
struct css_s * p_css; struct css_s * p_css;
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
# Objects # Objects
# #
PLUGIN_C = sdl.o vout_sdl.o aout_sdl.o PLUGIN_SDL = sdl.o vout_sdl.o aout_sdl.o
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o) BUILTIN_SDL = $(PLUGIN_SDL:%.o=BUILTIN_%.o)
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C) ALL_OBJ = $(PLUGIN_SDL) $(BUILTIN_SDL)
# #
# Virtual targets # Virtual targets
...@@ -22,18 +22,18 @@ $(PLUGIN_SDL): %.o: .dep/%.d ...@@ -22,18 +22,18 @@ $(PLUGIN_SDL): %.o: .dep/%.d
$(PLUGIN_SDL): %.o: %.c $(PLUGIN_SDL): %.o: %.c
$(CC) $(CFLAGS) $(PCFLAGS) $(CFLAGS_SDL) -DPLUGIN -c -o $@ $< $(CC) $(CFLAGS) $(PCFLAGS) $(CFLAGS_SDL) -DPLUGIN -c -o $@ $<
$(BUILTIN_SDL): BUILTIN_SDL_%.o: .dep/%.d $(BUILTIN_SDL): BUILTIN_%.o: .dep/%.d
$(BUILTIN_SDL): BUILTIN_SDL_%.o: %.c $(BUILTIN_SDL): BUILTIN_%.o: %.c
$(CC) $(CFLAGS) $(CFLAGS_SDL) -DBUILTIN -c -o $@ $< $(CC) $(CFLAGS) $(CFLAGS_SDL) -DBUILTIN -c -o $@ $<
# #
# Real targets # Real targets
# #
../../lib/sdl.so: $(PLUGIN_C) ../../lib/sdl.so: $(PLUGIN_SDL)
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) $(LIB_SDL) $(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) $(LIB_SDL)
../../lib/sdl.a: $(BUILTIN_C) ../../lib/sdl.a: $(BUILTIN_SDL)
ar r $@ $^ ar r $@ $^
$(RANLIB) $@ $(RANLIB) $@
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* and spawn threads. * and spawn threads.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: main.c,v 1.101 2001/06/12 11:02:07 reno Exp $ * $Id: main.c,v 1.102 2001/06/12 22:14:44 sam Exp $
* *
* Authors: Vincent Seguin <seguin@via.ecp.fr> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -133,6 +133,16 @@ ...@@ -133,6 +133,16 @@
#define SHORT_HELP 1 #define SHORT_HELP 1
#define LONG_HELP 2 #define LONG_HELP 2
/* Needed for x86 CPU capabilities detection */
#define cpuid( a ) \
asm volatile ( "cpuid" \
: "=a" ( i_eax ), \
"=b" ( i_ebx ), \
"=c" ( i_ecx ), \
"=d" ( i_edx ) \
: "a" ( a ) \
: "cc" );
/* Long options */ /* Long options */
static const struct option longopts[] = static const struct option longopts[] =
{ {
...@@ -912,7 +922,7 @@ static void InstructionSignalHandler( int i_signal ) ...@@ -912,7 +922,7 @@ static void InstructionSignalHandler( int i_signal )
* to an interface having been destroyed */ * to an interface having been destroyed */
/* Acknowledge the signal received */ /* Acknowledge the signal received */
fprintf(stderr,"illegal instruction : optimization disable\n"); fprintf( stderr, "illegal instruction : optimization disabled\n" );
i_illegal = 1; i_illegal = 1;
...@@ -920,9 +930,6 @@ static void InstructionSignalHandler( int i_signal ) ...@@ -920,9 +930,6 @@ static void InstructionSignalHandler( int i_signal )
longjmp( env, 1 ); longjmp( env, 1 );
} }
/***************************************************************************** /*****************************************************************************
* CPUCapabilities: list the processors MMX support and other capabilities * CPUCapabilities: list the processors MMX support and other capabilities
***************************************************************************** *****************************************************************************
...@@ -937,8 +944,9 @@ static int CPUCapabilities( void ) ...@@ -937,8 +944,9 @@ static int CPUCapabilities( void )
| CPU_CAPABILITY_586 | CPU_CAPABILITY_586
| CPU_CAPABILITY_MMX; | CPU_CAPABILITY_MMX;
#elif defined( SYS_DARWIN1_3 ) return( i_capabilities );
#elif defined( SYS_DARWIN1_3 )
struct host_basic_info hi; struct host_basic_info hi;
kern_return_t ret; kern_return_t ret;
host_name_port_t host; host_name_port_t host;
...@@ -966,21 +974,14 @@ static int CPUCapabilities( void ) ...@@ -966,21 +974,14 @@ static int CPUCapabilities( void )
i_capabilities |= CPU_CAPABILITY_ALTIVEC; i_capabilities |= CPU_CAPABILITY_ALTIVEC;
} }
return( i_capabilities );
#elif defined( __i386__ ) #elif defined( __i386__ )
volatile unsigned int i_eax, i_ebx, i_ecx, i_edx; volatile unsigned int i_eax, i_ebx, i_ecx, i_edx;
volatile boolean_t b_amd; volatile boolean_t b_amd;
signal( SIGILL, InstructionSignalHandler ); signal( SIGILL, InstructionSignalHandler );
# define cpuid( a ) \
asm volatile ( "cpuid" \
: "=a" ( i_eax ), \
"=b" ( i_ebx ), \
"=c" ( i_ecx ), \
"=d" ( i_edx ) \
: "a" ( a ) \
: "cc" ); \
/* test for a 486 CPU */ /* test for a 486 CPU */
asm volatile ( "pushfl\n\t" asm volatile ( "pushfl\n\t"
"popl %%eax\n\t" "popl %%eax\n\t"
...@@ -1032,20 +1033,21 @@ static int CPUCapabilities( void ) ...@@ -1032,20 +1033,21 @@ static int CPUCapabilities( void )
if( i_edx & 0x02000000 ) if( i_edx & 0x02000000 )
{ {
i_capabilities |= CPU_CAPABILITY_MMXEXT; i_capabilities |= CPU_CAPABILITY_MMXEXT;
/* We test if OS support the SSE instructions */ /* We test if OS support the SSE instructions */
i_illegal = 0; i_illegal = 0;
if(setjmp(env)==0) { /* Test a SSE instruction */ if( setjmp( env ) == 0 )
__asm__ __volatile__ ( {
"xorps %%xmm0,%%xmm0\n" /* Test a SSE instruction */
::); __asm__ __volatile__ ( "xorps %%xmm0,%%xmm0\n" : : );
} }
if( i_illegal != 1 ) if( i_illegal == 0 )
{
i_capabilities |= CPU_CAPABILITY_SSE; i_capabilities |= CPU_CAPABILITY_SSE;
} }
}
/* test for additional capabilities */ /* test for additional capabilities */
cpuid( 0x80000000 ); cpuid( 0x80000000 );
...@@ -1062,26 +1064,30 @@ static int CPUCapabilities( void ) ...@@ -1062,26 +1064,30 @@ static int CPUCapabilities( void )
if( i_edx & 0x80000000 ) if( i_edx & 0x80000000 )
{ {
i_illegal = 0; i_illegal = 0;
if(setjmp(env)==0) { /* Test a 3D Now! instruction */ if( setjmp( env ) == 0 )
__asm__ __volatile__ ( {
"pfadd %%mm0,%%mm0\n" /* Test a 3D Now! instruction */
"femms\n" __asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : );
::);
} }
if( i_illegal != 1 ) if( i_illegal == 0 )
{
i_capabilities |= CPU_CAPABILITY_3DNOW; i_capabilities |= CPU_CAPABILITY_3DNOW;
} }
}
if( b_amd && ( i_edx & 0x00400000 ) ) if( b_amd && ( i_edx & 0x00400000 ) )
{ {
i_capabilities |= CPU_CAPABILITY_MMXEXT; i_capabilities |= CPU_CAPABILITY_MMXEXT;
} }
signal( SIGILL, NULL );
return( i_capabilities );
#else #else
/* default behaviour */ /* default behaviour */
return( i_capabilities );
#endif #endif
signal( SIGILL, NULL );
return( i_capabilities );
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment