add servicets.so sources
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 6 May 2008 10:43:24 +0000 (10:43 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 6 May 2008 10:43:24 +0000 (10:43 +0000)
compile servicets.so when enigma2 headers are available
(this needs enigma2 with CVSDATA >= 20080507 and changes in enigma2.bb for
install enigma2 headers in staging dir)

acinclude.m4 [new file with mode: 0644]
configure.ac
vlcplayer/src/Makefile.am
vlcplayer/src/servicets/.cvsignore [new file with mode: 0644]
vlcplayer/src/servicets/Makefile.am [new file with mode: 0644]
vlcplayer/src/servicets/servicets.cpp [new file with mode: 0644]
vlcplayer/src/servicets/servicets.h [new file with mode: 0644]

diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644 (file)
index 0000000..3bb5b10
--- /dev/null
@@ -0,0 +1,485 @@
+AC_DEFUN([TUXBOX_APPS],[
+
+INSTALL="$INSTALL -p"
+
+AC_GNU_SOURCE
+AC_SYS_LARGEFILE
+
+AC_ARG_WITH(target,
+       [  --with-target=TARGET    target for compilation [[native,cdk]]],
+       [TARGET="$withval"],[TARGET="native"])
+
+AC_ARG_WITH(targetprefix,
+       [  --with-targetprefix=PATH  prefix relative to target root (only applicable in cdk mode)],
+       [targetprefix="$withval"],[targetprefix="NONE"])
+
+AC_ARG_WITH(debug,
+       [  --without-debug         disable debugging code],
+       [DEBUG="$withval"],[DEBUG="yes"])
+
+if test "$DEBUG" = "yes"; then
+       DEBUG_CFLAGS="-g3 -ggdb"
+       AC_DEFINE(DEBUG,1,[Enable debug messages])
+fi
+
+AC_MSG_CHECKING(target)
+
+if test "$TARGET" = "native"; then
+       AC_MSG_RESULT(native)
+
+       if test "$CFLAGS" = "" -a "$CXXFLAGS" = ""; then
+               CFLAGS="-Wall -O2 -pipe $DEBUG_CFLAGS"
+               CXXFLAGS="-Wall -O2 -pipe $DEBUG_CFLAGS"
+       fi
+       if test "$prefix" = "NONE"; then
+               prefix=/usr/local
+       fi
+       targetprefix=$prefix
+elif test "$TARGET" = "cdk"; then
+       AC_MSG_RESULT(cdk)
+
+       if test "$CC" = "" -a "$CXX" = ""; then
+               CC=powerpc-tuxbox-linux-gnu-gcc CXX=powerpc-tuxbox-linux-gnu-g++
+       fi
+       if test "$CFLAGS" = "" -a "$CXXFLAGS" = ""; then
+               CFLAGS="-Wall -Os -mcpu=823 -pipe $DEBUG_CFLAGS"
+               CXXFLAGS="-Wall -Os -mcpu=823 -pipe $DEBUG_CFLAGS"
+       fi
+       if test "$prefix" = "NONE"; then
+               AC_MSG_ERROR(invalid prefix, you need to specify one in cdk mode)
+       fi
+       if test "$targetprefix" = "NONE"; then
+               targetprefix=""
+       fi
+       if test "$host_alias" = ""; then
+               cross_compiling=yes
+               host_alias=powerpc-tuxbox-linux-gnu
+       fi
+else
+       AC_MSG_RESULT(none)
+       AC_MSG_ERROR([invalid target $TARGET, choose on from native,cdk]);
+fi
+
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+
+check_path () {
+       return $(perl -e "if(\"$1\"=~m#^/usr/(local/)?bin#){print \"0\"}else{print \"1\";}")
+}
+
+])
+
+AC_DEFUN([TUXBOX_APPS_DIRECTORY_ONE],[
+AC_ARG_WITH($1,[  $6$7 [[PREFIX$4$5]]],[
+       _$2=$withval
+       if test "$TARGET" = "cdk"; then
+               $2=`eval echo "${targetprefix}$withval"`
+       else
+               $2=$withval
+       fi
+],[
+       $2="\${$3}$5"
+       if test "$TARGET" = "cdk"; then
+               _$2=`eval echo "${target$3}$5"`
+       else
+               _$2=`eval echo "${$3}$5"`
+       fi
+])
+
+dnl automake <= 1.6 don't support this
+dnl AC_SUBST($2)
+AC_DEFINE_UNQUOTED($2,"$_$2",$7)
+])
+
+AC_DEFUN([TUXBOX_APPS_DIRECTORY],[
+AC_REQUIRE([TUXBOX_APPS])
+
+if test "$TARGET" = "cdk"; then
+       datadir="\${prefix}/share"
+       tuxboxdatadir="\${prefix}/share/tuxbox"
+       zoneinfodir="\${datadir}/zoneinfo"
+       sysconfdir="\${prefix}/etc"
+       localstatedir="\${prefix}/var"
+       localedir="\${prefix}/var"
+       libdir="\${prefix}/lib"
+       targetdatadir="\${targetprefix}/share"
+       targetsysconfdir="\${targetprefix}/etc"
+       targetlocalstatedir="\${targetprefix}/var"
+       targetlibdir="\${targetprefix}/lib"
+fi
+
+TUXBOX_APPS_DIRECTORY_ONE(configdir,CONFIGDIR,sysconfdir,/etc,,
+       [--with-configdir=PATH   ],[where to find the config files])
+
+TUXBOX_APPS_DIRECTORY_ONE(datadir,DATADIR,datadir,/share,,
+       [--with-datadir=PATH     ],[where to find data])
+
+TUXBOX_APPS_DIRECTORY_ONE(localedir,LOCALEDIR,datadir,/share,/locale,
+       [--with-localedir=PATH ],[where to find locales])
+
+TUXBOX_APPS_DIRECTORY_ONE(fontdir,FONTDIR,datadir,/share,/fonts,
+       [--with-fontdir=PATH     ],[where to find the fonts])
+
+TUXBOX_APPS_DIRECTORY_ONE(gamesdir,GAMESDIR,localstatedir,/var,/tuxbox/games,
+       [--with-gamesdir=PATH    ],[where games data is stored])
+
+TUXBOX_APPS_DIRECTORY_ONE(libdir,LIBDIR,libdir,/lib,,
+       [--with-libdir=PATH      ],[where to find the internal libs])
+
+TUXBOX_APPS_DIRECTORY_ONE(plugindir,PLUGINDIR,libdir,/lib,/tuxbox/plugins,
+       [--with-plugindir=PATH   ],[where to find the plugins])
+
+TUXBOX_APPS_DIRECTORY_ONE(tuxboxdatadir,TUXBOXDATADIR,datadir,/share,,
+       [--with-tuxboxdatadir=PATH],[where to find tuxbox data])
+
+TUXBOX_APPS_DIRECTORY_ONE(zoneinfodir,ZONEINFODIR,datadir,/share,/zoneinfo,
+       [--with-zoneinfodir=PATH ],[where to find zoneinfo db])
+])
+
+dnl automake <= 1.6 needs this specifications
+AC_SUBST(CONFIGDIR)
+AC_SUBST(DATADIR)
+AC_SUBST(ZONEINFODIR)
+AC_SUBST(FONTDIR)
+AC_SUBST(GAMESDIR)
+AC_SUBST(LIBDIR)
+AC_SUBST(LOCALEDIR)
+AC_SUBST(PLUGINDIR)
+AC_SUBST(TUXBOXDATADIR)
+dnl end workaround
+
+AC_DEFUN([TUXBOX_APPS_ENDIAN],[
+AC_CHECK_HEADERS(endian.h)
+AC_C_BIGENDIAN
+])
+
+AC_DEFUN([TUXBOX_APPS_DRIVER],[
+#AC_ARG_WITH(driver,
+#      [  --with-driver=PATH      path for driver sources [[NONE]]],
+#      [DRIVER="$withval"],[DRIVER=""])
+#
+#if test -d "$DRIVER/include"; then
+#      AC_DEFINE(HAVE_DBOX2_DRIVER,1,[Define to 1 if you have the dbox2 driver sources])
+#else
+#      AC_MSG_ERROR([can't find driver sources])
+#fi
+
+#AC_SUBST(DRIVER)
+
+#CPPFLAGS="$CPPFLAGS -I$DRIVER/include"
+])
+
+AC_DEFUN([TUXBOX_APPS_DVB],[
+AC_ARG_WITH(dvbincludes,
+       [  --with-dvbincludes=PATH  path for dvb includes [[NONE]]],
+       [DVBINCLUDES="$withval"],[DVBINCLUDES=""])
+
+if test "$DVBINCLUDES"; then
+       CPPFLAGS="$CPPFLAGS -I$DVBINCLUDES"
+fi
+
+AC_CHECK_HEADERS(ost/dmx.h,[
+       DVB_API_VERSION=1
+       AC_MSG_NOTICE([found dvb version 1])
+])
+
+if test -z "$DVB_API_VERSION"; then
+AC_CHECK_HEADERS(linux/dvb/version.h,[
+       AC_LANG_PREPROC_REQUIRE()
+       AC_REQUIRE([AC_PROG_EGREP])
+       AC_LANG_CONFTEST([AC_LANG_SOURCE([[
+#include <linux/dvb/version.h>
+version DVB_API_VERSION
+       ]])])
+       DVB_API_VERSION=`(eval "$ac_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | $EGREP "^version" | sed "s,version\ ,,"`
+       rm -f conftest*
+
+       AC_MSG_NOTICE([found dvb version $DVB_API_VERSION])
+])
+fi
+
+if test "$DVB_API_VERSION"; then
+       AC_DEFINE(HAVE_DVB,1,[Define to 1 if you have the dvb includes])
+       AC_DEFINE_UNQUOTED(HAVE_DVB_API_VERSION,$DVB_API_VERSION,[Define to the version of the dvb api])
+else
+       AC_MSG_ERROR([can't find dvb headers])
+fi
+])
+
+AC_DEFUN([_TUXBOX_APPS_LIB_CONFIG],[
+AC_PATH_PROG($1_CONFIG,$2,no)
+if test "$$1_CONFIG" != "no"; then
+       if test "$TARGET" = "cdk" && check_path "$$1_CONFIG"; then
+               AC_MSG_$3([could not find a suitable version of $2]);
+       else
+               $1_CFLAGS=$($$1_CONFIG --cflags)
+               $1_LIBS=$($$1_CONFIG --libs)
+       fi
+fi
+
+AC_SUBST($1_CFLAGS)
+AC_SUBST($1_LIBS)
+])
+
+AC_DEFUN([TUXBOX_APPS_LIB_CONFIG],[
+_TUXBOX_APPS_LIB_CONFIG($1,$2,ERROR)
+if test "$$1_CONFIG" = "no"; then
+       AC_MSG_ERROR([could not find $2]);
+fi
+])
+
+AC_DEFUN([TUXBOX_APPS_LIB_CONFIG_CHECK],[
+_TUXBOX_APPS_LIB_CONFIG($1,$2,WARN)
+])
+
+AC_DEFUN([TUXBOX_APPS_PKGCONFIG],[
+AC_PATH_PROG(PKG_CONFIG, pkg-config,no)
+if test "$PKG_CONFIG" = "no" ; then
+       AC_MSG_ERROR([could not find pkg-config]);
+fi
+])
+
+AC_DEFUN([_TUXBOX_APPS_LIB_PKGCONFIG],[
+PKG_CHECK_MODULES($1,$2)
+AC_SUBST($1_CFLAGS)
+AC_SUBST($1_LIBS)
+])
+
+AC_DEFUN([_TUXBOX_APPS_LIB_PKGCONFIG_OPTIONAL],[
+PKG_CHECK_MODULES($1,$2,$3="yes",$3="no")
+if test "$$3" = "yes"; then
+       AC_DEFINE($3, 1, [$2 available])
+else
+       $1_CFLAGS=""
+       $1_LIBS=""
+fi
+AC_SUBST($1_CFLAGS)
+AC_SUBST($1_LIBS)
+])
+
+AC_DEFUN([TUXBOX_APPS_LIB_PKGCONFIG],[
+_TUXBOX_APPS_LIB_PKGCONFIG($1,$2)
+if test -z "$$1_CFLAGS" ; then
+       AC_MSG_ERROR([could not find package $2]);
+fi
+])
+
+AC_DEFUN([TUXBOX_APPS_LIB_PKGCONFIG_CHECK],[
+_TUXBOX_APPS_LIB_PKGCONFIG($1,$2)
+])
+
+AC_DEFUN([_TUXBOX_APPS_LIB_SYMBOL],[
+AC_CHECK_LIB($2,$3,HAVE_$1="yes",HAVE_$1="no")
+if test "$HAVE_$1" = "yes"; then
+       $1_LIBS=-l$2
+fi
+
+AC_SUBST($1_LIBS)
+])
+
+AC_DEFUN([TUXBOX_APPS_LIB_SYMBOL],[
+_TUXBOX_APPS_LIB_SYMBOL($1,$2,$3,ERROR)
+if test "$HAVE_$1" = "no"; then
+       AC_MSG_ERROR([could not find $2]);
+fi
+])
+
+AC_DEFUN([TUXBOX_APPS_LIB_CONFIG_SYMBOL],[
+_TUXBOX_APPS_LIB_SYMBOL($1,$2,$3,WARN)
+])
+
+AC_DEFUN([TUXBOX_APPS_GETTEXT],[
+AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+       [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 &&
+       (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+       :)
+AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+
+AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+       [$ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 &&
+       (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+       :)
+
+AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,[$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1],:)
+
+AC_MSG_CHECKING([whether NLS is requested])
+AC_ARG_ENABLE(nls,
+       [  --disable-nls           do not use Native Language Support],
+       USE_NLS=$enableval, USE_NLS=yes)
+AC_MSG_RESULT($USE_NLS)
+AC_SUBST(USE_NLS)
+
+if test "$USE_NLS" = "yes"; then
+       AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc,[
+               AC_TRY_LINK([
+                       #include <libintl.h>
+                       #ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+                       #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+                       #endif
+                       extern int _nl_msg_cat_cntr;
+                       extern int *_nl_domain_bindings;
+                       ],[
+                       bindtextdomain ("", "");
+                       return (int) gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings;
+                       ], gt_cv_func_gnugettext_libc=yes, gt_cv_func_gnugettext_libc=no
+               )]
+       )
+
+       if test "$gt_cv_func_gnugettext_libc" = "yes"; then
+               AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if translation of program messages to the user's native language is requested.])
+               gt_use_preinstalled_gnugettext=yes
+       else
+               USE_NLS=no
+       fi
+fi
+
+if test -f "$srcdir/po/LINGUAS"; then
+       ALL_LINGUAS=$(sed -e "/^#/d" "$srcdir/po/LINGUAS")
+fi
+
+POFILES=
+GMOFILES=
+UPDATEPOFILES=
+DUMMYPOFILES=
+for lang in $ALL_LINGUAS; do
+       POFILES="$POFILES $srcdirpre$lang.po"
+       GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+       UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+       DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+done
+INST_LINGUAS=
+if test -n "$ALL_LINGUAS"; then
+       for presentlang in $ALL_LINGUAS; do
+               useit=no
+               if test -n "$LINGUAS"; then
+                       desiredlanguages="$LINGUAS"
+               else
+                       desiredlanguages="$ALL_LINGUAS"
+               fi
+               for desiredlang in $desiredlanguages; do
+                       case "$desiredlang" in
+                               "$presentlang"*) useit=yes;;
+                       esac
+               done
+               if test $useit = yes; then
+                       INST_LINGUAS="$INST_LINGUAS $presentlang"
+               fi
+       done
+fi
+CATALOGS=
+if test -n "$INST_LINGUAS"; then
+       for lang in $INST_LINGUAS; do
+               CATALOGS="$CATALOGS $lang.gmo"
+       done
+fi
+AC_SUBST(POFILES)
+AC_SUBST(GMOFILES)
+AC_SUBST(UPDATEPOFILES)
+AC_SUBST(DUMMYPOFILES)
+AC_SUBST(CATALOGS)
+])
+
+dnl backward compatiblity
+AC_DEFUN([AC_GNU_SOURCE],
+[AH_VERBATIM([_GNU_SOURCE],
+[/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif])dnl
+AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl
+AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
+AC_DEFINE([_GNU_SOURCE])
+])
+
+AC_DEFUN([AC_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+   [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])
+
+AC_DEFUN([AC_PYTHON_DEVEL],[
+       #
+       # should allow for checking of python version here...
+       #
+       if test $cross_compiling = "yes"; then
+               # Check for Python include path
+               AC_MSG_CHECKING([for Python include path])
+               
+               # FIXME: yes, this is wrong. sorry about that. (tmbinc)
+               cross_PYTHON_VERSION=$PYTHON_VERSION
+               python_path=
+               for i in $CPPFLAGS ; do
+                       p=`echo $i | sed "s,^-I,,"`
+                       if test -f "$p/python$cross_PYTHON_VERSION/Python.h"; then
+                               python_path="$p/python$cross_PYTHON_VERSION"
+                               break
+                       fi
+               done
+               AC_MSG_RESULT([$python_path])
+               if test -z "$python_path" ; then
+                                               AC_MSG_ERROR([cannot find Python include path])
+               fi
+               AC_SUBST([PYTHON_CPPFLAGS],[-I$python_path])
+
+               # Check for Python library path
+               AC_MSG_CHECKING([for Python library path])
+               python_path=
+               for i in $LDFLAGS; do
+                       l=`echo $i | sed "s,^-L,,"`
+                       python_path=`find $l -type f -name libpython$cross_PYTHON_VERSION.* -print | sed "1q"`
+                       if test -n "$python_path" ; then
+                               break
+                       fi
+               done
+               python_path=`echo $python_path | sed "s,/libpython.*$,,"`
+               AC_MSG_RESULT([$python_path])
+               if test -z "$python_path" ; then
+                                               AC_MSG_ERROR([cannot find Python library path])
+               fi
+               AC_SUBST([PYTHON_LDFLAGS],["-L$python_path -lpython$cross_PYTHON_VERSION"])
+               #
+               python_site=`echo $python_path | sed "s/config/site-packages/"`
+               AC_SUBST([PYTHON_SITE_PKG],[$python_site])
+       else
+               AC_REQUIRE([AM_PATH_PYTHON])
+
+               # Check for Python include path
+               AC_MSG_CHECKING([for Python include path])
+               python_path=`echo $PYTHON | sed "s,/bin.*$,,"`
+               for i in "$python_path/include/python$PYTHON_VERSION/" "$python_path/include/python/" "$python_path/" ; do
+                       python_path=`find $i -type f -name Python.h -print | sed "1q"`
+                       if test -n "$python_path" ; then
+                               break
+                       fi
+               done
+               python_path=`echo $python_path | sed "s,/Python.h$,,"`
+               AC_MSG_RESULT([$python_path])
+               if test -z "$python_path" ; then
+                       AC_MSG_ERROR([cannot find Python include path])
+               fi
+               AC_SUBST([PYTHON_CPPFLAGS],[-I$python_path])
+
+               # Check for Python library path
+               AC_MSG_CHECKING([for Python library path])
+               python_path=`echo $PYTHON | sed "s,/bin.*$,,"`
+               for i in "$python_path/lib/python$PYTHON_VERSION/config/" "$python_path/lib/python$PYTHON_VERSION/" "$python_path/lib/python/config/" "$python_path/lib/python/" "$python_path/" ; do
+                       python_path=`find $i -type f -name libpython$PYTHON_VERSION.* -print | sed "1q"`
+                       if test -n "$python_path" ; then
+                               break
+                       fi
+               done
+               python_path=`echo $python_path | sed "s,/libpython.*$,,"`
+               AC_MSG_RESULT([$python_path])
+               if test -z "$python_path" ; then
+                       AC_MSG_ERROR([cannot find Python library path])
+               fi
+               AC_SUBST([PYTHON_LDFLAGS],["-L$python_path -lpython$PYTHON_VERSION"])
+               #
+               python_site=`echo $python_path | sed "s/config/site-packages/"`
+               AC_SUBST([PYTHON_SITE_PKG],[$python_site])
+       fi
+])
index ad9aa1b..0eebd85 100644 (file)
@@ -3,6 +3,20 @@ AM_INIT_AUTOMAKE(enigma2-plugins, 1.0)
 
 AM_PATH_PYTHON()
 
+AC_CHECK_HEADER(enigma2/lib/base/i18n.h,have_e2_includes="yes",have_e2_includes="no")
+if test x"${have_e2_includes}" = "xyes"; then
+       AC_PYTHON_DEVEL
+       TUXBOX_APPS
+       TUXBOX_APPS_DIRECTORY
+       TUXBOX_APPS_DVB
+       TUXBOX_APPS_LIB_PKGCONFIG(ENIGMA2,enigma2)
+       TUXBOX_APPS_LIB_PKGCONFIG(SIGC,sigc++-1.2)
+       AC_DEFINE(HAVE_E2_INCLUDES, 1,[Define if enigm2 includes are available])
+else
+       AC_MSG_NOTICE([enigma2 headers not found.. dont build servicets.so])
+fi
+AM_CONDITIONAL(HAVE_E2_INCLUDES, test "$have_e2_includes" = "yes")
+
 AC_OUTPUT([
 Makefile
 antiscrollbar/Makefile
@@ -53,6 +67,7 @@ logomanager/logodir_hdd/Makefile
 
 vlcplayer/Makefile
 vlcplayer/src/Makefile
+vlcplayer/src/servicets/Makefile
 
 fritzcall/Makefile
 fritzcall/src/Makefile
index 1ca3222..7d7fcb7 100755 (executable)
@@ -1,3 +1,11 @@
+if HAVE_E2_INCLUDES
+SUBDIRS = servicets
+endif
+
 installdir = /usr/lib/enigma2/python/Plugins/Extensions/VlcPlayer
 
-install_PYTHON = *.py *.so
+if HAVE_E2_INCLUDES
+install_PYTHON = *.py servicets/servicets.so
+else
+install_PYTHON = *.py servicets.so
+endif
diff --git a/vlcplayer/src/servicets/.cvsignore b/vlcplayer/src/servicets/.cvsignore
new file mode 100644 (file)
index 0000000..4181869
--- /dev/null
@@ -0,0 +1,5 @@
+*.pyc
+*.pyo
+*.so
+Makefile
+Makefile.in
diff --git a/vlcplayer/src/servicets/Makefile.am b/vlcplayer/src/servicets/Makefile.am
new file mode 100644 (file)
index 0000000..6af7915
--- /dev/null
@@ -0,0 +1,8 @@
+servicets.so: servicets.cpp servicets.h
+       $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(ENIGMA2_CFLAGS) $(SIGC_CFLAGS) \
+       $(PYTHON_CPPFLAGS) $(DEFS) -I. -Wall -W servicets.cpp -shared -fPIC \
+       -Wl,-soname,servicets.so -o servicets.so $(LDFLAGS)
+
+all: servicets.so
+
+CLEANFILES = servicets.so
diff --git a/vlcplayer/src/servicets/servicets.cpp b/vlcplayer/src/servicets/servicets.cpp
new file mode 100644 (file)
index 0000000..dbe807d
--- /dev/null
@@ -0,0 +1,528 @@
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <signal.h>
+#include "servicets.h"
+#include <lib/base/eerror.h>
+#include <lib/base/object.h>
+#include <lib/base/ebase.h>
+#include <servicets.h>
+#include <lib/service/service.h>
+#include <lib/base/init_num.h>
+#include <lib/base/init.h>
+#include <lib/dvb/decoder.h>
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+// eServiceFactoryTS
+
+eServiceFactoryTS::eServiceFactoryTS()
+{
+       ePtr<eServiceCenter> sc;
+       
+       eServiceCenter::getPrivInstance(sc);
+       if (sc)
+       {
+               std::list<std::string> extensions;
+               sc->addServiceFactory(eServiceFactoryTS::id, this, extensions);
+       }
+
+       m_service_info = new eStaticServiceTSInfo();
+}
+
+eServiceFactoryTS::~eServiceFactoryTS()
+{
+       ePtr<eServiceCenter> sc;
+       
+       eServiceCenter::getPrivInstance(sc);
+       if (sc)
+               sc->removeServiceFactory(eServiceFactoryTS::id);
+}
+
+DEFINE_REF(eServiceFactoryTS)
+
+       // iServiceHandler
+RESULT eServiceFactoryTS::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
+{
+               // check resources...
+       ptr = new eServiceTS(ref);
+       return 0;
+}
+
+RESULT eServiceFactoryTS::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
+{
+       ptr=0;
+       return -1;
+}
+
+RESULT eServiceFactoryTS::list(const eServiceReference &, ePtr<iListableService> &ptr)
+{
+       ptr=0;
+       return -1;
+}
+
+RESULT eServiceFactoryTS::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
+{
+       ptr = m_service_info;
+       return 0;
+}
+
+RESULT eServiceFactoryTS::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
+{
+       ptr = 0;
+       return -1;
+}
+
+
+// eStaticServiceTSInfo
+DEFINE_REF(eStaticServiceTSInfo)
+
+eStaticServiceTSInfo::eStaticServiceTSInfo()
+{
+}
+
+RESULT eStaticServiceTSInfo::getName(const eServiceReference &ref, std::string &name)
+{
+       size_t last = ref.path.rfind('/');
+       if (last != std::string::npos)
+               name = ref.path.substr(last+1);
+       else
+               name = ref.path;
+       return 0;
+}
+
+int eStaticServiceTSInfo::getLength(const eServiceReference &ref)
+{
+       return -1;
+}
+
+// eServiceTS
+
+eServiceTS::eServiceTS(const eServiceReference &url): m_pump(eApp, 1)
+{
+       eDebug("ServiceTS construct!");
+       m_filename = url.path.c_str();
+       m_vpid = url.getData(0) == 0 ? 0x44 : url.getData(0);
+       m_apid = url.getData(1) == 0 ? 0x45 : url.getData(1);
+       m_state = stIdle;
+}
+
+eServiceTS::~eServiceTS()
+{
+       eDebug("ServiceTS destruct!");
+       if (m_state == stRunning)
+               stop();
+}
+
+DEFINE_REF(eServiceTS);        
+
+size_t crop(char *buf)
+{
+       size_t len = strlen(buf) - 1;
+       while (len > 0 && (buf[len] == '\r' || buf[len] == '\n')) {
+               buf[len--] = '\0';
+       }
+       return len;
+}
+
+static int getline(char** pbuffer, size_t* pbufsize, int fd) 
+{
+       size_t i = 0;
+       int rc;
+       while (true) {
+               if (i >= *pbufsize) {
+                       char *newbuf = (char*)realloc(*pbuffer, (*pbufsize)+1024);
+                       if (newbuf == NULL)
+                               return -ENOMEM;
+                       *pbuffer = newbuf;
+                       *pbufsize = (*pbufsize)+1024;
+               }
+               rc = ::read(fd, (*pbuffer)+i, 1);
+               if (rc <= 0 || (*pbuffer)[i] == '\n')
+               {
+                       (*pbuffer)[i] = '\0';
+                       return rc <= 0 ? -1 : i;
+               }
+               if ((*pbuffer)[i] != '\r') i++;
+       }
+}
+
+int eServiceTS::openHttpConnection(std::string url)
+{
+       std::string host;
+       int port = 80;
+       std::string uri;
+
+       int slash = url.find("/", 7);
+       if (slash > 0) {
+               host = url.substr(7, slash-7);
+               uri = url.substr(slash, url.length()-slash);
+       } else {
+               host = url.substr(7, url.length()-7);
+               uri = "";
+       }
+       int dp = host.find(":");
+       if (dp == 0) {
+               port = atoi(host.substr(1, host.length()-1).c_str());
+               host = "localhost";
+       } else if (dp > 0) {
+               port = atoi(host.substr(dp+1, host.length()-dp-1).c_str());
+               host = host.substr(0, dp);
+       }
+
+       struct hostent* h = gethostbyname(host.c_str());
+       if (h == NULL || h->h_addr_list == NULL)
+               return -1;
+       int fd = socket(PF_INET, SOCK_STREAM, 0);
+       if (fd == -1)
+               return -1;
+
+       struct sockaddr_in addr;
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = *((in_addr_t*)h->h_addr_list[0]);
+       addr.sin_port = htons(port);
+
+       eDebug("connecting to %s", url.c_str());
+
+       if (connect(fd, (sockaddr*)&addr, sizeof(addr)) == -1) {
+               std::string msg = "connect failed for: " + url;
+               eDebug(msg.c_str());
+               return -1;
+       }
+
+       std::string request = "GET ";
+       request.append(uri).append(" HTTP/1.1\n");
+       request.append("Host: ").append(host).append("\n");
+       request.append("Accept: */*\n");
+       request.append("Connection: close\n");
+       request.append("\n");
+       //eDebug(request.c_str());
+       write(fd, request.c_str(), request.length());
+
+       int rc;
+       size_t buflen = 1000;
+       char* linebuf = (char*)malloc(1000);
+
+       rc = getline(&linebuf, &buflen, fd);
+       //eDebug("RECV(%d): %s", rc, linebuf);
+       if (rc <= 0)
+       {
+               close(fd);
+               free(linebuf);
+               return -1;
+       }
+
+       char proto[100];
+       int statuscode = 0;
+       char statusmsg[100];
+       rc = sscanf(linebuf, "%99s %d %99s", proto, &statuscode, statusmsg);
+       if (rc != 3 || statuscode != 200) {
+               eDebug("wrong response: \"200 OK\" expected.");
+               free(linebuf);
+               close(fd);
+               return -1;
+       }
+       eDebug("proto=%s, code=%d, msg=%s", proto, statuscode, statusmsg);
+       while (rc > 0)
+       {
+               rc = getline(&linebuf, &buflen, fd);
+               //eDebug("RECV(%d): %s", rc, linebuf);
+       }
+       free(linebuf);
+
+       return fd;
+}
+
+RESULT eServiceTS::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
+{
+       connection = new eConnection((iPlayableService*)this, m_event.connect(event));
+       return 0;
+}
+
+RESULT eServiceTS::start()
+{
+       ePtr<eDVBResourceManager> rmgr;
+       eDVBResourceManager::getInstance(rmgr);
+       if (rmgr->allocateDemux(NULL, m_decodedemux, iDVBChannel::capDecode) != 0) {
+               eDebug("Cannot allocate decode-demux");
+               return 1;
+       }
+       if (m_decodedemux->get().getMPEGDecoder(m_decoder, 1) != 0) {
+               eDebug("Cannot allocate MPEGDecoder");
+               return 1;
+       }
+       m_decodedemux->get().setSourcePVR(0);
+       m_decoder->setVideoPID(m_vpid, eDVBVideo::MPEG2);
+       m_decoder->setAudioPID(m_apid, eDVBAudio::aMPEG);
+       m_streamthread = new eStreamThread();
+       CONNECT(m_streamthread->m_event, eServiceTS::recv_event);
+       m_decoder->freeze(0);
+       m_decoder->preroll();
+       if (unpause() != 0) return -1;
+       m_state = stRunning;
+       m_event(this, evStart);
+       return 0;
+}
+
+RESULT eServiceTS::stop()
+{
+       if (m_state != stRunning)
+               return -1;
+       printf("TS: %s stop\n", m_filename.c_str());
+       m_streamthread->stop();
+       m_decodedemux->get().flush();
+       m_state = stStopped;
+       return 0;
+}
+
+void eServiceTS::recv_event(int evt)
+{
+       eDebug("eServiceTS::recv_event: %d", evt);
+       switch (evt) {
+       case eStreamThread::evtEOS:
+               m_decodedemux->get().flush();
+               m_state = stStopped;
+               m_event((iPlayableService*)this, evEOF);
+               break;
+       case eStreamThread::evtReadError:
+       case eStreamThread::evtWriteError:
+               m_decoder->freeze(0);
+               m_state = stStopped;
+               m_event((iPlayableService*)this, evEOF);
+       }
+}
+
+RESULT eServiceTS::setTarget(int target)
+{
+       return -1;
+}
+
+RESULT eServiceTS::pause(ePtr<iPauseableService> &ptr)
+{
+       ptr=this;
+       return 0;
+}
+
+RESULT eServiceTS::setSlowMotion(int ratio)
+{
+       return -1;
+}
+
+RESULT eServiceTS::setFastForward(int ratio)
+{
+       return -1;
+}
+  
+               // iPausableService
+RESULT eServiceTS::pause()
+{
+       m_streamthread->stop();
+       m_decoder->freeze(0);
+       return 0;
+}
+
+RESULT eServiceTS::unpause()
+{
+       int is_streaming = !strncmp(m_filename.c_str(), "http://", 7);
+       int srcfd = -1;
+       if (is_streaming) {
+               srcfd = openHttpConnection(m_filename);
+       } else {
+               srcfd = ::open(m_filename.c_str(), O_RDONLY);
+       }
+       if (srcfd < 0) {
+               eDebug("Cannot open source stream: %s", m_filename.c_str());
+               return 1;
+       }
+       
+       int destfd = ::open("/dev/misc/pvr", O_WRONLY);
+       if (destfd < 0) {
+               eDebug("Cannot open source stream: %s", m_filename.c_str());
+               ::close(srcfd);
+               return 1;
+       }
+       m_decodedemux->get().flush();
+       m_streamthread->start(srcfd, destfd);
+       // let the video buffer fill up a bit
+       usleep(200*1000);
+       m_decoder->unfreeze();
+       return 0;
+}
+
+       /* iSeekableService */
+RESULT eServiceTS::seek(ePtr<iSeekableService> &ptr)
+{
+       ptr = this;
+       return 0;
+}
+
+RESULT eServiceTS::getLength(pts_t &pts)
+{
+       return 0;
+}
+
+RESULT eServiceTS::seekTo(pts_t to)
+{
+       return 0;
+}
+
+RESULT eServiceTS::seekRelative(int direction, pts_t to)
+{
+       return 0;
+}
+
+RESULT eServiceTS::getPlayPosition(pts_t &pts)
+{
+       return 0;
+}
+
+RESULT eServiceTS::setTrickmode(int trick)
+{
+       return -1;
+}
+
+
+RESULT eServiceTS::isCurrentlySeekable()
+{
+       return 1;
+}
+
+RESULT eServiceTS::info(ePtr<iServiceInformation>&i)
+{
+       i = this;
+       return 0;
+}
+
+RESULT eServiceTS::getName(std::string &name)
+{
+       name = m_filename;
+       size_t n = name.rfind('/');
+       if (n != std::string::npos)
+               name = name.substr(n + 1);
+       return 0;
+}
+
+int eServiceTS::getInfo(int w)
+{
+       return resNA;
+}
+
+std::string eServiceTS::getInfoString(int w)
+{
+       return "";
+}
+
+DEFINE_REF(eStreamThread)
+
+eStreamThread::eStreamThread(): m_messagepump(eApp, 0) {
+       CONNECT(m_messagepump.recv_msg, eStreamThread::recvEvent);
+}
+eStreamThread::~eStreamThread() {
+}
+
+void eStreamThread::start(int srcfd, int destfd) {
+       m_srcfd = srcfd;
+       m_destfd = destfd;
+       m_stop = false;
+       run(IOPRIO_CLASS_RT);
+}
+void eStreamThread::stop() {
+       m_stop = true;
+       kill();
+}
+
+void eStreamThread::recvEvent(const int &evt)
+{
+       m_event(evt);
+}
+
+void eStreamThread::thread() {
+       const int bufsize = 60000;
+       unsigned char buf[bufsize];
+       bool eof = false;
+       fd_set rfds;
+       fd_set wfds;
+       struct timeval timeout;
+       int rc,r,w,maxfd;
+       
+       r = w = 0;
+       hasStarted();
+       eDebug("eStreamThread started");
+       while (!m_stop) {
+               pthread_testcancel();
+               FD_ZERO(&rfds);
+               FD_ZERO(&wfds);
+               maxfd = 0;
+               timeout.tv_sec = 1;
+               timeout.tv_usec = 0;
+               if (r < bufsize) {
+                       FD_SET(m_srcfd, &rfds);
+                       maxfd = MAX(maxfd, m_srcfd);
+               }
+               if (w < r) {
+                       FD_SET(m_destfd, &wfds);
+                       maxfd = MAX(maxfd, m_destfd);
+               }
+               rc = select(maxfd+1, &rfds, &wfds, NULL, &timeout);
+               if (rc == 0) {
+                       eDebug("eStreamThread::thread: timeout!");
+                       continue;
+               }
+               if (rc < 0) {
+                       eDebug("eStreamThread::thread: error in select (%d)", errno);
+                       break;
+               }
+               if (FD_ISSET(m_srcfd, &rfds)) {
+                       rc = ::read(m_srcfd, buf+r, bufsize - r);
+                       if (rc < 0) {
+                               eDebug("eStreamThread::thread: error in read (%d)", errno);
+                               m_messagepump.send(evtReadError);
+                               break;
+                       } else if (rc == 0) {
+                               eof = true;
+                       } else {
+                               r += rc;
+                               if (r == bufsize) eDebug("eStreamThread::thread: buffer full");
+                       }
+               }
+               if (FD_ISSET(m_destfd, &wfds) && (w < r)) {
+                       rc = ::write(m_destfd, buf+w, r-w);
+                       if (rc < 0) {
+                               eDebug("eStreamThread::thread: error in write (%d)", errno);
+                               m_messagepump.send(evtWriteError);
+                               break;
+                       }
+                       w += rc;
+                       //eDebug("eStreamThread::thread: buffer r=%d w=%d",r,w);
+                       if (w == r) w = r = 0;
+               }
+               if (eof && (r==w)) {
+                       ::close(m_destfd);
+                       m_destfd = -1;
+                       ::close(m_srcfd);
+                       m_srcfd = -1;
+                       m_messagepump.send(evtEOS);
+                       break;
+               }
+       }
+       eDebug("eStreamThread end");
+}
+
+void eStreamThread::thread_finished() {
+       if (m_srcfd >= 0) ::close(m_srcfd);
+       if (m_destfd >= 0) ::close(m_destfd);
+       eDebug("eStreamThread closed");
+}
+
+eAutoInitPtr<eServiceFactoryTS> init_eServiceFactoryTS(eAutoInitNumbers::service+1, "eServiceFactoryTS");
+
+PyMODINIT_FUNC
+initservicets(void)
+{
+       Py_InitModule("servicets", NULL);
+}
diff --git a/vlcplayer/src/servicets/servicets.h b/vlcplayer/src/servicets/servicets.h
new file mode 100644 (file)
index 0000000..f426c59
--- /dev/null
@@ -0,0 +1,134 @@
+#ifndef __servicets_h
+#define __servicets_h
+
+#include <lib/base/ioprio.h>
+#include <lib/base/message.h>
+#include <lib/service/iservice.h>
+#include <lib/dvb/dvb.h>
+
+class eStaticServiceTSInfo;
+
+class eServiceFactoryTS: public iServiceHandler
+{
+DECLARE_REF(eServiceFactoryTS);
+public:
+       eServiceFactoryTS();
+       virtual ~eServiceFactoryTS();
+       enum { id = 0x1002 };
+
+       // iServiceHandler
+       RESULT play(const eServiceReference &, ePtr<iPlayableService> &ptr);
+       RESULT record(const eServiceReference &, ePtr<iRecordableService> &ptr);
+       RESULT list(const eServiceReference &, ePtr<iListableService> &ptr);
+       RESULT info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr);
+       RESULT offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr);
+private:
+       ePtr<eStaticServiceTSInfo> m_service_info;
+};
+
+class eStaticServiceTSInfo: public iStaticServiceInformation
+{
+       DECLARE_REF(eStaticServiceTSInfo);
+       friend class eServiceFactoryTS;
+       eStaticServiceTSInfo();
+public:
+       RESULT getName(const eServiceReference &ref, std::string &name);
+       int getLength(const eServiceReference &ref);
+};
+
+class eStreamThread;
+
+class eServiceTS: public iPlayableService, public iPauseableService, 
+       public iServiceInformation, public iSeekableService, public Object
+{
+DECLARE_REF(eServiceTS);
+public:
+       virtual ~eServiceTS();
+
+               // iPlayableService
+       RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection);
+       RESULT start();
+       RESULT stop();
+       RESULT setTarget(int target);
+       
+       RESULT pause(ePtr<iPauseableService> &ptr);
+       RESULT setSlowMotion(int ratio);
+       RESULT setFastForward(int ratio);
+
+       RESULT seek(ePtr<iSeekableService> &ptr);
+
+               // not implemented (yet)
+       RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr) { ptr = 0; return -1; }
+       RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr) { ptr = 0; return -1; }
+       RESULT frontendInfo(ePtr<iFrontendInformation> &ptr) { ptr = 0; return -1; }
+       RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }
+       RESULT timeshift(ePtr<iTimeshiftService> &ptr) { ptr = 0; return -1; }
+       RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
+       RESULT subtitle(ePtr<iSubtitleOutput> &ptr) { ptr = 0; return -1; }
+       RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
+       RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
+       RESULT stream(ePtr<iStreamableService> &ptr) { ptr = 0; return -1; }
+       RESULT keys(ePtr<iServiceKeys> &ptr) { ptr = 0; return -1; }
+               // iPausableService
+       RESULT pause();
+       RESULT unpause();
+       
+       RESULT info(ePtr<iServiceInformation>&);
+       
+               // iSeekableService
+       RESULT getLength(pts_t &SWIG_OUTPUT);
+       RESULT seekTo(pts_t to);
+       RESULT seekRelative(int direction, pts_t to);
+       RESULT getPlayPosition(pts_t &SWIG_OUTPUT);
+       RESULT setTrickmode(int trick);
+       RESULT isCurrentlySeekable();
+
+               // iServiceInformation
+       RESULT getName(std::string &name);
+       int getInfo(int w);
+       std::string getInfoString(int w);
+private:
+       friend class eServiceFactoryTS;
+       std::string m_filename;
+       int m_vpid, m_apid;
+       int m_srcfd, m_destfd;
+       ePtr<eDVBAllocatedDemux> m_decodedemux;
+       ePtr<iTSMPEGDecoder> m_decoder;
+       ePtr<eStreamThread> m_streamthread;
+       
+       eServiceTS(const eServiceReference &url);
+       int openHttpConnection(std::string url);
+       
+       Signal2<void,iPlayableService*,int> m_event;
+       enum
+       {
+               stIdle, stRunning, stStopped
+       };
+       int m_state;
+       eFixedMessagePump<int> m_pump;
+       void recv_event(int evt);
+};
+
+class eStreamThread: public eThread, public Object {
+DECLARE_REF(eStreamThread);
+public:
+       eStreamThread();
+       virtual ~eStreamThread();
+       void start(int srcfd, int destfd);
+       void stop();
+
+       virtual void thread();
+       virtual void thread_finished();
+
+       enum { evtEOS, evtReadError, evtWriteError, evtUser };
+       Signal1<void,int> m_event;
+private:
+       bool m_stop;
+       int m_srcfd, m_destfd;
+       eFixedMessagePump<int> m_messagepump;
+       void recvEvent(const int &evt);
+};
+
+#endif
+
+