From 6ea5efe93960fc761dbb5e0b2d93d9b5818d5d7c Mon Sep 17 00:00:00 2001 From: Frank Schmirler Date: Thu, 2 Dec 2010 09:57:17 +0100 Subject: Snapshot 2010-09-15 --- CONTRIBUTORS | 8 ++ HISTORY | 34 ++++++ Makefile | 153 +++++++++--------------- README | 204 +++++++++++++++++++++++--------- client/Makefile | 84 +++++++++++++ client/device.c | 24 +++- client/device.h | 6 +- client/po/de_DE.po | 50 ++++++++ client/po/fi_FI.po | 50 ++++++++ client/po/fr_FR.po | 50 ++++++++ client/po/it_IT.po | 52 +++++++++ client/po/lt_LT.po | 50 ++++++++ client/po/ru_RU.po | 50 ++++++++ client/po/sk_SK.po | 52 +++++++++ client/socket.c | 36 ++++-- client/socket.h | 5 +- client/streamdev-client.c | 59 ++++++++++ client/streamdev-client.h | 29 +++++ common.c | 4 +- common.h | 4 +- libdvbmpeg/Makefile | 41 ++++--- po/de_DE.po | 115 ------------------ po/fi_FI.po | 115 ------------------ po/fr_FR.po | 115 ------------------ po/it_IT.po | 117 ------------------- po/lt_LT.po | 115 ------------------ po/ru_RU.po | 115 ------------------ po/sk_SK.po | 118 ------------------- remux/Makefile | 34 ++++++ remux/extern.c | 5 + remux/extern.h | 5 +- server/Makefile | 82 +++++++++++++ server/connection.c | 221 +++++++++++++++++++++++++---------- server/connection.h | 31 ++++- server/connectionHTTP.c | 9 +- server/connectionHTTP.h | 19 +-- server/connectionIGMP.c | 8 +- server/connectionVTP.c | 52 +++++++-- server/connectionVTP.h | 6 + server/livestreamer.c | 60 +++++----- server/livestreamer.h | 6 +- server/menuHTTP.c | 23 ++-- server/menuHTTP.h | 12 +- server/po/de_DE.po | 83 +++++++++++++ server/po/fi_FI.po | 83 +++++++++++++ server/po/fr_FR.po | 83 +++++++++++++ server/po/it_IT.po | 85 ++++++++++++++ server/po/lt_LT.po | 83 +++++++++++++ server/po/ru_RU.po | 83 +++++++++++++ server/po/sk_SK.po | 85 ++++++++++++++ server/setup.c | 29 +++-- server/setup.h | 4 +- server/streamdev-server.c | 143 +++++++++++++++++++++++ server/streamdev-server.h | 33 ++++++ server/streamer.c | 11 +- server/streamer.h | 8 +- streamdev-client.c | 55 --------- streamdev-client.h | 28 ----- streamdev-server.c | 143 ----------------------- streamdev-server.h | 33 ------ streamdev-server/externremux.sh | 84 ++++++++++--- streamdev-server/streamdevhosts.conf | 14 +++ streamdev/externremux.sh | 48 -------- streamdev/streamdevhosts.conf | 14 --- tools/Makefile | 34 ++++++ 65 files changed, 2219 insertions(+), 1475 deletions(-) create mode 100644 client/Makefile create mode 100644 client/po/de_DE.po create mode 100644 client/po/fi_FI.po create mode 100644 client/po/fr_FR.po create mode 100644 client/po/it_IT.po create mode 100644 client/po/lt_LT.po create mode 100644 client/po/ru_RU.po create mode 100644 client/po/sk_SK.po create mode 100644 client/streamdev-client.c create mode 100644 client/streamdev-client.h delete mode 100644 po/de_DE.po delete mode 100644 po/fi_FI.po delete mode 100644 po/fr_FR.po delete mode 100755 po/it_IT.po delete mode 100644 po/lt_LT.po delete mode 100644 po/ru_RU.po delete mode 100644 po/sk_SK.po create mode 100644 remux/Makefile create mode 100644 server/Makefile create mode 100644 server/po/de_DE.po create mode 100644 server/po/fi_FI.po create mode 100644 server/po/fr_FR.po create mode 100644 server/po/it_IT.po create mode 100644 server/po/lt_LT.po create mode 100644 server/po/ru_RU.po create mode 100644 server/po/sk_SK.po create mode 100644 server/streamdev-server.c create mode 100644 server/streamdev-server.h delete mode 100644 streamdev-client.c delete mode 100644 streamdev-client.h delete mode 100644 streamdev-server.c delete mode 100644 streamdev-server.h create mode 100644 streamdev-server/streamdevhosts.conf delete mode 100755 streamdev/externremux.sh delete mode 100644 streamdev/streamdevhosts.conf create mode 100644 tools/Makefile diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 0e2a2f5..7dc9960 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -38,6 +38,7 @@ Rolf Ahrenberg for suggesting to include the charset in HTTP replies for requesting replacement of asprintf calls for suggesting to change the URL path from EXTERN to EXT + for suggesting increased thread priorities for cStreamdevWriter/Streamer Rantanen Teemu for providing vdr-incompletesections.diff @@ -160,6 +161,13 @@ Norman Thiel vel_tins for reporting that externremux x264 uses value of ABR for VBR + for various suggestions to improve externremux.sh Matthias Prill for reporting a compiler error with older libstdc++ versions + +Timothy D. Lenz + for reporting missing support for invisible channel groups in HTTP menu + +Rainer Blickle + for reporting that channel switches may interrupt live TV on the server diff --git a/HISTORY b/HISTORY index 1002dd7..9cdc58d 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,40 @@ VDR Plugin 'streamdev' Revision History --------------------------------------- +- VTP no longer uses a static priority value for its server-side receivers. + The server stores channel and priority requested with the PROV command and + re-uses these values in a subsequent TUNE for the same channel. The new + PRIO command is used to update the receiver's priority if necessary. +- added parameter HEIGHT to externremux.sh +- fixed syslog messages reporting local instead of remote IP and port +- fixed regression of the GetDevice(...) change. Filter streaming to clients + with a recent VDR version no longer worked. +- log an error if externremux.sh is missing or not executable +- since VDR 1.5.0 cDevice::GetDevice(...) is no longer a query only method. + It detaches all receivers of the device it returns. So it is no longer + suitable for testing the availability of a device. Added a copy of VDR's + cDevice::GetDevice(...) without the detach receivers part as a workaround + until a better solution is available +- added dsyslog messages to help troubleshouting channel switch issues +- VTP command SUSP didn't attach the player to the primary device +- fixed incompatibilities with older make versions +- replacing a connections receiver is now an atomic operation. Solves + stuttering audio/video due to lost TS packets when adding/removing PIDs +- disabled attribute warn_unused_result in libdvbmpeg +- slightly increased thread priorities of cStreamdevWriter/Streamer + (suggested by Rolf Ahrenberg) +- fixed missing support for invisible channel groups (groups without name) + in HTTP menu (reported by Timothy D. Lenz) +- don't quote actual program call in externremux.sh, so you can run the + program through e.g. nice or taskset just by extending the variable + which holds the program name +- in externremux.sh each mencoder audio and video codec has a dedicated + variable for a default option string now. Still you can override each + default option with an URL parameter +- externremux.sh mencoder now uses scale parameter with negative height + instead of -xy for scaling (suggested by vel_tins@vdrportal) +- added FPS (frames per second) parameter to externremux.sh (suggested by + vel_tins@vdrportal) - don't use std::map.at(). It's not available in older libstdc++ version (reported by Matthias Prill) - fixed extremux x264 using value of ABR for VBR (thanks to vel_tins@vdrportal) diff --git a/Makefile b/Makefile index 7b362ba..b375844 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,23 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile,v 1.21 2010/06/04 18:32:34 schmirl Exp $ +# $Id: Makefile,v 1.23 2010/08/02 10:36:59 schmirl Exp $ -# The official name of this plugin. -# This name will be used in the '-P...' option of VDR to load the plugin. -# By default the main source file also carries this name. +# The main source file name. # PLUGIN = streamdev -### The version number of this plugin (taken from the main source file): - -VERSION = $(shell grep 'const char \*VERSION *=' common.c | awk '{ print $$5 }' | sed -e 's/[";]//g') +### The C/C++ compiler and options: -### The C++ compiler and options: +CC ?= gcc +CFLAGS ?= -g -O2 -Wall CXX ?= g++ -CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses +CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses + +### The version number of this plugin (taken from the main source file): + +VERSION = $(shell grep 'const char \*VERSION *=' common.c | awk '{ print $$5 }' | sed -e 's/[";]//g') ### The directory environment: @@ -24,119 +25,72 @@ VDRDIR = ../../.. LIBDIR = ../../lib TMPDIR = /tmp -### Allow user defined options to overwrite defaults: - --include $(VDRDIR)/Make.config - ### The version number of VDR (taken from VDR's "config.h"): APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') APIVERSNUM = $(shell grep 'define APIVERSNUM ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') TSPLAYVERSNUM = $(shell grep 'define TSPLAY_PATCH_VERSION ' $(VDRDIR)/device.h | awk '{ print $$3 }') -### The name of the distribution archive: - -ARCHIVE = $(PLUGIN)-$(VERSION) -PACKAGE = vdr-$(ARCHIVE) - -### Includes and Defines (add further entries here): - -INCLUDES += -I$(VDRDIR)/include -I. - -DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' +### Allow user defined options to overwrite defaults: +ifeq ($(shell test $(APIVERSNUM) -ge 10713; echo $$?),0) +include $(VDRDIR)/Make.global +else ifeq ($(shell test $(APIVERSNUM) -ge 10704 -o -n "$(TSPLAYVERSNUM)" ; echo $$?),0) - DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE +DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE +CFLAGS += -fPIC +CXXFLAGS += -fPIC +else +CFLAGS += -fPIC +CXXFLAGS += -fPIC endif - -### The object files (add further files here): - -COMMONOBJS = common.o \ - \ - tools/source.o tools/select.o tools/socket.o tools/tools.o - -CLIENTOBJS = $(PLUGIN)-client.o \ - \ - client/socket.o client/device.o client/setup.o \ - client/filter.o - - -SERVEROBJS = $(PLUGIN)-server.o \ - \ - server/server.o server/component.o server/connection.o \ - server/componentVTP.o server/componentHTTP.o server/componentIGMP.o \ - server/connectionVTP.o server/connectionHTTP.o server/connectionIGMP.o \ - server/streamer.o server/livestreamer.o server/livefilter.o \ - server/suspend.o server/setup.o server/menuHTTP.o server/recplayer.o \ - remux/tsremux.o remux/ts2pes.o remux/ts2ps.o remux/ts2es.o remux/extern.o - -ifdef DEBUG - DEFINES += -DDEBUG endif -### The main target: - -.PHONY: all i18n dist clean -all: libvdr-$(PLUGIN)-client.so libvdr-$(PLUGIN)-server.so i18n - -### Implicit rules: - -%.o: %.c - $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< +-include $(VDRDIR)/Make.config -# Dependencies: +### export all vars for sub-makes, using absolute paths -MAKEDEP = $(CXX) -MM -MG -DEPFILE = .dependencies -ifdef GCC3 -$(DEPFILE): Makefile - @rm -f $@ - @for i in $(CLIENTOBJS:%.o=%.c) $(SERVEROBJS:%.o=%.c) $(COMMONOBJS:%.o=%.c) ; do \ - $(MAKEDEP) $(DEFINES) $(INCLUDES) -MT "`dirname $$i`/`basename $$i .c`.o" $$i >>$@ ; \ - done -else -$(DEPFILE): Makefile - @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(CLIENTOBJS:%.o=%.c) $(SERVEROBJS:%.o=%.c) \ - $(COMMONOBJS:%.o=%.c) > $@ -endif +VDRDIR := $(shell cd $(VDRDIR) >/dev/null 2>&1 && pwd) +LIBDIR := $(shell cd $(LIBDIR) >/dev/null 2>&1 && pwd) +export +unexport PLUGIN --include $(DEPFILE) +### The name of the distribution archive: -### Internationalization (I18N): +ARCHIVE = $(PLUGIN)-$(VERSION) +PACKAGE = vdr-$(ARCHIVE) -PODIR = po -LOCALEDIR = $(VDRDIR)/locale -I18Npo = $(wildcard $(PODIR)/*.po) -I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) -I18Npot = $(PODIR)/$(PLUGIN).pot +### Includes and Defines (add further entries here): -%.mo: %.po - msgfmt -c -o $@ $< +INCLUDES += -I$(VDRDIR)/include -I.. -$(I18Npot): $(CLIENTOBJS:%.o=%.c) $(SERVEROBJS:%.o=%.c) $(COMMONOBJS:%.o=%.c) - xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='' -o $@ $^ +DEFINES += -D_GNU_SOURCE -%.po: $(I18Npot) - msgmerge -U --no-wrap --no-location --backup=none -q $@ $< - @touch $@ +ifdef DEBUG +DEFINES += -DDEBUG +endif +ifdef STREAMDEV_DEBUG +DEFINES += -DDEBUG +endif -$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo - @mkdir -p $(dir $@) - cp $< $@ +### The main target: -i18n: $(I18Nmsgs) +.PHONY: all client server dist clean +all: client server ### Targets: -libdvbmpeg/libdvbmpegtools.a: libdvbmpeg/*.c libdvbmpeg/*.h - $(MAKE) -C ./libdvbmpeg libdvbmpegtools.a - -libvdr-$(PLUGIN)-client.so: $(CLIENTOBJS) $(COMMONOBJS) libdvbmpeg/libdvbmpegtools.a -libvdr-$(PLUGIN)-server.so: $(SERVEROBJS) $(COMMONOBJS) libdvbmpeg/libdvbmpegtools.a +client: + $(MAKE) -C ./tools + $(MAKE) -C ./client + # installs to $(LIBDIR)/libvdr-streamdev-client.so.$(APIVERSION) -%.so: - $(CXX) $(CXXFLAGS) -shared $^ -o $@ - @cp $@ $(LIBDIR)/$@.$(APIVERSION) +server: + $(MAKE) -C ./tools + $(MAKE) -C ./libdvbmpeg + $(MAKE) -C ./remux + $(MAKE) -C ./server + # installs to $(LIBDIR)/libvdr-streamdev-server.so.$(APIVERSION) dist: clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @@ -147,5 +101,8 @@ dist: clean @echo Distribution package created as $(PACKAGE).tgz clean: - @-rm -f $(COMMONOBJS) $(CLIENTOBJS) $(SERVEROBJS) $(DEPFILE) $(PODIR)/*.mo $(PODIR)/*.pot *.so *.tgz core* *~ + $(MAKE) -C ./tools clean $(MAKE) -C ./libdvbmpeg clean + $(MAKE) -C ./remux clean + $(MAKE) -C ./client clean + $(MAKE) -C ./server clean diff --git a/README b/README index ce95d63..e1597f5 100644 --- a/README +++ b/README @@ -15,9 +15,9 @@ Contents: 1. Description 2. Installation -2.1 VDR 1.4.x and older -2.2 VDR 1.6.0 and above -2.3 Updating from streamdev 0.3.x +2.1 Compatibility +2.2 Compiling +2.3 Updating 3. Usage 3.1 Usage HTTP server 3.2 Usage IGMP multicast server @@ -27,7 +27,8 @@ Contents: 4.1 Plugins for VDR-to-VDR clients 4.2 Plugins for Server 4.3 Alternatives -5. Known Problems +5. externremux.sh +6. Known Problems 1. Description: @@ -62,7 +63,7 @@ the PROTOCOL file. 2. Installation: ---------------- -Let's say streamdev's version is 0.4.0 and vdr's version is 1.X.X. If you +Let's say streamdev's version is 0.5.0 and vdr's version is 1.X.X. If you use anything else please exchange the version numbers appropriately (this way I don't have to update this section all the times;) ). @@ -79,54 +80,71 @@ If you want to drive additional Input-Devices (with different sources) on the client, you can merge the channels.conf files. VDR will detect if the local device or the network device can receive the channels. -Last, but not least you have to copy the streamdev folder into the -"plugins/streamdev" subfolder of VDR's config-directory (which is equal to your -video-directory if not specified otherwise). For example, if you didn't specify -a separate config-directory, and specified your video directory as "/video0", -the directory has to be copied to /video0/plugins/streamdev. +Last, but not least you have to copy the streamdev-server folder into the +"plugins/streamdev-server" subfolder of VDR's config-directory (which is equal +to your video-directory if not specified otherwise). For example, if you didn't +specify a separate config-directory, and set your video directory to "/video0", +the directory has to be copied to /video0/plugins/streamdev-server. The directory contains a file named streamdevhosts.conf which you must adjust to your needs. The syntax is the same as for svdrphosts.conf, so please consult VDR's documentation on how to fill that file, if you can't do it on-the-fly. There's also a sample externremux.sh script in this directory. It is used by -streamdev's external remux feature. The sample script uses mencoder. Please -check the script for further information. You can specify a different script -location with the -r parameter. The VDR commandline would then include a +streamdev's external remux feature. The sample script uses mencoder by default. +Please check the script for further information. You can specify a different +script location with the -r parameter. The VDR commandline would then include a "-P 'streamdev-server -r /usr/local/bin/remux.sh'". Note the additional quotes, as otherwise -r will be passed to VDR and not to streamdev. -2.1 VDR 1.4.x and older: ------------------------- +2.1 Compatibility: +------------------ This version is not compatible to VDR releases older than 1.5.9. Take one of the streamdev-0.4.x releases if you are running at least VDR 1.4.x. For older VDRs you will probably need one of the streamdev-0.3.x releases. -2.2 VDR 1.6.0 and above: ------------------------- +2.2 Compiling: +-------------- + + cd vdr-1.X.X/PLUGINS/src + tar xvfz vdr-streamdev-0.5.0.tgz + ln -s streamdev-0.5.0 streamdev + cp -r streamdev/streamdev-server VDRCONFDIR/plugins/ + cd ../.. + make [options, if necessary] vdr + make [options, if necessary] plugins + +To build only the plugin, change into the streamdev source folder and issue + make -cd vdr-1.X.X/PLUGINS/src -tar xvfz vdr-streamdev-0.4.0.tgz -ln -s streamdev-0.4.0 streamdev -cp -r streamdev/streamdev VDRCONFDIR/plugins/ -cd ../.. -make [options, if necessary] vdr -make [options, if necessary] plugins +To build only streamdev-server or only streamdev-client, use + make server + make client -2.3 Updating from streamdev 0.3.x ----------------------------------- +2.3 Updating: +-------------- -Starting with streamdev 0.4.0, all additional files are kept in a directory -called "streamdev" inside VDR's plugin config directory. It is the new default -location of externremux.sh and the new place where streamdev-server expects the -file "streamdevhosts.conf". You will have to move this file to its new location: +If you are updating streamdev from an earlier release, you might have to +perform some additional steps. Check which version you've been running before, +then read below for the necessary changes. -mv VDRCONFDIR/plugins/streamdevhosts.conf VDRCONFDIR/plugins/streamdev/ +* Location of files: +-------------------- +(Affected: 0.3.x, 0.4.x, 0.4.0pre, 0.5.0pre) -(Directory VDRCONFDIR/plugins/streamdev already exists, as you copied the -whole folder from the sources directory as suggested above, right?) +Starting with streamdev 0.5.0, all additional files are kept in a directory +called "streamdev-server" inside VDR's plugin config directory. It is the new +default location of externremux.sh and the new place where streamdev-server +expects the file "streamdevhosts.conf". You will have to move this file to its +new location: + +streamdev 0.3.x: + mv VDRCONFDIR/plugins/streamdevhosts.conf VDRCONFDIR/plugins/streamdev-server/ + +streamdev 0.4.x, 0.4.0pre and 0.5.0pre: + mv VDRCONFDIR/plugins/streamdev VDRCONFDIR/plugins/streamdev-server/ Now check the contents of streamdevhosts.conf. Does it contain a "0.0.0.0/0" entry? If your VDR machine is connected to the Internet, this line gives @@ -134,6 +152,21 @@ entry? If your VDR machine is connected to the Internet, this line gives prevent this (e.g. firewall). You might want to remove this line and enable HTTP authentication instead. +* Handling of externremux script: +--------------------------------- +(Affected: 0.3.x, 0.4.0pre, 0.5.0pre) + +Streamdev server's externremux script became responsible for emitting all HTTP +headers. A quick and dirty extension to your current script would be: + + echo -ne 'Content-type: video/mpeg\r\n' + echo -ne '\r\n' + +However I encourage you to try the new externremux.sh script shipped with the +streamdev source distribution. + +To emphasize the required change in externremux, the URL path for passing the +stream through externremux has changed from EXTERN to EXT. 3. Usage: --------- @@ -172,15 +205,15 @@ listen to with the parameter "HTTP Server Port". The parameter "HTTP Streamtype" allows you to specify a default stream type, which is used if no specific type has been requested in the URL (see below). The supported stream types are: -TS Transport Stream (i.e. a dump from the device) -PES Packetized Elemetary Stream (VDR's native recording format) -PS Program Stream (SVCD, DVD like stream) -ES Elementary Stream (only Video, if available, otherwise only Audio) -EXTERN Pass stream through external script (e.g. for converting with mencoder) + TS Transport Stream (i.e. a dump from the device) + PES Packetized Elemetary Stream (VDR's native recording format) + PS Program Stream (SVCD, DVD like stream) + ES Elementary Stream (only Video, if available, otherwise only Audio) + EXT Pass stream through external script (e.g. for converting with mencoder) Assuming that you leave the default port (3000), point your web browser to -http://hostname:3000/ + http://hostname:3000/ You will be presented a menu with links to various channel lists, including M3U playlist formats. @@ -188,27 +221,28 @@ playlist formats. If you don't want to use the HTML menu or the M3U playlists, you can access the streams directly like this: -http://hostname:3000/3 -http://hostname:3000/S19.2E-0-12480-898 + http://hostname:3000/3 + http://hostname:3000/S19.2E-0-12480-898 The first one will deliver a channel by number on the server, the second one will request the channel by unique channel id. In addition, you can specify the desired stream type as a path to the channel. -http://hostname:3000/TS/3 -http://hostname:3000/PES/S19.2E-0-12480-898 + http://hostname:3000/TS/3 + http://hostname:3000/PES/S19.2E-0-12480-898 The first one would deliver the stream in TS, the second one in PES format. -Possible values are 'PES', 'TS', 'PS', 'ES' and 'EXTERN'. You need to specify +Possible values are 'PES', 'TS', 'PS', 'ES' and 'EXT'. You need to specify the ES format explicitly if you want to listen to radio channels. Play them back i.e. with mpg123. -mpg123 http://hostname:3000/ES/200 - -With 'EXTERN' you can also add a parameter which is passed as argument to the -externremux script. + mpg123 http://hostname:3000/ES/200 -http://hostname:3000/EXTERN;some_parameter/3 +With 'EXT' you can also add parameters which are passed as arguments to the +externremux script (e.g. http://hostname:3000/EXT;param1=value1;param2=value2/3) +Check your externremux.sh script for the parameters it understands. For details +on how to modify or write your own externremux.sh, please see the chapter upon +externremux.sh further down. If you want to access streamdev's HTTP server from the Internet, do *not* grant access for anyone by allowing any IP in "streamdevhosts.conf". Instead, pass the @@ -216,7 +250,7 @@ access for anyone by allowing any IP in "streamdevhosts.conf". Instead, pass the as argument. Clients with an IP not accepted by "streamdevhosts.conf" will then have to login. The VDR commandline will have to look like this: -vdr ... -P 'streamdev-server -a vdr:secret' ... + vdr ... -P 'streamdev-server -a vdr:secret' ... Note the single quotes, as otherwise "-a" will be passed to VDR and not to streamdev-server. The login ("vdr" in the example above) doesn't have to exist @@ -347,6 +381,21 @@ which streamdev will accept to tune. Setting the minimum priority to a higher value than the maximum, you will get two ranges: "up to maximum" and "minimum and above". +Note that streamdev-client acts similar to a DVB card. It is possible to receive +multiple channels simultaneously, but only from the same transponder. Just add +additional instances of streamdev-client and you will be able to receive as many +transponders at a time. The same trick allows a client to receive channels from +different servers. To create an additional instance, copy the streamdev-client +binary to a different name (e.g. streamdev-client2): + + cd VDRPLUGINLIBDIR + cp libvdr-streamdev-client.so.1.X.X libvdr-streamdev-client2.so.1.X.X + +Now add -Pstreamdev-client2 to the VDR commandline. In the VDR plugin setup +a second streamdev-client entry should show up. Both instances have to be +configured individually. + + 4. Other useful Plugins: ------------------------ @@ -389,7 +438,58 @@ With its networking option, xineliboutput provides an alternative to streamdev. You will get the picture of the server VDR, including its OSD. However you won't get independent clients, as they all share the same output. -5. Known Problems: +5. externremux.sh: +------------------ + +When selecting streamtype "EXT", the TS stream from VDR is passed through an +external program for further processing. By default a script installed at +VDRCONFDIR/plugins/streamdev/externremux.sh is expected, however you may +specify a different location as parameter -r to the streamdev-server plugin +(see chapter upon Installation above). + +The TS stream is passed to the script on stdin, the resulting stream is expected +on stdout. The following parameters are passed to the script in the environment: + +* Information on the channel: + REMUX_CHANNEL_ID VDR channel ID + REMUX_CHANNEL_NAME Channel name + REMUX_VTYPE Video type (2 for MPEG-2) + REMUX_VPID Video PID (undefined if audio only) + REMUX_PPID PCR PID (undefined if equal to VPID) + REMUX_TPID Teletext PID (undefined if not available) + REMUX_APID Space separated list of audio pids + REMUX_ALANG Space separated list of audio languages + REMUX_DPID Space separated list of dolby pids + REMUX_DLANG Space separated list of dolby languages + REMUX_SPID Space separated list of subtitle pids + REMUX_SLANG Space separated list of subtitle languages + REMUX_PARAM_* All (user supplied) parameters (e.g. REMUX_PARAM_x) + +* Information on the connection (CGI like) + REMOTE_ADDR Client IP + SERVER_NAME Local IP + SERVER_PORT Local port + SERVER_PROTOCOL Streamdev protocol (HTTP, VTP, IGMP) + SERVER_SOFTWARE Streamdev version + All HTTP headers converted to uppercase, '-' replaced by '_' (e.g. USER_AGENT) + +The script should perform the following steps (pseudocode): + + if (SERVER_PROTOCOL == HTTP) + write headers (including Content-Type) to STDOUT + write empty line to STDOUT + if (REQUEST_METHOD == HEAD) + exit + endif + endif + while (read STDIN) + remux to STDOUT + wend + + onSIGINT/SIGKILL: cleanup and exit + + +6. Known Problems: ------------------ * In VDR-to-VDR setup, the availability of a channel is checked with a different @@ -417,7 +517,7 @@ hexadecimal values if you are using an editor to modify your channels.conf 2. Apply either patch "patches/vdr-1.6.0-intcamdevices.patch" or patch "patches/vdr-1.6.0-ignore_missing_cam.diff" to your client VDR. Intcamdevices -is the clean solution. But as it modifies the VDR API, so you will need to +is the clean solution, but it modifies the VDR API. So you will need to recompile all of your plugins. The ignore_missing_cam patch is trivial, no need to recompile other plugins. However it is not suitable for clients with a DVB card of their own. diff --git a/client/Makefile b/client/Makefile new file mode 100644 index 0000000..ecc4787 --- /dev/null +++ b/client/Makefile @@ -0,0 +1,84 @@ +# +# Makefile for a Video Disk Recorder plugin +# +# $Id: Makefile,v 1.2 2010/07/19 13:49:25 schmirl Exp $ + +# The official name of this plugin. +# This name will be used in the '-P...' option of VDR to load the plugin. +# By default the main source file also carries this name. +# +PLUGIN = streamdev-client + +### Includes and Defines (add further entries here): + +DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' + +### The object files (add further files here): + +COMMONOBJS = ../common.o + +CLIENTOBJS = $(PLUGIN).o \ + device.o filter.o setup.o socket.o + +### The main target: + +.PHONY: all i18n dist clean +all: libvdr-$(PLUGIN).so i18n + +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< + +### Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies + +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(CLIENTOBJS:%.o=%.c) $(COMMONOBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Internationalization (I18N): + +PODIR = po +LOCALEDIR = $(VDRDIR)/locale +I18Npo = $(wildcard $(PODIR)/*.po) +I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) +I18Npot = $(PODIR)/$(PLUGIN).pot + +%.mo: %.po + msgfmt -c -o $@ $< + +$(I18Npot): $(CLIENTOBJS:%.o=%.c) + xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='' -o $@ $^ + +%.po: $(I18Npot) + msgmerge -U --no-wrap --no-location --backup=none -q $@ $< + @touch $@ + +$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo + @mkdir -p $(dir $@) + cp $< $@ + +i18n: $(I18Nmsgs) + +### Targets: + +libvdr-$(PLUGIN).so: $(CLIENTOBJS) $(COMMONOBJS) ../tools/sockettools.a + +%.so: + $(CXX) $(CXXFLAGS) -shared $^ -o $@ + @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) + +dist: clean + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @mkdir $(TMPDIR)/$(ARCHIVE) + @cp -a * $(TMPDIR)/$(ARCHIVE) + @tar czf $(PACKAGE).tgz --exclude CVS -C $(TMPDIR) $(ARCHIVE) + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @echo Distribution package created as $(PACKAGE).tgz + +clean: + @-rm -f $(COMMONOBJS) $(CLIENTOBJS) $(DEPFILE) $(PODIR)/*.mo $(PODIR)/*.pot *.so *.tgz core* *~ diff --git a/client/device.c b/client/device.c index d53bde1..fb80107 100644 --- a/client/device.c +++ b/client/device.c @@ -1,5 +1,5 @@ /* - * $Id: device.c,v 1.26 2010/06/08 05:55:17 schmirl Exp $ + * $Id: device.c,v 1.27 2010/08/18 10:26:55 schmirl Exp $ */ #include "client/device.h" @@ -8,6 +8,7 @@ #include "tools/select.h" +#include #include #include #include @@ -32,6 +33,7 @@ cStreamdevDevice::cStreamdevDevice(void) { m_Device = this; m_Pids = 0; + m_Priority = -1; m_DvrClosed = true; } @@ -107,7 +109,7 @@ bool cStreamdevDevice::ProvidesChannel(const cChannel *Channel, int Priority, res = prio && ClientSocket.ProvidesChannel(Channel, Priority); ndr = true; } - + if (NeedsDetachReceivers) *NeedsDetachReceivers = ndr; Dprintf("prov res = %d, ndr = %d\n", res, ndr); @@ -118,6 +120,9 @@ bool cStreamdevDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { Dprintf("SetChannelDevice Channel: %s, LiveView: %s\n", Channel->Name(), LiveView ? "true" : "false"); + LOCK_THREAD; + + m_UpdatePriority = ClientSocket.SupportsPrio(); if (LiveView) return false; @@ -140,6 +145,8 @@ bool cStreamdevDevice::SetPid(cPidHandle *Handle, int Type, bool On) { Handle->used); LOCK_THREAD; + m_UpdatePriority = ClientSocket.SupportsPrio(); + if (On && !m_TSBuffer) { Dprintf("SetPid: no data connection -> OpenDvr()"); OpenDvrInt(); @@ -301,3 +308,16 @@ bool cStreamdevDevice::ReInit(void) { return StreamdevClientSetup.StartClient ? Init() : true; } +void cStreamdevDevice::UpdatePriority(void) { + if (m_Device) { + m_Device->Lock(); + if (m_Device->m_UpdatePriority && ClientSocket.DataSocket(siLive)) { + int Priority = m_Device->Priority(); + if (m_Device == cDevice::ActualDevice() && Priority < Setup.PrimaryLimit) + Priority = Setup.PrimaryLimit; + if (m_Device->m_Priority != Priority && ClientSocket.SetPriority(Priority)) + m_Device->m_Priority = Priority; + } + m_Device->Unlock(); + } +} diff --git a/client/device.h b/client/device.h index e96b05f..b2eed70 100644 --- a/client/device.h +++ b/client/device.h @@ -1,5 +1,5 @@ /* - * $Id: device.h,v 1.9 2009/06/23 10:26:54 schmirl Exp $ + * $Id: device.h,v 1.10 2010/08/18 10:26:55 schmirl Exp $ */ #ifndef VDR_STREAMDEV_DEVICE_H @@ -15,13 +15,14 @@ class cTBString; #define CMD_LOCK_OBJ(x) cMutexLock CmdLock((cMutex*)&(x)->m_Mutex) class cStreamdevDevice: public cDevice { - friend class cRemoteRecordings; private: const cChannel *m_Channel; cTSBuffer *m_TSBuffer; cStreamdevFilters *m_Filters; int m_Pids; + int m_Priority; + bool m_UpdatePriority; bool m_DvrClosed; static cStreamdevDevice *m_Device; @@ -59,6 +60,7 @@ public: #endif virtual bool IsTunedToTransponder(const cChannel *Channel); + static void UpdatePriority(void); static bool Init(void); static bool ReInit(void); diff --git a/client/po/de_DE.po b/client/po/de_DE.po new file mode 100644 index 0000000..1e481a2 --- /dev/null +++ b/client/po/de_DE.po @@ -0,0 +1,50 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Frank Schmirler , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:05+0200\n" +"PO-Revision-Date: 2008-03-30 02:11+0200\n" +"Last-Translator: Frank Schmirler \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VTP Streaming Client" +msgstr "VTP Streaming Client" + +msgid "Suspend Server" +msgstr "Server pausieren" + +msgid "Server is suspended" +msgstr "Server ist pausiert" + +msgid "Couldn't suspend Server!" +msgstr "Konnte Server nicht pausieren!" + +msgid "Hide Mainmenu Entry" +msgstr "Hauptmeneintrag verstecken" + +msgid "Start Client" +msgstr "Client starten" + +msgid "Remote IP" +msgstr "IP der Gegenseite" + +msgid "Remote Port" +msgstr "Port der Gegenseite" + +msgid "Filter Streaming" +msgstr "Filter-Daten streamen" + +msgid "Minimum Priority" +msgstr "Minimale Prioritt" + +msgid "Maximum Priority" +msgstr "Maximale Prioritt" + diff --git a/client/po/fi_FI.po b/client/po/fi_FI.po new file mode 100644 index 0000000..2091680 --- /dev/null +++ b/client/po/fi_FI.po @@ -0,0 +1,50 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Rolf Ahrenberg , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:05+0200\n" +"PO-Revision-Date: 2008-03-30 02:11+0200\n" +"Last-Translator: Rolf Ahrenberg \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VTP Streaming Client" +msgstr "VTP-suoratoistoasiakas" + +msgid "Suspend Server" +msgstr "Pysyt palvelin" + +msgid "Server is suspended" +msgstr "Palvelin on pysytetty" + +msgid "Couldn't suspend Server!" +msgstr "Palvelinta ei onnistuttu pysyttmn!" + +msgid "Hide Mainmenu Entry" +msgstr "Piilota valinta pvalikosta" + +msgid "Start Client" +msgstr "Kynnist VDR-asiakas" + +msgid "Remote IP" +msgstr "Etkoneen IP-osoite" + +msgid "Remote Port" +msgstr "Etkoneen portti" + +msgid "Filter Streaming" +msgstr "Suodatetun tiedon suoratoisto" + +msgid "Minimum Priority" +msgstr "Pienin prioriteetti" + +msgid "Maximum Priority" +msgstr "Suurin prioriteetti" + diff --git a/client/po/fr_FR.po b/client/po/fr_FR.po new file mode 100644 index 0000000..5c3e756 --- /dev/null +++ b/client/po/fr_FR.po @@ -0,0 +1,50 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Frank Schmirler , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:05+0200\n" +"PO-Revision-Date: 2008-03-30 02:11+0200\n" +"Last-Translator: micky979 \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VTP Streaming Client" +msgstr "Client de streaming VTP" + +msgid "Suspend Server" +msgstr "Suspendre le serveur" + +msgid "Server is suspended" +msgstr "Le serveur est suspendu" + +msgid "Couldn't suspend Server!" +msgstr "Impossible de suspendre le serveur!" + +msgid "Hide Mainmenu Entry" +msgstr "Masquer dans le menu principal" + +msgid "Start Client" +msgstr "Dmarrage du client" + +msgid "Remote IP" +msgstr "Adresse IP du serveur" + +msgid "Remote Port" +msgstr "Port du serveur" + +msgid "Filter Streaming" +msgstr "Filtre streaming" + +msgid "Minimum Priority" +msgstr "" + +msgid "Maximum Priority" +msgstr "" + diff --git a/client/po/it_IT.po b/client/po/it_IT.po new file mode 100644 index 0000000..f7268e0 --- /dev/null +++ b/client/po/it_IT.po @@ -0,0 +1,52 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Alberto Carraro , 2001 +# Antonio Ospite , 2003 +# Sean Carlos , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:05+0200\n" +"PO-Revision-Date: 2010-06-19 03:58+0100\n" +"Last-Translator: Diego Pierotto \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VTP Streaming Client" +msgstr "Client trasmissione VTP" + +msgid "Suspend Server" +msgstr "Sospendi Server" + +msgid "Server is suspended" +msgstr "Server sospeso" + +msgid "Couldn't suspend Server!" +msgstr "Impossibile sospendere il server!" + +msgid "Hide Mainmenu Entry" +msgstr "Nascondi voce menu principale" + +msgid "Start Client" +msgstr "Avvia Client" + +msgid "Remote IP" +msgstr "Indirizzo IP del Server" + +msgid "Remote Port" +msgstr "Porta Server Remoto" + +msgid "Filter Streaming" +msgstr "Filtra trasmissione" + +msgid "Minimum Priority" +msgstr "Priorit minima" + +msgid "Maximum Priority" +msgstr "Priorit massima" + diff --git a/client/po/lt_LT.po b/client/po/lt_LT.po new file mode 100644 index 0000000..f6a7d5c --- /dev/null +++ b/client/po/lt_LT.po @@ -0,0 +1,50 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Frank Schmirler , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:05+0200\n" +"PO-Revision-Date: 2009-11-26 21:57+0200\n" +"Last-Translator: Valdemaras Pipiras \n" +"Language-Team: Lietuvių\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VTP Streaming Client" +msgstr "VTP transliavimo standartas" + +msgid "Suspend Server" +msgstr "Sustabdyti serverį" + +msgid "Server is suspended" +msgstr "Serveris sustabdytas" + +msgid "Couldn't suspend Server!" +msgstr "Negali sustabdyti serverio!" + +msgid "Hide Mainmenu Entry" +msgstr "Paslėpti pagrindinio meniu įrašą" + +msgid "Start Client" +msgstr "Paleisti klientą" + +msgid "Remote IP" +msgstr "Nuotolinis IP adresas" + +msgid "Remote Port" +msgstr "Nuotolinis portas" + +msgid "Filter Streaming" +msgstr "Filtruoti transliavimą" + +msgid "Minimum Priority" +msgstr "Minimalus prioritetas" + +msgid "Maximum Priority" +msgstr "Maksimalus prioritetas" + diff --git a/client/po/ru_RU.po b/client/po/ru_RU.po new file mode 100644 index 0000000..c09d3f1 --- /dev/null +++ b/client/po/ru_RU.po @@ -0,0 +1,50 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Frank Schmirler , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:05+0200\n" +"PO-Revision-Date: 2008-06-26 15:36+0100\n" +"Last-Translator: Oleg Roitburd \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-5\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VTP Streaming Client" +msgstr "VTP Streaming " + +msgid "Suspend Server" +msgstr " " + +msgid "Server is suspended" +msgstr " " + +msgid "Couldn't suspend Server!" +msgstr " " + +msgid "Hide Mainmenu Entry" +msgstr " " + +msgid "Start Client" +msgstr " " + +msgid "Remote IP" +msgstr " IP" + +msgid "Remote Port" +msgstr " " + +msgid "Filter Streaming" +msgstr " " + +msgid "Minimum Priority" +msgstr "" + +msgid "Maximum Priority" +msgstr "" + diff --git a/client/po/sk_SK.po b/client/po/sk_SK.po new file mode 100644 index 0000000..e3dbf6b --- /dev/null +++ b/client/po/sk_SK.po @@ -0,0 +1,52 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2009 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Milan Hrala , 2009 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev_SK\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:05+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: Milan Hrala \n" +"Language-Team: Slovak \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-2\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Slovak\n" +"X-Poedit-Country: SLOVAKIA\n" + +msgid "VTP Streaming Client" +msgstr "VTP prdov klient" + +msgid "Suspend Server" +msgstr "Server pozastaven" + +msgid "Server is suspended" +msgstr "Server je doasne preruen" + +msgid "Couldn't suspend Server!" +msgstr "Nepodarilo sa pozastavi Server!" + +msgid "Hide Mainmenu Entry" +msgstr "Schova poloku v hlavnom menu" + +msgid "Start Client" +msgstr "Spusti Klienta" + +msgid "Remote IP" +msgstr "Vzdialen IP" + +msgid "Remote Port" +msgstr "Vzdialen port" + +msgid "Filter Streaming" +msgstr "filtrova prdy" + +msgid "Minimum Priority" +msgstr "minimlna priorita" + +msgid "Maximum Priority" +msgstr "maximlna priorita" + diff --git a/client/socket.c b/client/socket.c index bd2f9ba..0e8974f 100644 --- a/client/socket.c +++ b/client/socket.c @@ -1,5 +1,5 @@ /* - * $Id: socket.c,v 1.13 2010/06/08 05:55:17 schmirl Exp $ + * $Id: socket.c,v 1.15 2010/08/18 10:26:55 schmirl Exp $ */ #include @@ -20,6 +20,7 @@ cClientSocket ClientSocket; cClientSocket::cClientSocket(void) { memset(m_DataSockets, 0, sizeof(cTBSocket*) * si_Count); + m_Prio = false; Reset(); } @@ -142,8 +143,14 @@ bool cClientSocket::CheckConnection(void) { if(Command("CAPS FILTERS", 220)) Filters = ",FILTERS"; - isyslog("Streamdev: Connected to server %s:%d using capabilities TSPIDS%s", - RemoteIp().c_str(), RemotePort(), Filters); + const char *Prio = ""; + if(Command("CAPS PRIO", 220)) { + Prio = ",PRIO"; + m_Prio = true; + } + + isyslog("Streamdev: Connected to server %s:%d using capabilities TSPIDS%s%s", + RemoteIp().c_str(), RemotePort(), Filters, Prio); return true; } @@ -241,7 +248,7 @@ bool cClientSocket::SetChannelDevice(const cChannel *Channel) { CMD_LOCK; std::string command = (std::string)"TUNE " - + (const char*)Channel->GetChannelID().ToString(); + + (const char*)Channel->GetChannelID().ToString(); if (!Command(command, 220)) { if (errno == 0) esyslog("ERROR: Streamdev: Couldn't tune %s:%d to channel %s", @@ -251,6 +258,21 @@ bool cClientSocket::SetChannelDevice(const cChannel *Channel) { return true; } +bool cClientSocket::SetPriority(int Priority) { + if (!CheckConnection()) return false; + + CMD_LOCK; + + std::string command = (std::string)"PRIO " + (const char*)itoa(Priority); + if (!Command(command, 220)) { + if (errno == 0) + esyslog("Streamdev: Failed to update priority on %s:%d", RemoteIp().c_str(), + RemotePort()); + return false; + } + return true; +} + bool cClientSocket::SetPid(int Pid, bool On) { if (!CheckConnection()) return false; @@ -259,8 +281,8 @@ bool cClientSocket::SetPid(int Pid, bool On) { std::string command = (std::string)(On ? "ADDP " : "DELP ") + (const char*)itoa(Pid); if (!Command(command, 220)) { if (errno == 0) - esyslog("Streamdev: Pid %d not available from %s:%d", Pid, LocalIp().c_str(), - LocalPort()); + esyslog("Streamdev: Pid %d not available from %s:%d", Pid, RemoteIp().c_str(), + RemotePort()); return false; } return true; @@ -276,7 +298,7 @@ bool cClientSocket::SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On) { if (!Command(command, 220)) { if (errno == 0) esyslog("Streamdev: Filter %hu, %hhu, %hhu not available from %s:%d", - Pid, Tid, Mask, LocalIp().c_str(), LocalPort()); + Pid, Tid, Mask, RemoteIp().c_str(), RemotePort()); return false; } return true; diff --git a/client/socket.h b/client/socket.h index 7ad9a80..1197678 100644 --- a/client/socket.h +++ b/client/socket.h @@ -1,5 +1,5 @@ /* - * $Id: socket.h,v 1.7 2010/06/08 05:55:17 schmirl Exp $ + * $Id: socket.h,v 1.8 2010/08/18 10:26:55 schmirl Exp $ */ #ifndef VDR_STREAMDEV_CLIENT_CONNECTION_H @@ -20,6 +20,7 @@ private: cTBSocket *m_DataSockets[si_Count]; cMutex m_Mutex; char m_Buffer[BUFSIZ + 1]; // various uses + bool m_Prio; // server supports command PRIO protected: /* Send Command, and return true if the command results in Expected. @@ -45,6 +46,8 @@ public: bool CreateDataConnection(eSocketId Id); bool CloseDataConnection(eSocketId Id); bool SetChannelDevice(const cChannel *Channel); + bool SupportsPrio() { return m_Prio; } + bool SetPriority(int Priority); bool SetPid(int Pid, bool On); bool SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On); bool CloseDvr(void); diff --git a/client/streamdev-client.c b/client/streamdev-client.c new file mode 100644 index 0000000..00fa90c --- /dev/null +++ b/client/streamdev-client.c @@ -0,0 +1,59 @@ +/* + * streamdev.c: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: streamdev-client.c,v 1.3 2010/08/18 10:26:56 schmirl Exp $ + */ + +#include "streamdev-client.h" +#include "client/device.h" +#include "client/setup.h" + +#if !defined(APIVERSNUM) || APIVERSNUM < 10509 +#error "VDR-1.5.9 API version or greater is required!" +#endif + +const char *cPluginStreamdevClient::DESCRIPTION = trNOOP("VTP Streaming Client"); + +cPluginStreamdevClient::cPluginStreamdevClient(void) { +} + +cPluginStreamdevClient::~cPluginStreamdevClient() { +} + +const char *cPluginStreamdevClient::Description(void) { + return tr(DESCRIPTION); +} + +bool cPluginStreamdevClient::Start(void) { + I18nRegister(PLUGIN_NAME_I18N); + cStreamdevDevice::Init(); + return true; +} + +const char *cPluginStreamdevClient::MainMenuEntry(void) { + return StreamdevClientSetup.StartClient && !StreamdevClientSetup.HideMenuEntry ? tr("Suspend Server") : NULL; +} + +cOsdObject *cPluginStreamdevClient::MainMenuAction(void) { + if (ClientSocket.SuspendServer()) + Skins.Message(mtInfo, tr("Server is suspended")); + else + Skins.Message(mtError, tr("Couldn't suspend Server!")); + return NULL; +} + +cMenuSetupPage *cPluginStreamdevClient::SetupMenu(void) { + return new cStreamdevClientMenuSetupPage; +} + +bool cPluginStreamdevClient::SetupParse(const char *Name, const char *Value) { + return StreamdevClientSetup.SetupParse(Name, Value); +} + +void cPluginStreamdevClient::MainThreadHook(void) { + cStreamdevDevice::UpdatePriority(); +} + +VDRPLUGINCREATOR(cPluginStreamdevClient); // Don't touch this! diff --git a/client/streamdev-client.h b/client/streamdev-client.h new file mode 100644 index 0000000..1885ed1 --- /dev/null +++ b/client/streamdev-client.h @@ -0,0 +1,29 @@ +/* + * $Id: streamdev-client.h,v 1.3 2010/08/18 10:26:56 schmirl Exp $ + */ + +#ifndef VDR_STREAMDEVCLIENT_H +#define VDR_STREAMDEVCLIENT_H + +#include "common.h" + +#include + +class cPluginStreamdevClient : public cPlugin { +private: + static const char *DESCRIPTION; + +public: + cPluginStreamdevClient(void); + virtual ~cPluginStreamdevClient(); + virtual const char *Version(void) { return VERSION; } + virtual const char *Description(void); + virtual bool Start(void); + virtual const char *MainMenuEntry(void); + virtual cOsdObject *MainMenuAction(void); + virtual cMenuSetupPage *SetupMenu(void); + virtual bool SetupParse(const char *Name, const char *Value); + virtual void MainThreadHook(void); +}; + +#endif // VDR_STREAMDEVCLIENT_H diff --git a/common.c b/common.c index 279e909..47898aa 100644 --- a/common.c +++ b/common.c @@ -1,5 +1,5 @@ /* - * $Id: common.c,v 1.11 2009/09/18 10:41:41 schmirl Exp $ + * $Id: common.c,v 1.12 2010/07/19 13:49:24 schmirl Exp $ */ #include @@ -10,7 +10,7 @@ using namespace std; -const char *VERSION = "0.5.0-pre"; +const char *VERSION = "0.5.0-CVS"; const char cMenuEditIpItem::IpCharacters[] = "0123456789."; diff --git a/common.h b/common.h index ef6ef9e..12025f5 100644 --- a/common.h +++ b/common.h @@ -1,5 +1,5 @@ /* - * $Id: common.h,v 1.15 2009/09/18 10:41:41 schmirl Exp $ + * $Id: common.h,v 1.16 2010/07/19 13:49:24 schmirl Exp $ */ #ifndef VDR_STREAMDEV_COMMON_H @@ -37,7 +37,7 @@ enum eStreamType { stPES, stPS, stES, - stExtern, + stEXT, stTSPIDS, st_Count }; diff --git a/libdvbmpeg/Makefile b/libdvbmpeg/Makefile index a586182..4a78a12 100644 --- a/libdvbmpeg/Makefile +++ b/libdvbmpeg/Makefile @@ -1,25 +1,38 @@ -INCS = -I. -CFLAGS = -g -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -fPIC -MFLAG = -M -OBJS = ctools.o ringbuffy.o remux.o transform.o -SRC = $(wildcard *.c) +# +# Makefile for a Video Disk Recorder plugin +# +# $Id: Makefile,v 1.5 2010/07/30 10:49:28 schmirl Exp $ -DESTDIR = /usr/local +### The object files (add further files here): -.PHONY: clean +OBJS = ctools.o remux.o ringbuffy.o transform.o -clean: - - rm -f *.o *~ *.a .depend +### Disable attribute warn_unused_result + +DEFINES += -U_FORTIFY_SOURCE +### The main target: + +.PHONY: clean libdvbmpegtools.a: $(OBJS) ar -rcs libdvbmpegtools.a $(OBJS) -%.o: %.c - $(CC) -c $(CFLAGS) $(INCS) $(DEFINES) $< +### Implicit rules: -.depend: - $(CXX) $(DEFINES) $(MFLAG) $(SRC) $(INCS)> .depend +%.o: %.c + $(CC) $(CFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< +### Dependencies: +MAKEDEP = $(CC) -MM -MG +DEPFILE = .dependencies --include .depend +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Targets: + +clean: + @-rm -f $(OBJS) $(DEPFILE) *.a core* *~ diff --git a/po/de_DE.po b/po/de_DE.po deleted file mode 100644 index 1ee072f..0000000 --- a/po/de_DE.po +++ /dev/null @@ -1,115 +0,0 @@ -# VDR streamdev plugin language source file. -# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org -# This file is distributed under the same license as the VDR streamdev package. -# Frank Schmirler , 2008 -# -msgid "" -msgstr "" -"Project-Id-Version: streamdev 0.5.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-13 11:53+0100\n" -"PO-Revision-Date: 2008-03-30 02:11+0200\n" -"Last-Translator: Frank Schmirler \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-15\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "VTP Streaming Client" -msgstr "VTP Streaming Client" - -msgid "Suspend Server" -msgstr "Server pausieren" - -msgid "Server is suspended" -msgstr "Server ist pausiert" - -msgid "Couldn't suspend Server!" -msgstr "Konnte Server nicht pausieren!" - -msgid "Hide Mainmenu Entry" -msgstr "Hauptmeneintrag verstecken" - -msgid "Start Client" -msgstr "Client starten" - -msgid "Remote IP" -msgstr "IP der Gegenseite" - -msgid "Remote Port" -msgstr "Port der Gegenseite" - -msgid "Filter Streaming" -msgstr "Filter-Daten streamen" - -msgid "Minimum Priority" -msgstr "Minimale Prioritt" - -msgid "Maximum Priority" -msgstr "Maximale Prioritt" - -msgid "VDR Streaming Server" -msgstr "VDR Streaming Server" - -msgid "Streaming active" -msgstr "Streamen im Gange" - -msgid "Suspend Live TV" -msgstr "Live-TV pausieren" - -msgid "Common Settings" -msgstr "Allgemeines" - -msgid "Maximum Number of Clients" -msgstr "Maximalanzahl an Clients" - -msgid "Suspend behaviour" -msgstr "Pausierverhalten" - -msgid "Client may suspend" -msgstr "Client darf pausieren" - -msgid "VDR-to-VDR Server" -msgstr "VDR-zu-VDR Server" - -msgid "Start VDR-to-VDR Server" -msgstr "VDR-zu-VDR Server starten" - -msgid "VDR-to-VDR Server Port" -msgstr "Port des VDR-zu-VDR Servers" - -msgid "Bind to IP" -msgstr "Binde an IP" - -msgid "HTTP Server" -msgstr "HTTP Server" - -msgid "Start HTTP Server" -msgstr "HTTP Server starten" - -msgid "HTTP Server Port" -msgstr "Port des HTTP Servers" - -msgid "HTTP Streamtype" -msgstr "HTTP Streamtyp" - -msgid "Multicast Streaming Server" -msgstr "Multicast Streaming Server" - -msgid "Start IGMP Server" -msgstr "IGMP Server starten" - -msgid "Multicast Client Port" -msgstr "Port des Multicast Clients" - -msgid "Multicast Streamtype" -msgstr "Multicast Streamtyp" - -msgid "Offer suspend mode" -msgstr "Pausieren anbieten" - -msgid "Always suspended" -msgstr "Immer pausiert" - -msgid "Never suspended" -msgstr "Nie pausiert" diff --git a/po/fi_FI.po b/po/fi_FI.po deleted file mode 100644 index 7cd8a61..0000000 --- a/po/fi_FI.po +++ /dev/null @@ -1,115 +0,0 @@ -# VDR streamdev plugin language source file. -# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org -# This file is distributed under the same license as the VDR streamdev package. -# Rolf Ahrenberg , 2008 -# -msgid "" -msgstr "" -"Project-Id-Version: streamdev 0.5.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-13 11:53+0100\n" -"PO-Revision-Date: 2008-03-30 02:11+0200\n" -"Last-Translator: Rolf Ahrenberg \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-15\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "VTP Streaming Client" -msgstr "VTP-suoratoistoasiakas" - -msgid "Suspend Server" -msgstr "Pysyt palvelin" - -msgid "Server is suspended" -msgstr "Palvelin on pysytetty" - -msgid "Couldn't suspend Server!" -msgstr "Palvelinta ei onnistuttu pysyttmn!" - -msgid "Hide Mainmenu Entry" -msgstr "Piilota valinta pvalikosta" - -msgid "Start Client" -msgstr "Kynnist VDR-asiakas" - -msgid "Remote IP" -msgstr "Etkoneen IP-osoite" - -msgid "Remote Port" -msgstr "Etkoneen portti" - -msgid "Filter Streaming" -msgstr "Suodatetun tiedon suoratoisto" - -msgid "Minimum Priority" -msgstr "Pienin prioriteetti" - -msgid "Maximum Priority" -msgstr "Suurin prioriteetti" - -msgid "VDR Streaming Server" -msgstr "VDR-suoratoistopalvelin" - -msgid "Streaming active" -msgstr "Suoratoistopalvelin aktiivinen" - -msgid "Suspend Live TV" -msgstr "Pysyt suora TV-lhetys" - -msgid "Common Settings" -msgstr "Yleiset asetukset" - -msgid "Maximum Number of Clients" -msgstr "Suurin sallittu asiakkaiden mr" - -msgid "Suspend behaviour" -msgstr "Pysytystoiminto" - -msgid "Client may suspend" -msgstr "Asiakas saa pysytt palvelimen" - -msgid "VDR-to-VDR Server" -msgstr "VDR-palvelin" - -msgid "Start VDR-to-VDR Server" -msgstr "Kynnist VDR-palvelin" - -msgid "VDR-to-VDR Server Port" -msgstr "VDR-palvelimen portti" - -msgid "Bind to IP" -msgstr "Sido osoitteeseen" - -msgid "HTTP Server" -msgstr "HTTP-palvelin" - -msgid "Start HTTP Server" -msgstr "Kynnist HTTP-palvelin" - -msgid "HTTP Server Port" -msgstr "HTTP-palvelimen portti" - -msgid "HTTP Streamtype" -msgstr "HTTP-lhetysmuoto" - -msgid "Multicast Streaming Server" -msgstr "Multicast-suoratoistopalvelin" - -msgid "Start IGMP Server" -msgstr "Kynnist IGMP-palvelin" - -msgid "Multicast Client Port" -msgstr "Multicast-portti" - -msgid "Multicast Streamtype" -msgstr "Multicast-lhetysmuoto" - -msgid "Offer suspend mode" -msgstr "tyrkyt" - -msgid "Always suspended" -msgstr "aina" - -msgid "Never suspended" -msgstr "ei koskaan" diff --git a/po/fr_FR.po b/po/fr_FR.po deleted file mode 100644 index 4f6625f..0000000 --- a/po/fr_FR.po +++ /dev/null @@ -1,115 +0,0 @@ -# VDR streamdev plugin language source file. -# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org -# This file is distributed under the same license as the VDR streamdev package. -# Frank Schmirler , 2008 -# -msgid "" -msgstr "" -"Project-Id-Version: streamdev 0.5.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-13 11:53+0100\n" -"PO-Revision-Date: 2008-03-30 02:11+0200\n" -"Last-Translator: micky979 \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-15\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "VTP Streaming Client" -msgstr "Client de streaming VTP" - -msgid "Suspend Server" -msgstr "Suspendre le serveur" - -msgid "Server is suspended" -msgstr "Le serveur est suspendu" - -msgid "Couldn't suspend Server!" -msgstr "Impossible de suspendre le serveur!" - -msgid "Hide Mainmenu Entry" -msgstr "Masquer dans le menu principal" - -msgid "Start Client" -msgstr "Dmarrage du client" - -msgid "Remote IP" -msgstr "Adresse IP du serveur" - -msgid "Remote Port" -msgstr "Port du serveur" - -msgid "Filter Streaming" -msgstr "Filtre streaming" - -msgid "Minimum Priority" -msgstr "" - -msgid "Maximum Priority" -msgstr "" - -msgid "VDR Streaming Server" -msgstr "Serveur de streaming VDR" - -msgid "Streaming active" -msgstr "Streaming actif" - -msgid "Suspend Live TV" -msgstr "Suspendre Live TV" - -msgid "Common Settings" -msgstr "Paramtres communs" - -msgid "Maximum Number of Clients" -msgstr "Nombre maximun de clients" - -msgid "Suspend behaviour" -msgstr "Suspendre" - -msgid "Client may suspend" -msgstr "Le client peut suspendre" - -msgid "VDR-to-VDR Server" -msgstr "VDR-to-VDR Serveur" - -msgid "Start VDR-to-VDR Server" -msgstr "Dmarrer le serveur VDR-to-VDR" - -msgid "VDR-to-VDR Server Port" -msgstr "Port du serveur VDR-to-VDR" - -msgid "Bind to IP" -msgstr "Attacher aux IP" - -msgid "HTTP Server" -msgstr "Serveur HTTP" - -msgid "Start HTTP Server" -msgstr "Dmarrer le serveur HTTP" - -msgid "HTTP Server Port" -msgstr "Port du serveur HTTP" - -msgid "HTTP Streamtype" -msgstr "Type de Streaming HTTP" - -msgid "Multicast Streaming Server" -msgstr "" - -msgid "Start IGMP Server" -msgstr "" - -msgid "Multicast Client Port" -msgstr "" - -msgid "Multicast Streamtype" -msgstr "" - -msgid "Offer suspend mode" -msgstr "Offrir le mode suspendre" - -msgid "Always suspended" -msgstr "Toujours suspendre" - -msgid "Never suspended" -msgstr "Jamais suspendre" diff --git a/po/it_IT.po b/po/it_IT.po deleted file mode 100755 index 7ef7262..0000000 --- a/po/it_IT.po +++ /dev/null @@ -1,117 +0,0 @@ -# VDR streamdev plugin language source file. -# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org -# This file is distributed under the same license as the VDR streamdev package. -# Alberto Carraro , 2001 -# Antonio Ospite , 2003 -# Sean Carlos , 2005 -# -msgid "" -msgstr "" -"Project-Id-Version: streamdev 0.5.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-13 11:53+0100\n" -"PO-Revision-Date: 2008-04-13 23:42+0100\n" -"Last-Translator: Diego Pierotto \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-15\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "VTP Streaming Client" -msgstr "Client trasmissione VTP" - -msgid "Suspend Server" -msgstr "Sospendi Server" - -msgid "Server is suspended" -msgstr "Server sospeso" - -msgid "Couldn't suspend Server!" -msgstr "Impossibile sospendere il server!" - -msgid "Hide Mainmenu Entry" -msgstr "Nascondi voce menu principale" - -msgid "Start Client" -msgstr "Avvia Client" - -msgid "Remote IP" -msgstr "Indirizzo IP del Server" - -msgid "Remote Port" -msgstr "Porta Server Remoto" - -msgid "Filter Streaming" -msgstr "Filtra trasmissione" - -msgid "Minimum Priority" -msgstr "" - -msgid "Maximum Priority" -msgstr "" - -msgid "VDR Streaming Server" -msgstr "Server trasmissione VDR" - -msgid "Streaming active" -msgstr "Trasmissione attiva" - -msgid "Suspend Live TV" -msgstr "Sospendi TV dal vivo" - -msgid "Common Settings" -msgstr "Impostazioni comuni" - -msgid "Maximum Number of Clients" -msgstr "Numero massimo di Client" - -msgid "Suspend behaviour" -msgstr "Tipo sospensione" - -msgid "Client may suspend" -msgstr "Permetti sospensione al Client" - -msgid "VDR-to-VDR Server" -msgstr "Server VDR-a-VDR" - -msgid "Start VDR-to-VDR Server" -msgstr "Avvia Server VDR-a-VDR" - -msgid "VDR-to-VDR Server Port" -msgstr "Porta Server VDR-a-VDR" - -msgid "Bind to IP" -msgstr "IP associati" - -msgid "HTTP Server" -msgstr "Server HTTP" - -msgid "Start HTTP Server" -msgstr "Avvia Server HTTP" - -msgid "HTTP Server Port" -msgstr "Porta Server HTTP" - -msgid "HTTP Streamtype" -msgstr "Tipo flusso HTTP" - -msgid "Multicast Streaming Server" -msgstr "" - -msgid "Start IGMP Server" -msgstr "" - -msgid "Multicast Client Port" -msgstr "" - -msgid "Multicast Streamtype" -msgstr "" - -msgid "Offer suspend mode" -msgstr "Offri mod. sospensione" - -msgid "Always suspended" -msgstr "Sempre sospeso" - -msgid "Never suspended" -msgstr "Mai sospeso" diff --git a/po/lt_LT.po b/po/lt_LT.po deleted file mode 100644 index 857f7df..0000000 --- a/po/lt_LT.po +++ /dev/null @@ -1,115 +0,0 @@ -# VDR streamdev plugin language source file. -# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org -# This file is distributed under the same license as the VDR streamdev package. -# Frank Schmirler , 2008 -# -msgid "" -msgstr "" -"Project-Id-Version: streamdev 0.5.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-13 11:53+0100\n" -"PO-Revision-Date: 2009-11-26 21:57+0200\n" -"Last-Translator: Valdemaras Pipiras \n" -"Language-Team: Lietuvių\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "VTP Streaming Client" -msgstr "VTP transliavimo standartas" - -msgid "Suspend Server" -msgstr "Sustabdyti serverį" - -msgid "Server is suspended" -msgstr "Serveris sustabdytas" - -msgid "Couldn't suspend Server!" -msgstr "Negali sustabdyti serverio!" - -msgid "Hide Mainmenu Entry" -msgstr "Paslėpti pagrindinio meniu įrašą" - -msgid "Start Client" -msgstr "Paleisti klientą" - -msgid "Remote IP" -msgstr "Nuotolinis IP adresas" - -msgid "Remote Port" -msgstr "Nuotolinis portas" - -msgid "Filter Streaming" -msgstr "Filtruoti transliavimą" - -msgid "Minimum Priority" -msgstr "Minimalus prioritetas" - -msgid "Maximum Priority" -msgstr "Maksimalus prioritetas" - -msgid "VDR Streaming Server" -msgstr "VDR transliavimo serveris" - -msgid "Streaming active" -msgstr "Transliavimas vyksta" - -msgid "Suspend Live TV" -msgstr "Pristabdyti Live TV" - -msgid "Common Settings" -msgstr "Bendri nustatymai" - -msgid "Maximum Number of Clients" -msgstr "Maksimalus klientų skaičius" - -msgid "Suspend behaviour" -msgstr "Pristabdyti veikimą" - -msgid "Client may suspend" -msgstr "Klientas gali pristabdyti" - -msgid "VDR-to-VDR Server" -msgstr "VDR-su-VDR Serveris" - -msgid "Start VDR-to-VDR Server" -msgstr "Paleisti VDR-su-VDR serverį" - -msgid "VDR-to-VDR Server Port" -msgstr "VDR-su-VDR Serverio portas" - -msgid "Bind to IP" -msgstr "Pririšti IP" - -msgid "HTTP Server" -msgstr "HTTP Serveris" - -msgid "Start HTTP Server" -msgstr "Paleisti HTTP serverį" - -msgid "HTTP Server Port" -msgstr "HTTP serverio portas" - -msgid "HTTP Streamtype" -msgstr "HTTP transliavimo tipas" - -msgid "Multicast Streaming Server" -msgstr "Multicast transliavimo serveris" - -msgid "Start IGMP Server" -msgstr "Paleisti IGMP serverį" - -msgid "Multicast Client Port" -msgstr "Multicast kliento portas" - -msgid "Multicast Streamtype" -msgstr "Multicast transliavimo tipas" - -msgid "Offer suspend mode" -msgstr "Klausti dėl sustabdymo" - -msgid "Always suspended" -msgstr "Visada stabdyti" - -msgid "Never suspended" -msgstr "Niekada nestabdyti" diff --git a/po/ru_RU.po b/po/ru_RU.po deleted file mode 100644 index 44ca1fb..0000000 --- a/po/ru_RU.po +++ /dev/null @@ -1,115 +0,0 @@ -# VDR streamdev plugin language source file. -# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org -# This file is distributed under the same license as the VDR streamdev package. -# Frank Schmirler , 2008 -# -msgid "" -msgstr "" -"Project-Id-Version: streamdev 0.5.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-13 11:53+0100\n" -"PO-Revision-Date: 2008-06-26 15:36+0100\n" -"Last-Translator: Oleg Roitburd \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-5\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "VTP Streaming Client" -msgstr "VTP Streaming " - -msgid "Suspend Server" -msgstr " " - -msgid "Server is suspended" -msgstr " " - -msgid "Couldn't suspend Server!" -msgstr " " - -msgid "Hide Mainmenu Entry" -msgstr " " - -msgid "Start Client" -msgstr " " - -msgid "Remote IP" -msgstr " IP" - -msgid "Remote Port" -msgstr " " - -msgid "Filter Streaming" -msgstr " " - -msgid "Minimum Priority" -msgstr "" - -msgid "Maximum Priority" -msgstr "" - -msgid "VDR Streaming Server" -msgstr "VDR Streaming " - -msgid "Streaming active" -msgstr " " - -msgid "Suspend Live TV" -msgstr " Live TV" - -msgid "Common Settings" -msgstr "" - -msgid "Maximum Number of Clients" -msgstr ". " - -msgid "Suspend behaviour" -msgstr " " - -msgid "Client may suspend" -msgstr " " - -msgid "VDR-to-VDR Server" -msgstr "VDR-to-VDR " - -msgid "Start VDR-to-VDR Server" -msgstr " VDR-to-VDR " - -msgid "VDR-to-VDR Server Port" -msgstr "VDR-to-VDR " - -msgid "Bind to IP" -msgstr " IP" - -msgid "HTTP Server" -msgstr "HTTP " - -msgid "Start HTTP Server" -msgstr " HTTP " - -msgid "HTTP Server Port" -msgstr "HTTP " - -msgid "HTTP Streamtype" -msgstr " HTTP " - -msgid "Multicast Streaming Server" -msgstr "" - -msgid "Start IGMP Server" -msgstr "" - -msgid "Multicast Client Port" -msgstr "" - -msgid "Multicast Streamtype" -msgstr "" - -msgid "Offer suspend mode" -msgstr " " - -msgid "Always suspended" -msgstr " " - -msgid "Never suspended" -msgstr " " diff --git a/po/sk_SK.po b/po/sk_SK.po deleted file mode 100644 index 15effa5..0000000 --- a/po/sk_SK.po +++ /dev/null @@ -1,118 +0,0 @@ -# VDR streamdev plugin language source file. -# Copyright (C) 2009 streamdev development team. See http://streamdev.vdr-developer.org -# This file is distributed under the same license as the VDR streamdev package. -# Milan Hrala , 2009 -# -msgid "" -msgstr "" -"Project-Id-Version: streamdev_SK\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-23 13:59+0200\n" -"PO-Revision-Date: \n" -"Last-Translator: Milan Hrala \n" -"Language-Team: Slovak \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=iso-8859-2\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Slovak\n" -"X-Poedit-Country: SLOVAKIA\n" - -msgid "VTP Streaming Client" -msgstr "VTP prdov klient" - -msgid "Suspend Server" -msgstr "Server pozastaven" - -msgid "Server is suspended" -msgstr "Server je doasne preruen" - -msgid "Couldn't suspend Server!" -msgstr "Nepodarilo sa pozastavi Server!" - -msgid "Hide Mainmenu Entry" -msgstr "Schova poloku v hlavnom menu" - -msgid "Start Client" -msgstr "Spusti Klienta" - -msgid "Remote IP" -msgstr "Vzdialen IP" - -msgid "Remote Port" -msgstr "Vzdialen port" - -msgid "Filter Streaming" -msgstr "filtrova prdy" - -msgid "Minimum Priority" -msgstr "minimlna priorita" - -msgid "Maximum Priority" -msgstr "maximlna priorita" - -msgid "VDR Streaming Server" -msgstr "VDR prdov server" - -msgid "Streaming active" -msgstr "streamovanie aktivne" - -msgid "Suspend Live TV" -msgstr "Pozastavenie ivho vysielania" - -msgid "Common Settings" -msgstr "Veobecn nastavenia" - -msgid "Maximum Number of Clients" -msgstr "Maximly poet klientov" - -msgid "Suspend behaviour" -msgstr "Sprvanie preruenia" - -msgid "Client may suspend" -msgstr "Klient me pozastavi" - -msgid "VDR-to-VDR Server" -msgstr "VDR-do-VDR server" - -msgid "Start VDR-to-VDR Server" -msgstr "Spusti VDR-do-VDR Server" - -msgid "VDR-to-VDR Server Port" -msgstr "Port serveru pre VDR-do-VDR" - -msgid "Bind to IP" -msgstr "viaza na IP" - -msgid "HTTP Server" -msgstr "server HTTP" - -msgid "Start HTTP Server" -msgstr "Spusti HTTP Server" - -msgid "HTTP Server Port" -msgstr "Port serveru HTTP" - -msgid "HTTP Streamtype" -msgstr "typ prdu HTTP" - -msgid "Multicast Streaming Server" -msgstr "Multicast prdov server" - -msgid "Start IGMP Server" -msgstr "Spusti IGMP Server" - -msgid "Multicast Client Port" -msgstr "Port klienta Multicast" - -msgid "Multicast Streamtype" -msgstr "Multicast typ streamu" - -msgid "Offer suspend mode" -msgstr "Vber remu pozastavenia" - -msgid "Always suspended" -msgstr "Vdy pozastavi" - -msgid "Never suspended" -msgstr "Nikdy nepozastavi" - diff --git a/remux/Makefile b/remux/Makefile new file mode 100644 index 0000000..89cf4fd --- /dev/null +++ b/remux/Makefile @@ -0,0 +1,34 @@ +# +# Makefile for a Video Disk Recorder plugin +# +# $Id: Makefile,v 1.2 2010/07/19 13:49:28 schmirl Exp $ + +### The object files (add further files here): + +OBJS = tsremux.o ts2es.o ts2pes.o ts2ps.o extern.o + +### The main target: + +.PHONY: clean +remux.a: $(OBJS) + ar -rcs remux.a $^ + +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< + +### Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies + +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Targets: + +clean: + @-rm -f $(OBJS) $(DEPFILE) *.a core* *~ diff --git a/remux/extern.c b/remux/extern.c index d66dc0a..cf766d3 100644 --- a/remux/extern.c +++ b/remux/extern.c @@ -191,6 +191,11 @@ cTSExt::cTSExt(cRingBufferLinear *ResultBuffer, const cServerConnection *Connect if (setpgid(0, 0) == -1) esyslog("streamdev-server: externremux setpgid failed: %m"); + if (access(opt_remux, X_OK) == -1) { + esyslog("streamdev-server %s: %m", opt_remux); + _exit(-1); + } + if (execle("/bin/sh", "sh", "-c", opt_remux, NULL, env) == -1) { esyslog("streamdev-server: externremux script '%s' execution failed: %m", opt_remux); _exit(-1); diff --git a/remux/extern.h b/remux/extern.h index ff4ddec..070e4f6 100644 --- a/remux/extern.h +++ b/remux/extern.h @@ -5,6 +5,9 @@ #include #include +class cChannel; +class cServerConnection; + namespace Streamdev { class cTSExt; @@ -15,7 +18,7 @@ private: cTSExt *m_Remux; public: - cExternRemux(int VPid, const int *APids, const int *Dpids, const int *SPids, std::string Parameter); + cExternRemux(const cServerConnection *Connection, const cChannel *Channel, const int *APids, const int *Dpids); virtual ~cExternRemux(); int Put(const uchar *Data, int Count); diff --git a/server/Makefile b/server/Makefile new file mode 100644 index 0000000..8f512ac --- /dev/null +++ b/server/Makefile @@ -0,0 +1,82 @@ +# +# Makefile for a Video Disk Recorder plugin +# +# $Id: Makefile,v 1.2 2010/07/19 13:49:31 schmirl Exp $ + +# The official name of this plugin. +# This name will be used in the '-P...' option of VDR to load the plugin. +# By default the main source file also carries this name. +# +PLUGIN = streamdev-server + +### Includes and Defines (add further entries here): + +DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' + +### The object files (add further files here): + +COMMONOBJS = ../common.o + +SERVEROBJS = $(PLUGIN).o \ + server.o component.o connection.o \ + componentVTP.o connectionVTP.o \ + componentHTTP.o connectionHTTP.o menuHTTP.o \ + componentIGMP.o connectionIGMP.o \ + streamer.o livestreamer.o livefilter.o recplayer.o \ + suspend.o setup.o + +### The main target: + +.PHONY: all i18n clean +all: libvdr-$(PLUGIN).so i18n + +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< + +### Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies + +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(SERVEROBJS:%.o=%.c) $(COMMONOBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Internationalization (I18N): + +PODIR = po +LOCALEDIR = $(VDRDIR)/locale +I18Npo = $(wildcard $(PODIR)/*.po) +I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) +I18Npot = $(PODIR)/$(PLUGIN).pot + +%.mo: %.po + msgfmt -c -o $@ $< + +$(I18Npot): $(SERVEROBJS:%.o=%.c) + xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='' -o $@ $^ + +%.po: $(I18Npot) + msgmerge -U --no-wrap --no-location --backup=none -q $@ $< + @touch $@ + +$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo + @mkdir -p $(dir $@) + cp $< $@ + +i18n: $(I18Nmsgs) + +### Targets: + +libvdr-$(PLUGIN).so: $(SERVEROBJS) $(COMMONOBJS) \ + ../tools/sockettools.a ../remux/remux.a ../libdvbmpeg/libdvbmpegtools.a + +%.so: + $(CXX) $(CXXFLAGS) -shared $^ -o $@ + @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) + +clean: + @-rm -f $(COMMONOBJS) $(SERVEROBJS) $(DEPFILE) $(PODIR)/*.mo $(PODIR)/*.pot *.so *.tgz core* *~ diff --git a/server/connection.c b/server/connection.c index eccb3c4..2ba99f3 100644 --- a/server/connection.c +++ b/server/connection.c @@ -1,5 +1,5 @@ /* - * $Id: connection.c,v 1.13 2009/09/18 10:43:26 schmirl Exp $ + * $Id: connection.c,v 1.16 2010/08/03 10:51:53 schmirl Exp $ */ #include "server/connection.h" @@ -8,6 +8,7 @@ #include "common.h" #include +#include #include #include #include @@ -27,7 +28,7 @@ cServerConnection::~cServerConnection() { } -const cChannel* cServerConnection::ChannelFromString(const char *String, int *Apid) { +const cChannel* cServerConnection::ChannelFromString(const char *String, int *Apid, int *Dpid) { const cChannel *channel = NULL; char *string = strdup(String); char *ptr, *end; @@ -58,7 +59,8 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap } if (channel != NULL && apididx > 0) { - int apid = 0, index = 1; + int apid = 0, dpid = 0; + int index = 1; for (int i = 0; channel->Apid(i) != 0; ++i, ++index) { if (index == apididx) { @@ -70,7 +72,7 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap if (apid == 0) { for (int i = 0; channel->Dpid(i) != 0; ++i, ++index) { if (index == apididx) { - apid = channel->Dpid(i); + dpid = channel->Dpid(i); break; } } @@ -78,6 +80,8 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap if (Apid != NULL) *Apid = apid; + if (Dpid != NULL) + *Dpid = dpid; } free(string); @@ -181,75 +185,172 @@ bool cServerConnection::Respond(const char *Message, bool Last, ...) m_Pending = !Last; return true; } - + +#if APIVERSNUM >= 10700 +static int GetClippedNumProvidedSystems(int AvailableBits, cDevice *Device) +{ + int MaxNumProvidedSystems = 1 << AvailableBits; + int NumProvidedSystems = Device->NumProvidedSystems(); + if (NumProvidedSystems > MaxNumProvidedSystems) { + esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->CardIndex() + 1, NumProvidedSystems, MaxNumProvidedSystems); + NumProvidedSystems = MaxNumProvidedSystems; + } + else if (NumProvidedSystems <= 0) { + esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->CardIndex() + 1, NumProvidedSystems); + NumProvidedSystems = 1; + } + return NumProvidedSystems; +} +#endif + +/* + * copy of cDevice::GetDevice(...) but without side effects (not detaching receivers) + */ +cDevice* cServerConnection::CheckDevice(const cChannel *Channel, int Priority, bool LiveView, const cDevice *AvoidDevice) +{ + //cDevice *AvoidDevice = avoidDevice; + //avoidDevice = NULL; + // Collect the current priorities of all CAM slots that can decrypt the channel: + int NumCamSlots = CamSlots.Count(); + int SlotPriority[NumCamSlots]; + int NumUsableSlots = 0; + if (Channel->Ca() >= CA_ENCRYPTED_MIN) { + for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) { + SlotPriority[CamSlot->Index()] = MAXPRIORITY + 1; // assumes it can't be used + if (CamSlot->ModuleStatus() == msReady) { + if (CamSlot->ProvidesCa(Channel->Caids())) { + if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->SlotNumber())) { + SlotPriority[CamSlot->Index()] = CamSlot->Priority(); + NumUsableSlots++; + } + } + } + } + if (!NumUsableSlots) + return NULL; // no CAM is able to decrypt this channel + } + + bool NeedsDetachReceivers = false; + cDevice *d = NULL; + //cCamSlot *s = NULL; + + uint32_t Impact = 0xFFFFFFFF; // we're looking for a device with the least impact + for (int j = 0; j < NumCamSlots || !NumUsableSlots; j++) { + if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) + continue; // there is no CAM available in this slot + for (int i = 0; i < cDevice::NumDevices(); i++) { + cDevice *device = cDevice::GetDevice(i); + if (device == AvoidDevice) + continue; // we've been asked to skip this device + if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device->CardIndex() + 1) + continue; // a specific card was requested, but not this one + if (NumUsableSlots && !CamSlots.Get(j)->Assign(device, true)) + continue; // CAM slot can't be used with this device + bool ndr; + if (device->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basicly able to do the job + if (NumUsableSlots && device->CamSlot() && device->CamSlot() != CamSlots.Get(j)) + ndr = true; // using a different CAM slot requires detaching receivers + // Put together an integer number that reflects the "impact" using + // this device would have on the overall system. Each condition is represented + // by one bit in the number (or several bits, if the condition is actually + // a numeric value). The sequence in which the conditions are listed corresponds + // to their individual severity, where the one listed first will make the most + // difference, because it results in the most significant bit of the result. + uint32_t imp = 0; + imp <<= 1; imp |= LiveView ? !device->IsPrimaryDevice() || ndr : 0; // prefer the primary device for live viewing if we don't need to detach existing receivers + imp <<= 1; imp |= !device->Receiving() && (device != cTransferControl::ReceiverDevice() || device->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode + imp <<= 1; imp |= device->Receiving(); // avoid devices that are receiving +#if APIVERSNUM >= 10700 + imp <<= 2; imp |= GetClippedNumProvidedSystems(2, device) - 1; // avoid cards which support multiple delivery systems +#endif + imp <<= 1; imp |= device == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device + imp <<= 8; imp |= min(max(device->Priority() + MAXPRIORITY, 0), 0xFF); // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) + imp <<= 8; imp |= min(max((NumUsableSlots ? SlotPriority[j] : 0) + MAXPRIORITY, 0), 0xFF); // use the CAM slot with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) + imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers + imp <<= 1; imp |= device->IsPrimaryDevice(); // avoid the primary device + imp <<= 1; imp |= NumUsableSlots ? 0 : device->HasCi(); // avoid cards with Common Interface for FTA channels + imp <<= 1; imp |= device->HasDecoder(); // avoid full featured cards + imp <<= 1; imp |= NumUsableSlots ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel + if (imp < Impact) { + // This device has less impact than any previous one, so we take it. + Impact = imp; + d = device; + NeedsDetachReceivers = ndr; + } + } + } + if (!NumUsableSlots) + break; // no CAM necessary, so just one loop over the devices + } + return d; +} + cDevice *cServerConnection::GetDevice(const cChannel *Channel, int Priority) { - cDevice *device = NULL; - - /*Dprintf("+ Statistics:\n"); - Dprintf("+ Current Channel: %d\n", cDevice::CurrentChannel()); - Dprintf("+ Current Device: %d\n", cDevice::ActualDevice()->CardIndex()); - Dprintf("+ Transfer Mode: %s\n", cDevice::ActualDevice() - == cDevice::PrimaryDevice() ? "false" : "true"); - Dprintf("+ Replaying: %s\n", cDevice::PrimaryDevice()->Replaying() ? "true" - : "false");*/ - - Dprintf(" * GetDevice(const cChannel*, int)\n"); - Dprintf(" * -------------------------------\n"); - - device = cDevice::GetDevice(Channel, Priority, false); - - Dprintf(" * Found following device: %p (%d)\n", device, - device ? device->CardIndex() + 1 : 0); - if (device == cDevice::ActualDevice()) - Dprintf(" * is actual device\n"); - if (!cSuspendCtl::IsActive() && StreamdevServerSetup.SuspendMode != smAlways) - Dprintf(" * NOT suspended\n"); - - if (!device || (device == cDevice::ActualDevice() + const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel()); + + // turn off the streams of this connection + Detach(); + // This call may detach receivers of the device it returns + cDevice *device = cDevice::GetDevice(Channel, Priority, false); + + if (device && device == cDevice::ActualDevice() && !cSuspendCtl::IsActive() - && StreamdevServerSetup.SuspendMode != smAlways)) { + && StreamdevServerSetup.SuspendMode != smAlways + && current != NULL + && !TRANSPONDER(Channel, current)) { + // now we would have to switch away live tv...let's see if live tv + // can be handled by another device +#if VDRVERSNUM >= 10516 + cDevice::SetAvoidDevice(device); + cDevice *newdev = cDevice::GetDevice(current, 0, true); +#else + cDevice *newdev = CheckDevice(current, 0, true, device); +#endif + if (newdev) + newdev->SwitchChannel(current, true); + else + device = NULL; + } + + if (!device) { + // can't switch - continue the current stream + Attach(); + dsyslog("streamdev: GetDevice failed for channel %s at priority %d", Channel->Name(), Priority); + } + return device; +} + +bool cServerConnection::ProvidesChannel(const cChannel *Channel, int Priority) +{ + const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel()); + + cDevice *device = CheckDevice(Channel, Priority, false); + if (!device || (device == cDevice::ActualDevice() + && !cSuspendCtl::IsActive() + && StreamdevServerSetup.SuspendMode != smAlways + && current != NULL + && !TRANSPONDER(Channel, current))) { // mustn't switch actual device // maybe a device would be free if THIS connection did turn off its streams? - Dprintf(" * trying again...\n"); - const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel()); - isyslog("streamdev-server: Detaching current receiver"); Detach(); - device = cDevice::GetDevice(Channel, Priority, false); + device = CheckDevice(Channel, Priority, false); Attach(); - Dprintf(" * Found following device: %p (%d)\n", device, - device ? device->CardIndex() + 1 : 0); - if (device == cDevice::ActualDevice()) - Dprintf(" * is actual device\n"); - if (!cSuspendCtl::IsActive() - && StreamdevServerSetup.SuspendMode != smAlways) - Dprintf(" * NOT suspended\n"); - if (current && !TRANSPONDER(Channel, current)) - Dprintf(" * NOT same transponder\n"); - if (device && (device == cDevice::ActualDevice() - && !cSuspendCtl::IsActive() + if (device && device == cDevice::ActualDevice() + && !cSuspendCtl::IsActive() && StreamdevServerSetup.SuspendMode != smAlways && current != NULL - && !TRANSPONDER(Channel, current))) { + && !TRANSPONDER(Channel, current)) { // now we would have to switch away live tv...let's see if live tv // can be handled by another device - cDevice *newdev = NULL; - for (int i = 0; i < cDevice::NumDevices(); ++i) { - cDevice *dev = cDevice::GetDevice(i); - if (dev->ProvidesChannel(current, 0) && dev != device) { - newdev = dev; - break; - } - } - Dprintf(" * Found device for live tv: %p (%d)\n", newdev, - newdev ? newdev->CardIndex() + 1 : 0); - if (newdev == NULL || newdev == device) - // no suitable device to continue live TV, giving up... + cDevice *newdev = CheckDevice(current, 0, true, device); + if (!newdev) { device = NULL; - else - newdev->SwitchChannel(current, true); + dsyslog("streamdev: Not providing channel %s at priority %d - live TV not suspended", Channel->Name(), Priority); + } } + else if (!device) + dsyslog("streamdev: No device provides channel %s at priority %d", Channel->Name(), Priority); } - return device; } diff --git a/server/connection.h b/server/connection.h index 73cb3d5..22301b1 100644 --- a/server/connection.h +++ b/server/connection.h @@ -1,5 +1,5 @@ /* - * $Id: connection.h,v 1.8 2009/09/18 10:43:26 schmirl Exp $ + * $Id: connection.h,v 1.10 2010/08/03 10:46:41 schmirl Exp $ */ #ifndef VDR_STREAMDEV_SERVER_CONNECTION_H @@ -8,6 +8,11 @@ #include "tools/socket.h" #include "common.h" +#include + +typedef std::map tStrStrMap; +typedef std::pair tStrStr; + class cChannel; class cDevice; @@ -28,6 +33,13 @@ private: uint m_WriteBytes; uint m_WriteIndex; + tStrStrMap m_Headers; + + /* Check if a device would be available for transfering the given + channel. This call has no side effects except for temporarily + detaching this connection's receivers. */ + cDevice *CheckDevice(const cChannel *Channel, int Priority, bool LiveView, const cDevice *AvoidDevice = NULL); + protected: /* Will be called when a command terminated by a newline has been received */ @@ -41,7 +53,10 @@ protected: virtual bool Respond(const char *Message, bool Last = true, ...); //__attribute__ ((format (printf, 2, 4))); - static const cChannel *ChannelFromString(const char *String, int *Apid = NULL); + /* Add a request header */ + void SetHeader(const char *Name, const char *Value, const char *Prefix = "") { m_Headers.insert(tStrStr(std::string(Prefix) + Name, Value)); } + + static const cChannel *ChannelFromString(const char *String, int *Apid = NULL, int *Dpid = NULL); public: /* If you derive, specify a short string such as HTTP for Protocol, which @@ -81,14 +96,24 @@ public: /* Will make the socket close after sending all queued output data */ void DeferClose(void) { m_DeferClose = true; } - /* Will retrieve an unused device for transmitting data. Use the returned + /* Will retrieve an unused device for transmitting data. Receivers have + already been attached from the device if necessary. Use the returned cDevice in a following call to StartTransfer */ cDevice *GetDevice(const cChannel *Channel, int Priority); + /* Test if a call to GetDevice would return a usable device. */ + bool ProvidesChannel(const cChannel *Channel, int Priority); + virtual void Flushed(void) {} virtual void Detach(void) = 0; virtual void Attach(void) = 0; + + /* This connections protocol name */ + virtual const char* Protocol(void) const { return m_Protocol; } + + /* std::map with additional information */ + const tStrStrMap& Headers(void) const { return m_Headers; } }; inline bool cServerConnection::HasData(void) const diff --git a/server/connectionHTTP.c b/server/connectionHTTP.c index 16a2af7..54ccf5a 100644 --- a/server/connectionHTTP.c +++ b/server/connectionHTTP.c @@ -1,5 +1,5 @@ /* - * $Id: connectionHTTP.c,v 1.20 2010/07/22 14:18:18 schmirl Exp $ + * $Id: connectionHTTP.c,v 1.21 2010/08/03 10:46:41 schmirl Exp $ */ #include @@ -149,7 +149,9 @@ bool cConnectionHTTP::ProcessRequest(void) if (m_ChannelList) return Respond("%s", true, m_ChannelList->HttpHeader().c_str()); else if (m_Channel != NULL) { - cDevice *device = GetDevice(m_Channel, 0); + cDevice *device = NULL; + if (ProvidesChannel(m_Channel, 0)) + device = GetDevice(m_Channel, 0); if (device != NULL) { device->SwitchChannel(m_Channel, false); m_LiveStreamer = new cStreamdevLiveStreamer(0, this); @@ -186,8 +188,7 @@ bool cConnectionHTTP::ProcessRequest(void) if (m_ChannelList) return Respond("%s", true, m_ChannelList->HttpHeader().c_str()); else if (m_Channel != NULL) { - cDevice *device = GetDevice(m_Channel, 0); - if (device != NULL) { + if (ProvidesChannel(m_Channel, 0)) { if (m_StreamType == stEXT) { // TODO return Respond("HTTP/1.0 200 OK") diff --git a/server/connectionHTTP.h b/server/connectionHTTP.h index 0548959..56f89b0 100644 --- a/server/connectionHTTP.h +++ b/server/connectionHTTP.h @@ -1,5 +1,5 @@ /* - * $Id: connectionHTTP.h,v 1.6 2008/10/14 11:05:48 schmirl Exp $ + * $Id: connectionHTTP.h,v 1.7 2010/07/19 13:49:31 schmirl Exp $ */ #ifndef VDR_STREAMDEV_SERVERS_CONNECTIONHTTP_H @@ -8,6 +8,7 @@ #include "connection.h" #include "server/livestreamer.h" +#include #include class cChannel; @@ -23,26 +24,19 @@ private: hsFinished, }; - enum eHTTPJob { - hjTransfer, - hjListing, - }; - - std::string m_Request; - std::string m_Host; std::string m_Authorization; - //std::map m_Headers; TODO: later? eHTTPStatus m_Status; - eHTTPJob m_Job; // job: transfer cStreamdevLiveStreamer *m_LiveStreamer; - std::string m_StreamerParameter; const cChannel *m_Channel; - int m_Apid; + int m_Apid[2]; + int m_Dpid[2]; eStreamType m_StreamType; // job: listing cChannelList *m_ChannelList; + cChannelList* ChannelListFromString(const std::string &PathInfo, const std::string &Filebase, const std::string &Fileext) const; + bool ProcessURI(const std::string &PathInfo); protected: bool ProcessRequest(void); @@ -56,7 +50,6 @@ public: virtual bool CanAuthenticate(void); virtual bool Command(char *Cmd); - bool CmdGET(const std::string &Opts); virtual bool Abort(void) const; virtual void Flushed(void); diff --git a/server/connectionIGMP.c b/server/connectionIGMP.c index dc08798..708f41c 100644 --- a/server/connectionIGMP.c +++ b/server/connectionIGMP.c @@ -1,5 +1,5 @@ /* - * $Id: connectionIGMP.c,v 1.1 2009/02/13 10:39:22 schmirl Exp $ + * $Id: connectionIGMP.c,v 1.3 2010/08/03 10:46:41 schmirl Exp $ */ #include @@ -25,13 +25,15 @@ cConnectionIGMP::~cConnectionIGMP() bool cConnectionIGMP::Start(cChannel *Channel, in_addr_t Dst) { if (Channel != NULL) { - cDevice *device = GetDevice(Channel, 0); + cDevice *device = NULL; + if (ProvidesChannel(Channel, 0)) + device = GetDevice(Channel, 0); if (device != NULL) { device->SwitchChannel(Channel, false); struct in_addr ip; ip.s_addr = Dst; if (Connect(inet_ntoa(ip), m_ClientPort)) { - m_LiveStreamer = new cStreamdevLiveStreamer(0); + m_LiveStreamer = new cStreamdevLiveStreamer(0, this); if (m_LiveStreamer->SetChannel(Channel, m_StreamType)) { m_LiveStreamer->SetDevice(device); if (!SetDSCP()) diff --git a/server/connectionVTP.c b/server/connectionVTP.c index 7ff60e5..0f92db0 100644 --- a/server/connectionVTP.c +++ b/server/connectionVTP.c @@ -1,5 +1,5 @@ /* - * $Id: connectionVTP.c,v 1.27 2010/01/29 12:03:02 schmirl Exp $ + * $Id: connectionVTP.c,v 1.31 2010/08/18 10:26:54 schmirl Exp $ */ #include "server/connectionVTP.h" @@ -746,6 +746,8 @@ cConnectionVTP::cConnectionVTP(void): m_StreamType(stTSPIDS), m_FiltersSupport(false), m_RecPlayer(NULL), + m_TuneChannel(NULL), + m_TunePriority(0), m_LSTEHandler(NULL), m_LSTCHandler(NULL), m_LSTTHandler(NULL), @@ -836,6 +838,7 @@ bool cConnectionVTP::Command(char *Cmd) else if (strcasecmp(Cmd, "READ") == 0) return CmdREAD(param); else if (strcasecmp(Cmd, "TUNE") == 0) return CmdTUNE(param); else if (strcasecmp(Cmd, "PLAY") == 0) return CmdPLAY(param); + else if (strcasecmp(Cmd, "PRIO") == 0) return CmdPRIO(param); else if (strcasecmp(Cmd, "ADDP") == 0) return CmdADDP(param); else if (strcasecmp(Cmd, "DELP") == 0) return CmdDELP(param); else if (strcasecmp(Cmd, "ADDF") == 0) return CmdADDF(param); @@ -881,8 +884,8 @@ bool cConnectionVTP::CmdCAPS(char *Opts) return Respond(220, "Capability \"%s\" accepted", Opts); } - if (strcasecmp(Opts, "EXTERN") == 0) { - m_StreamType = stExtern; + if (strcasecmp(Opts, "EXT") == 0) { + m_StreamType = stEXT; return Respond(220, "Capability \"%s\" accepted", Opts); } @@ -894,6 +897,11 @@ bool cConnectionVTP::CmdCAPS(char *Opts) return Respond(220, "Capability \"%s\" accepted", Opts); } + // Command PRIO is known + if (strcasecmp(Opts, "PRIO") == 0) { + return Respond(220, "Capability \"%s\" accepted", Opts); + } + return Respond(561, "Capability \"%s\" not known", Opts); } @@ -911,9 +919,15 @@ bool cConnectionVTP::CmdPROV(char *Opts) if ((chan = ChannelFromString(Opts)) == NULL) return Respond(550, "Undefined channel \"%s\"", Opts); - return GetDevice(chan, prio) != NULL - ? Respond(220, "Channel available") - : Respond(560, "Channel not available"); + if (ProvidesChannel(chan, prio)) { + m_TuneChannel = chan; + m_TunePriority = prio; + return Respond(220, "Channel available"); + } + else { + m_TuneChannel = NULL; + return Respond(560, "Channel not available"); + } } bool cConnectionVTP::CmdPORT(char *Opts) @@ -1067,18 +1081,23 @@ bool cConnectionVTP::CmdTUNE(char *Opts) { const cChannel *chan; cDevice *dev; + int prio = m_TunePriority; if ((chan = ChannelFromString(Opts)) == NULL) return Respond(550, "Undefined channel \"%s\"", Opts); - if ((dev = GetDevice(chan, 0)) == NULL) + if (chan != m_TuneChannel) { + esyslog("streamdev-server TUNE %s: Priority unknown - using 0", Opts); + prio = 0; + } + if ((dev = GetDevice(chan, prio)) == NULL) return Respond(560, "Channel not available"); if (!dev->SwitchChannel(chan, false)) return Respond(560, "Channel not available"); delete m_LiveStreamer; - m_LiveStreamer = new cStreamdevLiveStreamer(1); + m_LiveStreamer = new cStreamdevLiveStreamer(prio, this); m_LiveStreamer->SetChannel(chan, m_StreamType); m_LiveStreamer->SetDevice(dev); if(m_LiveSocket) @@ -1119,6 +1138,22 @@ bool cConnectionVTP::CmdPLAY(char *Opts) } } +bool cConnectionVTP::CmdPRIO(char *Opts) +{ + int prio; + char *end; + + prio = strtoul(Opts, &end, 10); + if (end == Opts || (*end != '\0' && *end != ' ')) + return Respond(500, "Use: PRIO Priority"); + + if (m_LiveStreamer) { + m_LiveStreamer->SetPriority(prio); + return Respond(220, "Priority changed to %d", prio); + } + return Respond(550, "Priority not applicable"); +} + bool cConnectionVTP::CmdADDP(char *Opts) { int pid; @@ -1243,6 +1278,7 @@ bool cConnectionVTP::CmdSUSP(void) else if (StreamdevServerSetup.SuspendMode == smOffer && StreamdevServerSetup.AllowSuspend) { cControl::Launch(new cSuspendCtl); + cControl::Attach(); return Respond(220, "Server is suspended"); } else return Respond(550, "Client may not suspend server"); diff --git a/server/connectionVTP.h b/server/connectionVTP.h index b938fe6..ee842fe 100644 --- a/server/connectionVTP.h +++ b/server/connectionVTP.h @@ -31,6 +31,11 @@ private: bool m_FiltersSupport; RecPlayer *m_RecPlayer; + // Priority is only known in PROV command + // Store in here for later use in TUNE call + const cChannel *m_TuneChannel; + int m_TunePriority; + // Members adopted for SVDRP cLSTEHandler *m_LSTEHandler; cLSTCHandler *m_LSTCHandler; @@ -59,6 +64,7 @@ public: bool CmdREAD(char *Opts); bool CmdTUNE(char *Opts); bool CmdPLAY(char *Opts); + bool CmdPRIO(char *Opts); bool CmdADDP(char *Opts); bool CmdDELP(char *Opts); bool CmdADDF(char *Opts); diff --git a/server/livestreamer.c b/server/livestreamer.c index ab7c6b4..1286abd 100644 --- a/server/livestreamer.c +++ b/server/livestreamer.c @@ -289,7 +289,7 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i if (written != TS_SIZE) siBuffer.ReportOverflow(TS_SIZE - written); if (pmtPid != prevPmtPid) { - m_Streamer->SetPids(pmtPid); + m_Streamer->SetPid(pmtPid, true); Add(pmtPid, 0x02); pmtVersion = -1; } @@ -335,10 +335,9 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i // --- cStreamdevLiveStreamer ------------------------------------------------- -cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority, std::string Parameter): - cStreamdevStreamer("streamdev-livestreaming"), +cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority, const cServerConnection *Connection): + cStreamdevStreamer("streamdev-livestreaming", Connection), m_Priority(Priority), - m_Parameter(Parameter), m_NumPids(0), m_StreamType(stTSPIDS), m_Channel(NULL), @@ -435,53 +434,58 @@ bool cStreamdevLiveStreamer::SetPids(int Pid, const int *Pids1, const int *Pids2 return true; } +void cStreamdevLiveStreamer::SetPriority(int Priority) +{ + m_Priority = Priority; + StartReceiver(); +} + void cStreamdevLiveStreamer::StartReceiver(void) { - DELETENULL(m_Receiver); - if (m_NumPids > 0) { + if (m_Device != NULL && m_NumPids > 0 && IsRunning()) { Dprintf("Creating Receiver to respect changed pids\n"); + cReceiver *current = m_Receiver; m_Receiver = new cStreamdevLiveReceiver(this, m_Channel->GetChannelID(), m_Priority, m_Pids); - if (IsRunning() && m_Device != NULL) { - Dprintf("Attaching new receiver\n"); - Attach(); - } + cThreadLock ThreadLock(m_Device); + Attach(); + delete current; } + else + DELETENULL(m_Receiver); } -bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid) +bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, const int* Apid, const int *Dpid) { Dprintf("Initializing Remuxer for full channel transfer\n"); //printf("ca pid: %d\n", Channel->Ca()); m_Channel = Channel; m_StreamType = StreamType; - int apid[2] = { Apid, 0 }; - const int *Apids = Apid ? apid : m_Channel->Apids(); - const int *Dpids = Apid ? NULL : m_Channel->Dpids(); + const int *Apids = Apid ? Apid : m_Channel->Apids(); + const int *Dpids = Dpid ? Dpid : m_Channel->Dpids(); switch (m_StreamType) { case stES: { int pid = ISRADIO(m_Channel) ? m_Channel->Apid(0) : m_Channel->Vpid(); - if (Apid != 0) - pid = Apid; + if (Apid && Apid[0]) + pid = Apid[0]; + else if (Dpid && Dpid[0]) + pid = Dpid[0]; m_Remux = new cTS2ESRemux(pid); return SetPids(pid); } case stPES: - m_Remux = new cTS2PESRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(), - m_Channel->Spids()); + m_Remux = new cTS2PESRemux(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids()); return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids()); case stPS: - m_Remux = new cTS2PSRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(), - m_Channel->Spids()); + m_Remux = new cTS2PSRemux(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids()); return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids()); - case stExtern: - m_Remux = new cExternRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(), - m_Channel->Spids(), m_Parameter); + case stEXT: + m_Remux = new cExternRemux(Connection(), m_Channel, Apids, Dpids); // fall through case stTS: // This should never happen, but ... @@ -634,12 +638,10 @@ void cStreamdevFilterStreamer::SetDevice(cDevice *Device) { Dprintf("cStreamdevFilterStreamer::SetDevice()\n"); LOCK_THREAD; - if(Device != m_Device) { - Detach(); - m_Device = Device; - //m_Channel = NULL; - Attach(); - } + Detach(); + m_Device = Device; + //m_Channel = NULL; + Attach(); } bool cStreamdevFilterStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On) diff --git a/server/livestreamer.h b/server/livestreamer.h index 92448bb..71feb4c 100644 --- a/server/livestreamer.h +++ b/server/livestreamer.h @@ -18,7 +18,6 @@ class cStreamdevLiveReceiver; class cStreamdevLiveStreamer: public cStreamdevStreamer { private: int m_Priority; - std::string m_Parameter; int m_Pids[MAXRECEIVEPIDS + 1]; int m_NumPids; eStreamType m_StreamType; @@ -32,13 +31,14 @@ private: bool HasPid(int Pid); public: - cStreamdevLiveStreamer(int Priority, std::string Parameter = ""); + cStreamdevLiveStreamer(int Priority, const cServerConnection *Connection); virtual ~cStreamdevLiveStreamer(); void SetDevice(cDevice *Device) { m_Device = Device; } bool SetPid(int Pid, bool On); bool SetPids(int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL); - bool SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid = 0); + bool SetChannel(const cChannel *Channel, eStreamType StreamType, const int* Apid = NULL, const int* Dpid = NULL); + void SetPriority(int Priority); virtual int Put(const uchar *Data, int Count); virtual uchar *Get(int &Count); diff --git a/server/menuHTTP.c b/server/menuHTTP.c index 84a4fb7..d7fb817 100644 --- a/server/menuHTTP.c +++ b/server/menuHTTP.c @@ -2,7 +2,7 @@ #include "server/menuHTTP.h" //**************************** cChannelIterator ************** -cChannelIterator::cChannelIterator(cChannel *First): channel(First) +cChannelIterator::cChannelIterator(const cChannel *First): channel(First) {} const cChannel* cChannelIterator::Next() @@ -19,7 +19,7 @@ cListAll::cListAll(): cChannelIterator(Channels.First()) const cChannel* cListAll::NextChannel(const cChannel *Channel) { if (Channel) - Channel = Channels.Next(Channel); + Channel = SkipFakeGroups(Channels.Next(Channel)); return Channel; } @@ -46,14 +46,19 @@ const cChannel* cListGroups::NextChannel(const cChannel *Channel) } // // ********************* cListGroup **************** -cListGroup::cListGroup(const cChannel *Group): cChannelIterator((Group && Group->GroupSep() && Channels.Next(Group) && !Channels.Next(Group)->GroupSep()) ? Channels.Next(Group) : NULL) +cListGroup::cListGroup(const cChannel *Group): cChannelIterator(GetNextChannelInGroup(Group)) {} -const cChannel* cListGroup::NextChannel(const cChannel *Channel) +const cChannel* cListGroup::GetNextChannelInGroup(const cChannel *Channel) { if (Channel) - Channel = Channels.Next(Channel); - return (Channel && !Channel->GroupSep()) ? Channel : NULL; + Channel = SkipFakeGroups(Channels.Next(Channel)); + return Channel && !Channel->GroupSep() ? Channel : NULL; +} + +const cChannel* cListGroup::NextChannel(const cChannel *Channel) +{ + return GetNextChannelInGroup(Channel); } // // ********************* cListTree **************** @@ -68,7 +73,7 @@ const cChannel* cListTree::NextChannel(const cChannel *Channel) if (currentGroup == selectedGroup) { if (Channel) - Channel = Channels.Next(Channel); + Channel = SkipFakeGroups(Channels.Next(Channel)); if (Channel && Channel->GroupSep()) currentGroup = Channel; } @@ -205,8 +210,8 @@ std::string cHtmlChannelList::StreamTypeMenu() (std::string) "[PES] "); typeMenu += (streamType == stES ? (std::string) "[ES] " : (std::string) "[ES] "); - typeMenu += (streamType == stExtern ? (std::string) "[Extern] " : - (std::string) "[Extern] "); + typeMenu += (streamType == stEXT ? (std::string) "[EXT] " : + (std::string) "[EXT] "); return typeMenu; } diff --git a/server/menuHTTP.h b/server/menuHTTP.h index cbd7b59..4ef6363 100644 --- a/server/menuHTTP.h +++ b/server/menuHTTP.h @@ -13,9 +13,10 @@ class cChannelIterator const cChannel *channel; protected: virtual const cChannel* NextChannel(const cChannel *Channel) = 0; + static inline const cChannel* SkipFakeGroups(const cChannel *Channel); public: const cChannel* Next(); - cChannelIterator(cChannel *First); + cChannelIterator(const cChannel *First); virtual ~cChannelIterator() {}; }; @@ -48,6 +49,8 @@ class cListGroups: public cChannelIterator class cListGroup: public cChannelIterator { + private: + static const cChannel* GetNextChannelInGroup(const cChannel *Channel); protected: virtual const cChannel* NextChannel(const cChannel *Channel); public: @@ -140,4 +143,11 @@ class cM3uChannelList: public cChannelList virtual ~cM3uChannelList(); }; +inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group) +{ + while (Group && Group->GroupSep() && !*Group->Name()) + Group = Channels.Next(Group); + return Group; +} + #endif diff --git a/server/po/de_DE.po b/server/po/de_DE.po new file mode 100644 index 0000000..5fb611d --- /dev/null +++ b/server/po/de_DE.po @@ -0,0 +1,83 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Frank Schmirler , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:06+0200\n" +"PO-Revision-Date: 2008-03-30 02:11+0200\n" +"Last-Translator: Frank Schmirler \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VDR Streaming Server" +msgstr "VDR Streaming Server" + +msgid "Streaming active" +msgstr "Streamen im Gange" + +msgid "Suspend Live TV" +msgstr "Live-TV pausieren" + +msgid "Offer suspend mode" +msgstr "Pausieren anbieten" + +msgid "Always suspended" +msgstr "Immer pausiert" + +msgid "Never suspended" +msgstr "Nie pausiert" + +msgid "Common Settings" +msgstr "Allgemeines" + +msgid "Maximum Number of Clients" +msgstr "Maximalanzahl an Clients" + +msgid "Suspend behaviour" +msgstr "Pausierverhalten" + +msgid "Client may suspend" +msgstr "Client darf pausieren" + +msgid "VDR-to-VDR Server" +msgstr "VDR-zu-VDR Server" + +msgid "Start VDR-to-VDR Server" +msgstr "VDR-zu-VDR Server starten" + +msgid "VDR-to-VDR Server Port" +msgstr "Port des VDR-zu-VDR Servers" + +msgid "Bind to IP" +msgstr "Binde an IP" + +msgid "HTTP Server" +msgstr "HTTP Server" + +msgid "Start HTTP Server" +msgstr "HTTP Server starten" + +msgid "HTTP Server Port" +msgstr "Port des HTTP Servers" + +msgid "HTTP Streamtype" +msgstr "HTTP Streamtyp" + +msgid "Multicast Streaming Server" +msgstr "Multicast Streaming Server" + +msgid "Start IGMP Server" +msgstr "IGMP Server starten" + +msgid "Multicast Client Port" +msgstr "Port des Multicast Clients" + +msgid "Multicast Streamtype" +msgstr "Multicast Streamtyp" + diff --git a/server/po/fi_FI.po b/server/po/fi_FI.po new file mode 100644 index 0000000..99c6ee5 --- /dev/null +++ b/server/po/fi_FI.po @@ -0,0 +1,83 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Rolf Ahrenberg , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:06+0200\n" +"PO-Revision-Date: 2008-03-30 02:11+0200\n" +"Last-Translator: Rolf Ahrenberg \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VDR Streaming Server" +msgstr "VDR-suoratoistopalvelin" + +msgid "Streaming active" +msgstr "Suoratoistopalvelin aktiivinen" + +msgid "Suspend Live TV" +msgstr "Pysyt suora TV-lhetys" + +msgid "Offer suspend mode" +msgstr "tyrkyt" + +msgid "Always suspended" +msgstr "aina" + +msgid "Never suspended" +msgstr "ei koskaan" + +msgid "Common Settings" +msgstr "Yleiset asetukset" + +msgid "Maximum Number of Clients" +msgstr "Suurin sallittu asiakkaiden mr" + +msgid "Suspend behaviour" +msgstr "Pysytystoiminto" + +msgid "Client may suspend" +msgstr "Asiakas saa pysytt palvelimen" + +msgid "VDR-to-VDR Server" +msgstr "VDR-palvelin" + +msgid "Start VDR-to-VDR Server" +msgstr "Kynnist VDR-palvelin" + +msgid "VDR-to-VDR Server Port" +msgstr "VDR-palvelimen portti" + +msgid "Bind to IP" +msgstr "Sido osoitteeseen" + +msgid "HTTP Server" +msgstr "HTTP-palvelin" + +msgid "Start HTTP Server" +msgstr "Kynnist HTTP-palvelin" + +msgid "HTTP Server Port" +msgstr "HTTP-palvelimen portti" + +msgid "HTTP Streamtype" +msgstr "HTTP-lhetysmuoto" + +msgid "Multicast Streaming Server" +msgstr "Multicast-suoratoistopalvelin" + +msgid "Start IGMP Server" +msgstr "Kynnist IGMP-palvelin" + +msgid "Multicast Client Port" +msgstr "Multicast-portti" + +msgid "Multicast Streamtype" +msgstr "Multicast-lhetysmuoto" + diff --git a/server/po/fr_FR.po b/server/po/fr_FR.po new file mode 100644 index 0000000..c4b458e --- /dev/null +++ b/server/po/fr_FR.po @@ -0,0 +1,83 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Frank Schmirler , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:06+0200\n" +"PO-Revision-Date: 2008-03-30 02:11+0200\n" +"Last-Translator: micky979 \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VDR Streaming Server" +msgstr "Serveur de streaming VDR" + +msgid "Streaming active" +msgstr "Streaming actif" + +msgid "Suspend Live TV" +msgstr "Suspendre Live TV" + +msgid "Offer suspend mode" +msgstr "Offrir le mode suspendre" + +msgid "Always suspended" +msgstr "Toujours suspendre" + +msgid "Never suspended" +msgstr "Jamais suspendre" + +msgid "Common Settings" +msgstr "Paramtres communs" + +msgid "Maximum Number of Clients" +msgstr "Nombre maximun de clients" + +msgid "Suspend behaviour" +msgstr "Suspendre" + +msgid "Client may suspend" +msgstr "Le client peut suspendre" + +msgid "VDR-to-VDR Server" +msgstr "VDR-to-VDR Serveur" + +msgid "Start VDR-to-VDR Server" +msgstr "Dmarrer le serveur VDR-to-VDR" + +msgid "VDR-to-VDR Server Port" +msgstr "Port du serveur VDR-to-VDR" + +msgid "Bind to IP" +msgstr "Attacher aux IP" + +msgid "HTTP Server" +msgstr "Serveur HTTP" + +msgid "Start HTTP Server" +msgstr "Dmarrer le serveur HTTP" + +msgid "HTTP Server Port" +msgstr "Port du serveur HTTP" + +msgid "HTTP Streamtype" +msgstr "Type de Streaming HTTP" + +msgid "Multicast Streaming Server" +msgstr "" + +msgid "Start IGMP Server" +msgstr "" + +msgid "Multicast Client Port" +msgstr "" + +msgid "Multicast Streamtype" +msgstr "" + diff --git a/server/po/it_IT.po b/server/po/it_IT.po new file mode 100644 index 0000000..c5eed57 --- /dev/null +++ b/server/po/it_IT.po @@ -0,0 +1,85 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Alberto Carraro , 2001 +# Antonio Ospite , 2003 +# Sean Carlos , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:06+0200\n" +"PO-Revision-Date: 2010-06-19 03:58+0100\n" +"Last-Translator: Diego Pierotto \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VDR Streaming Server" +msgstr "Server trasmissione VDR" + +msgid "Streaming active" +msgstr "Trasmissione attiva" + +msgid "Suspend Live TV" +msgstr "Sospendi TV dal vivo" + +msgid "Offer suspend mode" +msgstr "Offri mod. sospensione" + +msgid "Always suspended" +msgstr "Sempre sospeso" + +msgid "Never suspended" +msgstr "Mai sospeso" + +msgid "Common Settings" +msgstr "Impostazioni comuni" + +msgid "Maximum Number of Clients" +msgstr "Numero massimo di Client" + +msgid "Suspend behaviour" +msgstr "Tipo sospensione" + +msgid "Client may suspend" +msgstr "Permetti sospensione al Client" + +msgid "VDR-to-VDR Server" +msgstr "Server VDR-a-VDR" + +msgid "Start VDR-to-VDR Server" +msgstr "Avvia Server VDR-a-VDR" + +msgid "VDR-to-VDR Server Port" +msgstr "Porta Server VDR-a-VDR" + +msgid "Bind to IP" +msgstr "IP associati" + +msgid "HTTP Server" +msgstr "Server HTTP" + +msgid "Start HTTP Server" +msgstr "Avvia Server HTTP" + +msgid "HTTP Server Port" +msgstr "Porta Server HTTP" + +msgid "HTTP Streamtype" +msgstr "Tipo flusso HTTP" + +msgid "Multicast Streaming Server" +msgstr "Server trasmissione Multicast" + +msgid "Start IGMP Server" +msgstr "Avvia Server IGMP" + +msgid "Multicast Client Port" +msgstr "Porta Client Multicast" + +msgid "Multicast Streamtype" +msgstr "Tipo flusso Multicast" + diff --git a/server/po/lt_LT.po b/server/po/lt_LT.po new file mode 100644 index 0000000..f12de4d --- /dev/null +++ b/server/po/lt_LT.po @@ -0,0 +1,83 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Frank Schmirler , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:06+0200\n" +"PO-Revision-Date: 2009-11-26 21:57+0200\n" +"Last-Translator: Valdemaras Pipiras \n" +"Language-Team: Lietuvių\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VDR Streaming Server" +msgstr "VDR transliavimo serveris" + +msgid "Streaming active" +msgstr "Transliavimas vyksta" + +msgid "Suspend Live TV" +msgstr "Pristabdyti Live TV" + +msgid "Offer suspend mode" +msgstr "Klausti dėl sustabdymo" + +msgid "Always suspended" +msgstr "Visada stabdyti" + +msgid "Never suspended" +msgstr "Niekada nestabdyti" + +msgid "Common Settings" +msgstr "Bendri nustatymai" + +msgid "Maximum Number of Clients" +msgstr "Maksimalus klientų skaičius" + +msgid "Suspend behaviour" +msgstr "Pristabdyti veikimą" + +msgid "Client may suspend" +msgstr "Klientas gali pristabdyti" + +msgid "VDR-to-VDR Server" +msgstr "VDR-su-VDR Serveris" + +msgid "Start VDR-to-VDR Server" +msgstr "Paleisti VDR-su-VDR serverį" + +msgid "VDR-to-VDR Server Port" +msgstr "VDR-su-VDR Serverio portas" + +msgid "Bind to IP" +msgstr "Pririšti IP" + +msgid "HTTP Server" +msgstr "HTTP Serveris" + +msgid "Start HTTP Server" +msgstr "Paleisti HTTP serverį" + +msgid "HTTP Server Port" +msgstr "HTTP serverio portas" + +msgid "HTTP Streamtype" +msgstr "HTTP transliavimo tipas" + +msgid "Multicast Streaming Server" +msgstr "Multicast transliavimo serveris" + +msgid "Start IGMP Server" +msgstr "Paleisti IGMP serverį" + +msgid "Multicast Client Port" +msgstr "Multicast kliento portas" + +msgid "Multicast Streamtype" +msgstr "Multicast transliavimo tipas" + diff --git a/server/po/ru_RU.po b/server/po/ru_RU.po new file mode 100644 index 0000000..21abeaf --- /dev/null +++ b/server/po/ru_RU.po @@ -0,0 +1,83 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Frank Schmirler , 2008 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev 0.5.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:06+0200\n" +"PO-Revision-Date: 2008-06-26 15:36+0100\n" +"Last-Translator: Oleg Roitburd \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-5\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "VDR Streaming Server" +msgstr "VDR Streaming " + +msgid "Streaming active" +msgstr " " + +msgid "Suspend Live TV" +msgstr " Live TV" + +msgid "Offer suspend mode" +msgstr " " + +msgid "Always suspended" +msgstr " " + +msgid "Never suspended" +msgstr " " + +msgid "Common Settings" +msgstr "" + +msgid "Maximum Number of Clients" +msgstr ". " + +msgid "Suspend behaviour" +msgstr " " + +msgid "Client may suspend" +msgstr " " + +msgid "VDR-to-VDR Server" +msgstr "VDR-to-VDR " + +msgid "Start VDR-to-VDR Server" +msgstr " VDR-to-VDR " + +msgid "VDR-to-VDR Server Port" +msgstr "VDR-to-VDR " + +msgid "Bind to IP" +msgstr " IP" + +msgid "HTTP Server" +msgstr "HTTP " + +msgid "Start HTTP Server" +msgstr " HTTP " + +msgid "HTTP Server Port" +msgstr "HTTP " + +msgid "HTTP Streamtype" +msgstr " HTTP " + +msgid "Multicast Streaming Server" +msgstr "" + +msgid "Start IGMP Server" +msgstr "" + +msgid "Multicast Client Port" +msgstr "" + +msgid "Multicast Streamtype" +msgstr "" + diff --git a/server/po/sk_SK.po b/server/po/sk_SK.po new file mode 100644 index 0000000..78d98c9 --- /dev/null +++ b/server/po/sk_SK.po @@ -0,0 +1,85 @@ +# VDR streamdev plugin language source file. +# Copyright (C) 2009 streamdev development team. See http://streamdev.vdr-developer.org +# This file is distributed under the same license as the VDR streamdev package. +# Milan Hrala , 2009 +# +msgid "" +msgstr "" +"Project-Id-Version: streamdev_SK\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-06-14 13:06+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: Milan Hrala \n" +"Language-Team: Slovak \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-2\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Slovak\n" +"X-Poedit-Country: SLOVAKIA\n" + +msgid "VDR Streaming Server" +msgstr "VDR prdov server" + +msgid "Streaming active" +msgstr "streamovanie aktivne" + +msgid "Suspend Live TV" +msgstr "Pozastavenie ivho vysielania" + +msgid "Offer suspend mode" +msgstr "Vber remu pozastavenia" + +msgid "Always suspended" +msgstr "Vdy pozastavi" + +msgid "Never suspended" +msgstr "Nikdy nepozastavi" + +msgid "Common Settings" +msgstr "Veobecn nastavenia" + +msgid "Maximum Number of Clients" +msgstr "Maximly poet klientov" + +msgid "Suspend behaviour" +msgstr "Sprvanie preruenia" + +msgid "Client may suspend" +msgstr "Klient me pozastavi" + +msgid "VDR-to-VDR Server" +msgstr "VDR-do-VDR server" + +msgid "Start VDR-to-VDR Server" +msgstr "Spusti VDR-do-VDR Server" + +msgid "VDR-to-VDR Server Port" +msgstr "Port serveru pre VDR-do-VDR" + +msgid "Bind to IP" +msgstr "viaza na IP" + +msgid "HTTP Server" +msgstr "server HTTP" + +msgid "Start HTTP Server" +msgstr "Spusti HTTP Server" + +msgid "HTTP Server Port" +msgstr "Port serveru HTTP" + +msgid "HTTP Streamtype" +msgstr "typ prdu HTTP" + +msgid "Multicast Streaming Server" +msgstr "Multicast prdov server" + +msgid "Start IGMP Server" +msgstr "Spusti IGMP Server" + +msgid "Multicast Client Port" +msgstr "Port klienta Multicast" + +msgid "Multicast Streamtype" +msgstr "Multicast typ streamu" + diff --git a/server/setup.c b/server/setup.c index db709db..8c9b8ad 100644 --- a/server/setup.c +++ b/server/setup.c @@ -1,5 +1,5 @@ /* - * $Id: setup.c,v 1.9 2009/10/13 06:38:47 schmirl Exp $ + * $Id: setup.c,v 1.10 2010/07/19 13:49:31 schmirl Exp $ */ #include @@ -50,7 +50,7 @@ const char* cStreamdevServerMenuSetupPage::StreamTypes[st_Count - 1] = { "PES", "PS", "ES", - "Extern" + "EXT" }; const char* cStreamdevServerMenuSetupPage::SuspendModes[sm_Count] = { @@ -62,15 +62,25 @@ const char* cStreamdevServerMenuSetupPage::SuspendModes[sm_Count] = { cStreamdevServerMenuSetupPage::cStreamdevServerMenuSetupPage(void) { m_NewSetup = StreamdevServerSetup; + Set(); +} + +cStreamdevServerMenuSetupPage::~cStreamdevServerMenuSetupPage() { +} + +void cStreamdevServerMenuSetupPage::Set(void) { static const char* modes[sm_Count]; for (int i = 0; i < sm_Count; i++) modes[i] = tr(SuspendModes[i]); + int current = Current(); + Clear(); AddCategory (tr("Common Settings")); Add(new cMenuEditIntItem (tr("Maximum Number of Clients"), &m_NewSetup.MaxClients, 0, 100)); Add(new cMenuEditStraItem(tr("Suspend behaviour"), &m_NewSetup.SuspendMode, sm_Count, modes)); - Add(new cMenuEditBoolItem(tr("Client may suspend"), &m_NewSetup.AllowSuspend)); + if (m_NewSetup.SuspendMode == smOffer) + Add(new cMenuEditBoolItem(tr("Client may suspend"), &m_NewSetup.AllowSuspend)); AddCategory (tr("VDR-to-VDR Server")); Add(new cMenuEditBoolItem(tr("Start VDR-to-VDR Server"), &m_NewSetup.StartVTPServer)); @@ -87,10 +97,8 @@ cStreamdevServerMenuSetupPage::cStreamdevServerMenuSetupPage(void) { Add(new cMenuEditIntItem (tr("Multicast Client Port"), &m_NewSetup.IGMPClientPort, 0, 65535)); Add(new cMenuEditStraItem(tr("Multicast Streamtype"), &m_NewSetup.IGMPStreamType, st_Count - 1, StreamTypes)); Add(new cMenuEditIpItem (tr("Bind to IP"), m_NewSetup.IGMPBindIP)); - SetCurrent(Get(1)); -} - -cStreamdevServerMenuSetupPage::~cStreamdevServerMenuSetupPage() { + SetCurrent(Get(current)); + Display(); } void cStreamdevServerMenuSetupPage::AddCategory(const char *Title) { @@ -139,3 +147,10 @@ void cStreamdevServerMenuSetupPage::Store(void) { cStreamdevServer::Initialize(); } +eOSState cStreamdevServerMenuSetupPage::ProcessKey(eKeys Key) { + int oldMode = m_NewSetup.SuspendMode; + eOSState state = cMenuSetupPage::ProcessKey(Key); + if (oldMode != m_NewSetup.SuspendMode) + Set(); + return state; +} diff --git a/server/setup.h b/server/setup.h index d22ab34..9f06aac 100644 --- a/server/setup.h +++ b/server/setup.h @@ -1,5 +1,5 @@ /* - * $Id: setup.h,v 1.3 2009/09/18 10:43:26 schmirl Exp $ + * $Id: setup.h,v 1.4 2010/07/19 13:49:31 schmirl Exp $ */ #ifndef VDR_STREAMDEV_SETUPSERVER_H @@ -37,8 +37,10 @@ private: cStreamdevServerSetup m_NewSetup; void AddCategory(const char *Title); + void Set(); protected: virtual void Store(void); + virtual eOSState ProcessKey(eKeys Key); public: cStreamdevServerMenuSetupPage(void); diff --git a/server/streamdev-server.c b/server/streamdev-server.c new file mode 100644 index 0000000..b444df7 --- /dev/null +++ b/server/streamdev-server.c @@ -0,0 +1,143 @@ +/* + * streamdev.c: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: streamdev-server.c,v 1.2 2010/07/19 13:49:32 schmirl Exp $ + */ + +#include +#include +#include "streamdev-server.h" +#include "server/setup.h" +#include "server/server.h" +#include "server/suspend.h" + +#if !defined(APIVERSNUM) || APIVERSNUM < 10509 +#error "VDR-1.5.9 API version or greater is required!" +#endif + +const char *cPluginStreamdevServer::DESCRIPTION = trNOOP("VDR Streaming Server"); + +cPluginStreamdevServer::cPluginStreamdevServer(void) +{ +} + +cPluginStreamdevServer::~cPluginStreamdevServer() +{ + free(opt_auth); + free(opt_remux); +} + +const char *cPluginStreamdevServer::Description(void) +{ + return tr(DESCRIPTION); +} + +const char *cPluginStreamdevServer::CommandLineHelp(void) +{ + // return a string that describes all known command line options. + return + " -a , --auth= Credentials for HTTP authentication.\n" + " -r , --remux= Define an external command for remuxing.\n" + ; +} + +bool cPluginStreamdevServer::ProcessArgs(int argc, char *argv[]) +{ + // implement command line argument processing here if applicable. + static const struct option long_options[] = { + { "auth", required_argument, NULL, 'a' }, + { "remux", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0 } + }; + + int c; + while((c = getopt_long(argc, argv, "a:r:", long_options, NULL)) != -1) { + switch (c) { + case 'a': + { + if (opt_auth) + free(opt_auth); + int l = strlen(optarg); + cBase64Encoder Base64((uchar*) optarg, l, l * 4 / 3 + 3); + const char *s = Base64.NextLine(); + if (s) + opt_auth = strdup(s); + } + break; + case 'r': + if (opt_remux) + free(opt_remux); + opt_remux = strdup(optarg); + break; + default: + return false; + } + } + return true; +} + +bool cPluginStreamdevServer::Start(void) +{ + I18nRegister(PLUGIN_NAME_I18N); + if (!StreamdevHosts.Load(STREAMDEVHOSTSPATH, true, true)) { + esyslog("streamdev-server: error while loading %s", STREAMDEVHOSTSPATH); + fprintf(stderr, "streamdev-server: error while loading %s\n", STREAMDEVHOSTSPATH); + if (access(STREAMDEVHOSTSPATH, F_OK) != 0) { + fprintf(stderr, " Please install streamdevhosts.conf into the path " + "printed above. Without it\n" + " no client will be able to access your streaming-" + "server. An example can be\n" + " found together with this plugin's sources.\n"); + } + return false; + } + if (!opt_remux) + opt_remux = strdup(DEFAULT_EXTERNREMUX); + + cStreamdevServer::Initialize(); + + return true; +} + +void cPluginStreamdevServer::Stop(void) +{ + cStreamdevServer::Destruct(); +} + +cString cPluginStreamdevServer::Active(void) +{ + if (cStreamdevServer::Active()) + { + static const char *Message = NULL; + if (!Message) Message = tr("Streaming active"); + return Message; + } + return NULL; +} + +const char *cPluginStreamdevServer::MainMenuEntry(void) +{ + if (StreamdevServerSetup.SuspendMode == smOffer && !cSuspendCtl::IsActive()) + return tr("Suspend Live TV"); + return NULL; +} + +cOsdObject *cPluginStreamdevServer::MainMenuAction(void) +{ + cControl::Launch(new cSuspendCtl); + return NULL; +} + +cMenuSetupPage *cPluginStreamdevServer::SetupMenu(void) +{ + return new cStreamdevServerMenuSetupPage; +} + +bool cPluginStreamdevServer::SetupParse(const char *Name, const char *Value) +{ + return StreamdevServerSetup.SetupParse(Name, Value); +} + +VDRPLUGINCREATOR(cPluginStreamdevServer); // Don't touch this! diff --git a/server/streamdev-server.h b/server/streamdev-server.h new file mode 100644 index 0000000..4083689 --- /dev/null +++ b/server/streamdev-server.h @@ -0,0 +1,33 @@ +/* + * $Id: streamdev-server.h,v 1.2 2010/07/19 13:49:32 schmirl Exp $ + */ + +#ifndef VDR_STREAMDEVSERVER_H +#define VDR_STREAMDEVSERVER_H + +#include "common.h" + +#include + +class cPluginStreamdevServer : public cPlugin { +private: + static const char *DESCRIPTION; + +public: + cPluginStreamdevServer(void); + virtual ~cPluginStreamdevServer(); + + virtual const char *Version(void) { return VERSION; } + virtual const char *Description(void); + virtual const char *CommandLineHelp(void); + virtual bool ProcessArgs(int argc, char *argv[]); + virtual bool Start(void); + virtual void Stop(void); + virtual cString Active(void); + virtual const char *MainMenuEntry(void); + virtual cOsdObject *MainMenuAction(void); + virtual cMenuSetupPage *SetupMenu(void); + virtual bool SetupParse(const char *Name, const char *Value); +}; + +#endif // VDR_STREAMDEVSERVER_H diff --git a/server/streamer.c b/server/streamer.c index 42e7efa..ec7d3c3 100644 --- a/server/streamer.c +++ b/server/streamer.c @@ -1,5 +1,5 @@ /* - * $Id: streamer.c,v 1.19 2009/06/19 06:32:45 schmirl Exp $ + * $Id: streamer.c,v 1.21 2010/07/30 10:01:11 schmirl Exp $ */ #include @@ -46,6 +46,9 @@ void cStreamdevWriter::Action(void) uchar *block = NULL; int count, offset = 0; +#if APIVERSNUM >= 10705 + SetPriority(-3); +#endif sel.Clear(); sel.Add(*m_Socket, true); while (Running()) { @@ -100,8 +103,9 @@ void cStreamdevWriter::Action(void) // --- cStreamdevStreamer ----------------------------------------------------- -cStreamdevStreamer::cStreamdevStreamer(const char *Name): +cStreamdevStreamer::cStreamdevStreamer(const char *Name, const cServerConnection *Connection): cThread(Name), + m_Connection(Connection), m_Writer(NULL), m_RingBuffer(new cStreamdevBuffer(STREAMERBUFSIZE, TS_SIZE * 2, true, "streamdev-streamer")), @@ -148,6 +152,9 @@ void cStreamdevStreamer::Stop(void) void cStreamdevStreamer::Action(void) { +#if APIVERSNUM >= 10705 + SetPriority(-3); +#endif while (Running()) { int got; uchar *block = m_RingBuffer->Get(got); diff --git a/server/streamer.h b/server/streamer.h index 6561bc2..988775a 100644 --- a/server/streamer.h +++ b/server/streamer.h @@ -1,5 +1,5 @@ /* - * $Id: streamer.h,v 1.11 2009/06/19 06:32:45 schmirl Exp $ + * $Id: streamer.h,v 1.12 2010/07/19 13:49:32 schmirl Exp $ */ #ifndef VDR_STREAMDEV_STREAMER_H @@ -11,6 +11,7 @@ class cTBSocket; class cStreamdevStreamer; +class cServerConnection; #ifndef TS_SIZE #define TS_SIZE 188 @@ -64,6 +65,7 @@ public: class cStreamdevStreamer: public cThread { private: + const cServerConnection *m_Connection; cStreamdevWriter *m_Writer; cStreamdevBuffer *m_RingBuffer; cStreamdevBuffer *m_SendBuffer; @@ -74,9 +76,11 @@ protected: bool IsRunning(void) const { return m_Writer; } public: - cStreamdevStreamer(const char *Name); + cStreamdevStreamer(const char *Name, const cServerConnection *Connection = NULL); virtual ~cStreamdevStreamer(); + const cServerConnection* Connection(void) const { return m_Connection; } + virtual void Start(cTBSocket *Socket); virtual void Stop(void); bool Abort(void); diff --git a/streamdev-client.c b/streamdev-client.c deleted file mode 100644 index 9a6b4a7..0000000 --- a/streamdev-client.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * streamdev.c: A plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - * $Id: streamdev-client.c,v 1.7 2010/06/08 05:55:16 schmirl Exp $ - */ - -#include "streamdev-client.h" -#include "client/device.h" -#include "client/setup.h" - -#if !defined(APIVERSNUM) || APIVERSNUM < 10509 -#error "VDR-1.5.9 API version or greater is required!" -#endif - -const char *cPluginStreamdevClient::DESCRIPTION = trNOOP("VTP Streaming Client"); - -cPluginStreamdevClient::cPluginStreamdevClient(void) { -} - -cPluginStreamdevClient::~cPluginStreamdevClient() { -} - -const char *cPluginStreamdevClient::Description(void) { - return tr(DESCRIPTION); -} - -bool cPluginStreamdevClient::Start(void) { - I18nRegister(PLUGIN_NAME_I18N); - cStreamdevDevice::Init(); - return true; -} - -const char *cPluginStreamdevClient::MainMenuEntry(void) { - return StreamdevClientSetup.StartClient && !StreamdevClientSetup.HideMenuEntry ? tr("Suspend Server") : NULL; -} - -cOsdObject *cPluginStreamdevClient::MainMenuAction(void) { - if (ClientSocket.SuspendServer()) - Skins.Message(mtInfo, tr("Server is suspended")); - else - Skins.Message(mtError, tr("Couldn't suspend Server!")); - return NULL; -} - -cMenuSetupPage *cPluginStreamdevClient::SetupMenu(void) { - return new cStreamdevClientMenuSetupPage; -} - -bool cPluginStreamdevClient::SetupParse(const char *Name, const char *Value) { - return StreamdevClientSetup.SetupParse(Name, Value); -} - -VDRPLUGINCREATOR(cPluginStreamdevClient); // Don't touch this! diff --git a/streamdev-client.h b/streamdev-client.h deleted file mode 100644 index 97af4dd..0000000 --- a/streamdev-client.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * $Id: streamdev-client.h,v 1.2 2010/06/08 05:55:16 schmirl Exp $ - */ - -#ifndef VDR_STREAMDEVCLIENT_H -#define VDR_STREAMDEVCLIENT_H - -#include "common.h" - -#include - -class cPluginStreamdevClient : public cPlugin { -private: - static const char *DESCRIPTION; - -public: - cPluginStreamdevClient(void); - virtual ~cPluginStreamdevClient(); - virtual const char *Version(void) { return VERSION; } - virtual const char *Description(void); - virtual bool Start(void); - virtual const char *MainMenuEntry(void); - virtual cOsdObject *MainMenuAction(void); - virtual cMenuSetupPage *SetupMenu(void); - virtual bool SetupParse(const char *Name, const char *Value); -}; - -#endif // VDR_STREAMDEVCLIENT_H diff --git a/streamdev-server.c b/streamdev-server.c deleted file mode 100644 index 3593d9f..0000000 --- a/streamdev-server.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * streamdev.c: A plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - * $Id: streamdev-server.c,v 1.12 2009/06/19 06:32:38 schmirl Exp $ - */ - -#include -#include -#include "streamdev-server.h" -#include "server/setup.h" -#include "server/server.h" -#include "server/suspend.h" - -#if !defined(APIVERSNUM) || APIVERSNUM < 10509 -#error "VDR-1.5.9 API version or greater is required!" -#endif - -const char *cPluginStreamdevServer::DESCRIPTION = trNOOP("VDR Streaming Server"); - -cPluginStreamdevServer::cPluginStreamdevServer(void) -{ -} - -cPluginStreamdevServer::~cPluginStreamdevServer() -{ - free(opt_auth); - free(opt_remux); -} - -const char *cPluginStreamdevServer::Description(void) -{ - return tr(DESCRIPTION); -} - -const char *cPluginStreamdevServer::CommandLineHelp(void) -{ - // return a string that describes all known command line options. - return - " -a , --auth= Credentials for HTTP authentication.\n" - " -r , --remux= Define an external command for remuxing.\n" - ; -} - -bool cPluginStreamdevServer::ProcessArgs(int argc, char *argv[]) -{ - // implement command line argument processing here if applicable. - static const struct option long_options[] = { - { "auth", required_argument, NULL, 'a' }, - { "remux", required_argument, NULL, 'r' }, - { NULL, 0, NULL, 0 } - }; - - int c; - while((c = getopt_long(argc, argv, "a:r:", long_options, NULL)) != -1) { - switch (c) { - case 'a': - { - if (opt_auth) - free(opt_auth); - int l = strlen(optarg); - cBase64Encoder Base64((uchar*) optarg, l, l * 4 / 3 + 3); - const char *s = Base64.NextLine(); - if (s) - opt_auth = strdup(s); - } - break; - case 'r': - if (opt_remux) - free(opt_remux); - opt_remux = strdup(optarg); - break; - default: - return false; - } - } - return true; -} - -bool cPluginStreamdevServer::Start(void) -{ - I18nRegister(PLUGIN_NAME_I18N); - if (!StreamdevHosts.Load(STREAMDEVHOSTSPATH, true, true)) { - esyslog("streamdev-server: error while loading %s", STREAMDEVHOSTSPATH); - fprintf(stderr, "streamdev-server: error while loading %s\n", STREAMDEVHOSTSPATH); - if (access(STREAMDEVHOSTSPATH, F_OK) != 0) { - fprintf(stderr, " Please install streamdevhosts.conf into the path " - "printed above. Without it\n" - " no client will be able to access your streaming-" - "server. An example can be\n" - " found together with this plugin's sources.\n"); - } - return false; - } - if (!opt_remux) - opt_remux = strdup(DEFAULT_EXTERNREMUX); - - cStreamdevServer::Initialize(); - - return true; -} - -void cPluginStreamdevServer::Stop(void) -{ - cStreamdevServer::Destruct(); -} - -cString cPluginStreamdevServer::Active(void) -{ - if (cStreamdevServer::Active()) - { - static const char *Message = NULL; - if (!Message) Message = tr("Streaming active"); - return Message; - } - return NULL; -} - -const char *cPluginStreamdevServer::MainMenuEntry(void) -{ - if (StreamdevServerSetup.SuspendMode == smOffer && !cSuspendCtl::IsActive()) - return tr("Suspend Live TV"); - return NULL; -} - -cOsdObject *cPluginStreamdevServer::MainMenuAction(void) -{ - cControl::Launch(new cSuspendCtl); - return NULL; -} - -cMenuSetupPage *cPluginStreamdevServer::SetupMenu(void) -{ - return new cStreamdevServerMenuSetupPage; -} - -bool cPluginStreamdevServer::SetupParse(const char *Name, const char *Value) -{ - return StreamdevServerSetup.SetupParse(Name, Value); -} - -VDRPLUGINCREATOR(cPluginStreamdevServer); // Don't touch this! diff --git a/streamdev-server.h b/streamdev-server.h deleted file mode 100644 index 8149e4b..0000000 --- a/streamdev-server.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * $Id: streamdev-server.h,v 1.4 2007/02/19 12:08:16 schmirl Exp $ - */ - -#ifndef VDR_STREAMDEVSERVER_H -#define VDR_STREAMDEVSERVER_H - -#include "common.h" - -#include - -class cPluginStreamdevServer : public cPlugin { -private: - static const char *DESCRIPTION; - -public: - cPluginStreamdevServer(void); - virtual ~cPluginStreamdevServer(); - - virtual const char *Version(void) { return VERSION; } - virtual const char *Description(void); - virtual const char *CommandLineHelp(void); - virtual bool ProcessArgs(int argc, char *argv[]); - virtual bool Start(void); - virtual void Stop(void); - virtual cString Active(void); - virtual const char *MainMenuEntry(void); - virtual cOsdObject *MainMenuAction(void); - virtual cMenuSetupPage *SetupMenu(void); - virtual bool SetupParse(const char *Name, const char *Value); -}; - -#endif // VDR_STREAMDEVSERVER_H diff --git a/streamdev-server/externremux.sh b/streamdev-server/externremux.sh index 06c7052..20fda78 100755 --- a/streamdev-server/externremux.sh +++ b/streamdev-server/externremux.sh @@ -16,6 +16,8 @@ # VBR video bitrate (kbit) # VOPTS custom video options # WIDTH scale video to width +# HEIGHT scale video to height +# FPS output frames per second # AC audio codec # ABR audio bitrate (kbit) # AOPTS custom audio options @@ -42,14 +44,22 @@ ABR_MONO=64 ### # mencoder binary MENCODER=mencoder +### video part # Default video codec (e.g. lavc/x264/copy) MENCODER_VC=lavc +# Default video options if lavc is used (-ovc lavc -lavcopts ...) +MENCODER_LAVC_VOPTS=vcodec=mpeg4 +# Default video options if x264 is used (-ovc x264 -x264encopts ...) +MENCODER_X264_VOPTS=threads=auto +### audio part # Default audio codec (e.g. lavc/mp3lame/faac/copy) MENCODER_AC=mp3lame -# Default video codec if lavc is used (-ovc lavc -lavcopts vcodec=) -MENCODER_LAVC_VC=mpeg4 -# Default audio codec if lavc is used (-oac lavc -lavcopts acodec=) -MENCODER_LAVC_AC=mp2 +# Default audio options if lavc is used (-oac lavc -lavcopts ...) +MENCODER_LAVC_AOPTS=acodec=mp2 +# Default audio options if mp3lame is used (-oac mp3lame -lameopts ...) +MENCODER_LAME_AOPTS= +# Default audio options if faac is used (-oac faac -faacopts ...) +MENCODER_FAAC_AOPTS= ### ### MENCODER CONFIG END @@ -63,6 +73,8 @@ OGG_SPEED=1 OGG_VQUALITY=0 # audioquality - higher value gives better quality but is slower (0..10) OGG_AQUALITY=0 +# aspect ratio used for scaling if only one of HEIGHT/WIDTH given (16/9 or 4/3) +OGG_ASPECT='4 / 3' ### ### OGG CONFIG END @@ -70,7 +82,19 @@ OGG_AQUALITY=0 function hasOpt { echo "$1" | grep -q "\b${2}\b"; } -function isNumeric() { echo "$@" | grep -q '^[0-9]\{1,\}$'; } +# $1: concatenation of already set option=value pairs +# $2-$n: option=value pairs to be echod if the option is not present in $1 +function addOpts +{ + local opts="$1" + shift + while [ $# -gt 0 ]; do + hasOpt "$opts" ${1%%=*}= || echo $1 + shift + done +} + +function isNumeric() { echo "$@" | grep -q '^-\?[0-9]\{1,\}$'; } function remux_cat { @@ -87,20 +111,31 @@ function remux_mencoder # Assemble video options VC=${REMUX_PARAM_VC:-$MENCODER_VC} VOPTS=${REMUX_PARAM_VOPTS} - WIDTH=${REMUX_PARAM_WIDTH:-$WIDTH} + FPS=${REMUX_PARAM_FPS:-$FPS} + + # if only one of HEIGHT/WIDTH given: + # have mencoder calculate other value depending on actual aspect ratio + if [ "$HEIGHT" -a -z "$WIDTH" ]; then + WIDTH=-3 + elif [ "$WIDTH" -a -z "$HEIGHT" ]; then + HEIGHT=-3 + fi + case "$VC" in lavc) LAVCOPTS=( ${VOPTS} - $(hasOpt "$VOPTS" vcodec || echo "vcodec=$MENCODER_LAVC_VC") + $(IFS=$IFS:; addOpts "$VOPTS" $MENCODER_LAVC_VOPTS) ${VBR:+vbitrate=$VBR} ) [ ${#LAVCOPTS[*]} -gt 0 ] && VOPTS=$(IFS=:; echo -lavcopts "${LAVCOPTS[*]}") ;; x264) + isNumeric "$HEIGHT" && [ $HEIGHT -lt 0 -a $HEIGHT -gt -8 ] && ((HEIGHT-=8)) + isNumeric "$WIDTH" && [ $WIDTH -lt 0 -a $WIDTH -gt -8 ] && ((WIDTH-=8)) X264OPTS=( ${VOPTS} - $(hasOpt "$VOPTS" threads || echo "threads=auto") + $(IFS=$IFS:; addOpts "$VOPTS" $MENCODER_X264_VOPTS) ${VBR:+bitrate=$VBR} ) [ ${#X264OPTS[*]} -gt 0 ] && VOPTS=$(IFS=:; echo -x264encopts "${X264OPTS[*]}") @@ -121,7 +156,7 @@ function remux_mencoder LAVCOPTS=( ${LAVCOPTS[*]} ${AOPTS} - $(hasOpt "$AOPTS" acodec || echo "acodec=$MENCODER_LAVC_AC") + $(IFS=$IFS:; addOpts "$AOPTS" $MENCODER_LAVC_AOPTS) ${ABR:+abitrate=$ABR} ) @@ -133,6 +168,7 @@ function remux_mencoder LAMEOPTS=( ${AOPTS} $(isNumeric "${ABR}" && [ "${ABR}" -lt "$ABR_MONO" ] && ! hasOpt "${AOPTS}" mode ] && echo 'mode=3') + $(IFS=$IFS:; addOpts "$AOPTS" $MENCODER_LAME_AOPTS) ${ABR:+preset=$ABR} ) [ ${#LAMEOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -lameopts "${LAMEOPTS[*]}") @@ -140,6 +176,7 @@ function remux_mencoder faac) FAACOPTS=( ${AOPTS} + $(IFS=$IFS:; addOpts "$AOPTS" $MENCODER_FAAC_AOPTS) ${ABR:+br=$ABR} ) [ ${#FAACOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -faacopts "${FAACOPTS[*]}") @@ -155,15 +192,17 @@ function remux_mencoder startReply exec 3<&0 - echo "$MENCODER" \ + echo $MENCODER \ -ovc $VC $VOPTS \ -oac $AC $AOPTS \ - ${WIDTH:+-vf scale -zoom -xy $WIDTH} \ + ${WIDTH:+-vf scale=$WIDTH:$HEIGHT -zoom} \ + ${FPS:+-ofps $FPS} \ -o "$FIFO" -- - >&2 - "$MENCODER" \ + $MENCODER \ -ovc $VC $VOPTS \ -oac $AC $AOPTS \ - ${WIDTH:+-vf scale -zoom -xy $WIDTH} \ + ${WIDTH:+-vf scale=$WIDTH:$HEIGHT -zoom} \ + ${FPS:+-ofps $FPS} \ -o "$FIFO" -- - 0<&3 >/dev/null & } @@ -171,7 +210,15 @@ function remux_ogg { VOPTS=${REMUX_PARAM_VOPTS//[:=]/ } AOPTS=${REMUX_PARAM_AOPTS//[:=]/ } - WIDTH=${REMUX_PARAM_WIDTH:-$WIDTH} + + # if only one of HEIGHT/WIDTH given: + # calculate other value depending on configured aspect ratio + # trim to multiple of 8 + if [ "$HEIGHT" -a -z "$WIDTH" ]; then + WIDTH=$((HEIGHT * $OGG_ASPECT / 8 * 8)) + elif [ "$WIDTH" -a -z "$HEIGHT" ]; then + HEIGHT=$(($WIDTH * $( echo $OGG_ASPECT | sed 's#^\([0-9]\+\) */ *\([0-9]\+\)$#\2 / \1#') / 8 * 8)) + fi OGGOPTS=( ${VOPTS} @@ -187,14 +234,14 @@ function remux_ogg startReply exec 3<&0 - echo "$OGG" --format ts \ + echo $OGG --format ts \ ${OGGOPTS[*]} \ - ${WIDTH:+--width $WIDTH --height $(($WIDTH * 3 / 4 / 8 * 8))} \ + ${WIDTH:+--width $WIDTH --height $HEIGHT} \ --title "VDR Streamdev: ${REMUX_CHANNEL_NAME}" \ --output "$FIFO" -- - 0<&3 >&2 - "$OGG" --format ts \ + $OGG --format ts \ ${OGGOPTS[*]} \ - ${WIDTH:+--width $WIDTH --height $(($WIDTH * 3 / 4 / 8 * 8))} \ + ${WIDTH:+--width $WIDTH --height $HEIGHT} \ --title "VDR Streamdev: ${REMUX_CHANNEL_NAME}" \ --output "$FIFO" -- - 0<&3 >/dev/null & } @@ -254,6 +301,7 @@ esac ABR=${REMUX_PARAM_ABR:-$ABR} VBR=${REMUX_PARAM_VBR:-$VBR} WIDTH=${REMUX_PARAM_WIDTH:-$WIDTH} +HEIGHT=${REMUX_PARAM_HEIGHT:-$HEIGHT} PROG=${REMUX_PARAM_PROG:-$PROG} case "$PROG" in diff --git a/streamdev-server/streamdevhosts.conf b/streamdev-server/streamdevhosts.conf new file mode 100644 index 0000000..7243eeb --- /dev/null +++ b/streamdev-server/streamdevhosts.conf @@ -0,0 +1,14 @@ +# +# streamdevhosts This file describes a number of host addresses that +# are allowed to connect to the streamdev server running +# with the Video Disk Recorder (VDR) on this system. +# Syntax: +# +# IP-Address[/Netmask] +# + +127.0.0.1 # always accept localhost +#192.168.100.0/24 # any host on the local net +#204.152.189.113 # a specific host +#239.255.0.0/16 # uncomment for IGMP multicast streaming +#0.0.0.0/0 # any host on any net (DON'T DO THAT! USE AUTHENTICATION) diff --git a/streamdev/externremux.sh b/streamdev/externremux.sh deleted file mode 100755 index e2b4156..0000000 --- a/streamdev/externremux.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# -# externremux.sh - sample remux script using mencoder for remuxing. -# -# Install this script as VDRCONFDIR/plugins/streamdev/externremux.sh -# -# The parameter STREAMQUALITY selects the default remux parameters. Adjust -# to your needs and point your web browser to http://servername:3000/extern/ -# To select different remux parameters on the fly, insert a semicolon and -# the name of the requested quality: http://servername:3000/extern;WLAN11/ - -# CONFIG START - STREAMQUALITY="DSL6000" # DSL{1,2,3,6}000, LAN10, WLAN{11,54}, IPAQ - TMP=/tmp/externremux-${RANDOM:-$$} - MENCODER=mencoder -# CONFIG END - -mkdir -p $TMP -mkfifo $TMP/out.avi -(trap "rm -rf $TMP" EXIT HUP INT TERM ABRT; cat $TMP/out.avi) & - -case ${1:-$STREAMQUALITY} in - DSL1000) exec $MENCODER -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=100 \ - -oac mp3lame -lameopts preset=15:mode=3 -vf scale=160:104 \ - -o $TMP/out.avi -- - &>$TMP/out.log ;; - DSL2000) exec $MENCODER -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=128 \ - -oac mp3lame -lameopts preset=15:mode=3 -vf scale=160:104 \ - -o $TMP/out.avi -- - &>$TMP/out.log ;; - DSL3000) exec $MENCODER -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=250 \ - -oac mp3lame -lameopts preset=15:mode=3 -vf scale=320:208 \ - -o $TMP/out.avi -- - &>$TMP/out.log ;; - DSL6000) exec $MENCODER -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=350 \ - -oac mp3lame -lameopts preset=15:mode=3 -vf scale=320:208 \ - -o $TMP/out.avi -- - &>$TMP/out.log ;; - LAN10) exec $MENCODER -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=4096 \ - -oac mp3lame -lameopts preset=standard \ - -o $TMP/out.avi -- - &>$TMP/out.log ;; - WLAN11) exec $MENCODER -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=768 \ - -oac mp3lame -lameopts preset=standard -vf scale=640:408 \ - -o $TMP/out.avi -- - &>$TMP/out.log ;; - WLAN54) exec $MENCODER -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=2048 \ - -oac mp3lame -lameopts preset=standard \ - -o $TMP/out.avi -- - &>$TMP/out.log ;; - IPAQ) exec $MENCODER -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=350 \ - -oac mp3lame -lameopts preset=15:mode=3 -vf scale=320:208 \ - -o $TMP/out.avi -- - &>$TMP/out.log ;; - *) touch $TMP/out.avi ;; -esac diff --git a/streamdev/streamdevhosts.conf b/streamdev/streamdevhosts.conf deleted file mode 100644 index 49882a2..0000000 --- a/streamdev/streamdevhosts.conf +++ /dev/null @@ -1,14 +0,0 @@ -# -# streamdevhosts This file describes a number of host addresses that -# are allowed to connect to the streamdev server running -# with the Video Disk Recorder (VDR) on this system. -# Syntax: -# -# IP-Address[/Netmask] -# - -127.0.0.1 # always accept localhost -#192.168.100.0/24 # any host on the local net -#204.152.189.113 # a specific host -#239.255.0.0/16 # uncomment for IGMP multicast streaming -#0.0.0.0/0 # any host on any net (USE THIS WITH CARE!) diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..60da509 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,34 @@ +# +# Makefile for a Video Disk Recorder plugin +# +# $Id: Makefile,v 1.2 2010/07/19 13:49:44 schmirl Exp $ + +### The object files (add further files here): + +OBJS = select.o socket.o source.o tools.o + +### The main target: + +.PHONY: clean +sockettools.a: $(OBJS) + ar -rcs sockettools.a $(OBJS) + +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< + +### Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies + +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Targets: + +clean: + @-rm -f $(OBJS) $(DEPFILE) *.a core* *~ -- cgit v1.2.3