Snapshot 2010-09-15

This commit is contained in:
Frank Schmirler 2010-12-02 09:57:17 +01:00 committed by Mikko Matilainen
parent 0a860a1e3e
commit 6ea5efe939
53 changed files with 1454 additions and 710 deletions

View File

@ -38,6 +38,7 @@ Rolf Ahrenberg
for suggesting to include the charset in HTTP replies for suggesting to include the charset in HTTP replies
for requesting replacement of asprintf calls for requesting replacement of asprintf calls
for suggesting to change the URL path from EXTERN to EXT for suggesting to change the URL path from EXTERN to EXT
for suggesting increased thread priorities for cStreamdevWriter/Streamer
Rantanen Teemu Rantanen Teemu
for providing vdr-incompletesections.diff for providing vdr-incompletesections.diff
@ -160,6 +161,13 @@ Norman Thiel
vel_tins vel_tins
for reporting that externremux x264 uses value of ABR for VBR for reporting that externremux x264 uses value of ABR for VBR
for various suggestions to improve externremux.sh
Matthias Prill Matthias Prill
for reporting a compiler error with older libstdc++ versions 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

34
HISTORY
View File

@ -1,6 +1,40 @@
VDR Plugin 'streamdev' Revision History 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 - don't use std::map.at(). It's not available in older libstdc++ version
(reported by Matthias Prill) (reported by Matthias Prill)
- fixed extremux x264 using value of ABR for VBR (thanks to vel_tins@vdrportal) - fixed extremux x264 using value of ABR for VBR (thanks to vel_tins@vdrportal)

153
Makefile
View File

@ -1,39 +1,60 @@
# #
# Makefile for a Video Disk Recorder plugin # 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. # The main source file name.
# 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 PLUGIN = streamdev
### The C/C++ compiler and options:
CC ?= gcc
CFLAGS ?= -g -O2 -Wall
CXX ?= g++
CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
### The version number of this plugin (taken from the main source file): ### 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') VERSION = $(shell grep 'const char \*VERSION *=' common.c | awk '{ print $$5 }' | sed -e 's/[";]//g')
### The C++ compiler and options:
CXX ?= g++
CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
### The directory environment: ### The directory environment:
VDRDIR = ../../.. VDRDIR = ../../..
LIBDIR = ../../lib LIBDIR = ../../lib
TMPDIR = /tmp TMPDIR = /tmp
### Allow user defined options to overwrite defaults:
-include $(VDRDIR)/Make.config
### The version number of VDR (taken from VDR's "config.h"): ### 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') 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') 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 }') TSPLAYVERSNUM = $(shell grep 'define TSPLAY_PATCH_VERSION ' $(VDRDIR)/device.h | awk '{ print $$3 }')
### 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
CFLAGS += -fPIC
CXXFLAGS += -fPIC
else
CFLAGS += -fPIC
CXXFLAGS += -fPIC
endif
endif
-include $(VDRDIR)/Make.config
### export all vars for sub-makes, using absolute paths
VDRDIR := $(shell cd $(VDRDIR) >/dev/null 2>&1 && pwd)
LIBDIR := $(shell cd $(LIBDIR) >/dev/null 2>&1 && pwd)
export
unexport PLUGIN
### The name of the distribution archive: ### The name of the distribution archive:
ARCHIVE = $(PLUGIN)-$(VERSION) ARCHIVE = $(PLUGIN)-$(VERSION)
@ -41,102 +62,35 @@ PACKAGE = vdr-$(ARCHIVE)
### Includes and Defines (add further entries here): ### Includes and Defines (add further entries here):
INCLUDES += -I$(VDRDIR)/include -I. INCLUDES += -I$(VDRDIR)/include -I..
DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' DEFINES += -D_GNU_SOURCE
ifeq ($(shell test $(APIVERSNUM) -ge 10704 -o -n "$(TSPLAYVERSNUM)" ; echo $$?),0)
DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
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 ifdef DEBUG
DEFINES += -DDEBUG DEFINES += -DDEBUG
endif endif
ifdef STREAMDEV_DEBUG
DEFINES += -DDEBUG
endif
### The main target: ### The main target:
.PHONY: all i18n dist clean .PHONY: all client server dist clean
all: libvdr-$(PLUGIN)-client.so libvdr-$(PLUGIN)-server.so i18n all: client server
### Implicit rules:
%.o: %.c
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
# Dependencies:
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
-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) $(SERVEROBJS:%.o=%.c) $(COMMONOBJS:%.o=%.c)
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<http://www.vdr-developer.org/mantisbt/>' -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: ### Targets:
libdvbmpeg/libdvbmpegtools.a: libdvbmpeg/*.c libdvbmpeg/*.h client:
$(MAKE) -C ./libdvbmpeg libdvbmpegtools.a $(MAKE) -C ./tools
$(MAKE) -C ./client
# installs to $(LIBDIR)/libvdr-streamdev-client.so.$(APIVERSION)
libvdr-$(PLUGIN)-client.so: $(CLIENTOBJS) $(COMMONOBJS) libdvbmpeg/libdvbmpegtools.a server:
libvdr-$(PLUGIN)-server.so: $(SERVEROBJS) $(COMMONOBJS) libdvbmpeg/libdvbmpegtools.a $(MAKE) -C ./tools
$(MAKE) -C ./libdvbmpeg
%.so: $(MAKE) -C ./remux
$(CXX) $(CXXFLAGS) -shared $^ -o $@ $(MAKE) -C ./server
@cp $@ $(LIBDIR)/$@.$(APIVERSION) # installs to $(LIBDIR)/libvdr-streamdev-server.so.$(APIVERSION)
dist: clean dist: clean
@-rm -rf $(TMPDIR)/$(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE)
@ -147,5 +101,8 @@ dist: clean
@echo Distribution package created as $(PACKAGE).tgz @echo Distribution package created as $(PACKAGE).tgz
clean: clean:
@-rm -f $(COMMONOBJS) $(CLIENTOBJS) $(SERVEROBJS) $(DEPFILE) $(PODIR)/*.mo $(PODIR)/*.pot *.so *.tgz core* *~ $(MAKE) -C ./tools clean
$(MAKE) -C ./libdvbmpeg clean $(MAKE) -C ./libdvbmpeg clean
$(MAKE) -C ./remux clean
$(MAKE) -C ./client clean
$(MAKE) -C ./server clean

174
README
View File

@ -15,9 +15,9 @@ Contents:
1. Description 1. Description
2. Installation 2. Installation
2.1 VDR 1.4.x and older 2.1 Compatibility
2.2 VDR 1.6.0 and above 2.2 Compiling
2.3 Updating from streamdev 0.3.x 2.3 Updating
3. Usage 3. Usage
3.1 Usage HTTP server 3.1 Usage HTTP server
3.2 Usage IGMP multicast server 3.2 Usage IGMP multicast server
@ -27,7 +27,8 @@ Contents:
4.1 Plugins for VDR-to-VDR clients 4.1 Plugins for VDR-to-VDR clients
4.2 Plugins for Server 4.2 Plugins for Server
4.3 Alternatives 4.3 Alternatives
5. Known Problems 5. externremux.sh
6. Known Problems
1. Description: 1. Description:
@ -62,7 +63,7 @@ the PROTOCOL file.
2. Installation: 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 use anything else please exchange the version numbers appropriately (this
way I don't have to update this section all the times;) ). 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 client, you can merge the channels.conf files. VDR will detect if the local
device or the network device can receive the channels. device or the network device can receive the channels.
Last, but not least you have to copy the streamdev folder into the Last, but not least you have to copy the streamdev-server folder into the
"plugins/streamdev" subfolder of VDR's config-directory (which is equal to your "plugins/streamdev-server" subfolder of VDR's config-directory (which is equal
video-directory if not specified otherwise). For example, if you didn't specify to your video-directory if not specified otherwise). For example, if you didn't
a separate config-directory, and specified your video directory as "/video0", specify a separate config-directory, and set your video directory to "/video0",
the directory has to be copied to /video0/plugins/streamdev. the directory has to be copied to /video0/plugins/streamdev-server.
The directory contains a file named streamdevhosts.conf which you must adjust 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 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. 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 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 streamdev's external remux feature. The sample script uses mencoder by default.
check the script for further information. You can specify a different script Please check the script for further information. You can specify a different
location with the -r parameter. The VDR commandline would then include a 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, "-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. 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 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 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. 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 cd vdr-1.X.X/PLUGINS/src
tar xvfz vdr-streamdev-0.4.0.tgz tar xvfz vdr-streamdev-0.5.0.tgz
ln -s streamdev-0.4.0 streamdev ln -s streamdev-0.5.0 streamdev
cp -r streamdev/streamdev VDRCONFDIR/plugins/ cp -r streamdev/streamdev-server VDRCONFDIR/plugins/
cd ../.. cd ../..
make [options, if necessary] vdr make [options, if necessary] vdr
make [options, if necessary] plugins make [options, if necessary] plugins
2.3 Updating from streamdev 0.3.x To build only the plugin, change into the streamdev source folder and issue
---------------------------------- make
Starting with streamdev 0.4.0, all additional files are kept in a directory To build only streamdev-server or only streamdev-client, use
called "streamdev" inside VDR's plugin config directory. It is the new default make server
location of externremux.sh and the new place where streamdev-server expects the make client
file "streamdevhosts.conf". You will have to move this file to its new location:
mv VDRCONFDIR/plugins/streamdevhosts.conf VDRCONFDIR/plugins/streamdev/ 2.3 Updating:
--------------
(Directory VDRCONFDIR/plugins/streamdev already exists, as you copied the If you are updating streamdev from an earlier release, you might have to
whole folder from the sources directory as suggested above, right?) perform some additional steps. Check which version you've been running before,
then read below for the necessary changes.
* Location of files:
--------------------
(Affected: 0.3.x, 0.4.x, 0.4.0pre, 0.5.0pre)
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" 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 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 prevent this (e.g. firewall). You might want to remove this line and enable
HTTP authentication instead. 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: 3. Usage:
--------- ---------
@ -176,7 +209,7 @@ TS Transport Stream (i.e. a dump from the device)
PES Packetized Elemetary Stream (VDR's native recording format) PES Packetized Elemetary Stream (VDR's native recording format)
PS Program Stream (SVCD, DVD like stream) PS Program Stream (SVCD, DVD like stream)
ES Elementary Stream (only Video, if available, otherwise only Audio) ES Elementary Stream (only Video, if available, otherwise only Audio)
EXTERN Pass stream through external script (e.g. for converting with mencoder) 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 Assuming that you leave the default port (3000), point your web browser to
@ -199,16 +232,17 @@ http://hostname:3000/TS/3
http://hostname:3000/PES/S19.2E-0-12480-898 http://hostname:3000/PES/S19.2E-0-12480-898
The first one would deliver the stream in TS, the second one in PES format. 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 the ES format explicitly if you want to listen to radio channels. Play them
back i.e. with mpg123. back i.e. with mpg123.
mpg123 http://hostname:3000/ES/200 mpg123 http://hostname:3000/ES/200
With 'EXTERN' you can also add a parameter which is passed as argument to the With 'EXT' you can also add parameters which are passed as arguments to the
externremux script. 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
http://hostname:3000/EXTERN;some_parameter/3 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 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 access for anyone by allowing any IP in "streamdevhosts.conf". Instead, pass the
@ -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 value than the maximum, you will get two ranges: "up to maximum" and "minimum
and above". 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: 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 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. 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 * 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 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 "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 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 to recompile other plugins. However it is not suitable for clients with a DVB
card of their own. card of their own.

84
client/Makefile Normal file
View File

@ -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='<http://www.vdr-developer.org/mantisbt/>' -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* *~

View File

@ -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" #include "client/device.h"
@ -8,6 +8,7 @@
#include "tools/select.h" #include "tools/select.h"
#include <vdr/config.h>
#include <vdr/channels.h> #include <vdr/channels.h>
#include <vdr/ringbuffer.h> #include <vdr/ringbuffer.h>
#include <vdr/eit.h> #include <vdr/eit.h>
@ -32,6 +33,7 @@ cStreamdevDevice::cStreamdevDevice(void) {
m_Device = this; m_Device = this;
m_Pids = 0; m_Pids = 0;
m_Priority = -1;
m_DvrClosed = true; m_DvrClosed = true;
} }
@ -118,6 +120,9 @@ bool cStreamdevDevice::SetChannelDevice(const cChannel *Channel,
bool LiveView) { bool LiveView) {
Dprintf("SetChannelDevice Channel: %s, LiveView: %s\n", Channel->Name(), Dprintf("SetChannelDevice Channel: %s, LiveView: %s\n", Channel->Name(),
LiveView ? "true" : "false"); LiveView ? "true" : "false");
LOCK_THREAD;
m_UpdatePriority = ClientSocket.SupportsPrio();
if (LiveView) if (LiveView)
return false; return false;
@ -140,6 +145,8 @@ bool cStreamdevDevice::SetPid(cPidHandle *Handle, int Type, bool On) {
Handle->used); Handle->used);
LOCK_THREAD; LOCK_THREAD;
m_UpdatePriority = ClientSocket.SupportsPrio();
if (On && !m_TSBuffer) { if (On && !m_TSBuffer) {
Dprintf("SetPid: no data connection -> OpenDvr()"); Dprintf("SetPid: no data connection -> OpenDvr()");
OpenDvrInt(); OpenDvrInt();
@ -301,3 +308,16 @@ bool cStreamdevDevice::ReInit(void) {
return StreamdevClientSetup.StartClient ? Init() : true; 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();
}
}

View File

@ -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 #ifndef VDR_STREAMDEV_DEVICE_H
@ -15,13 +15,14 @@ class cTBString;
#define CMD_LOCK_OBJ(x) cMutexLock CmdLock((cMutex*)&(x)->m_Mutex) #define CMD_LOCK_OBJ(x) cMutexLock CmdLock((cMutex*)&(x)->m_Mutex)
class cStreamdevDevice: public cDevice { class cStreamdevDevice: public cDevice {
friend class cRemoteRecordings;
private: private:
const cChannel *m_Channel; const cChannel *m_Channel;
cTSBuffer *m_TSBuffer; cTSBuffer *m_TSBuffer;
cStreamdevFilters *m_Filters; cStreamdevFilters *m_Filters;
int m_Pids; int m_Pids;
int m_Priority;
bool m_UpdatePriority;
bool m_DvrClosed; bool m_DvrClosed;
static cStreamdevDevice *m_Device; static cStreamdevDevice *m_Device;
@ -59,6 +60,7 @@ public:
#endif #endif
virtual bool IsTunedToTransponder(const cChannel *Channel); virtual bool IsTunedToTransponder(const cChannel *Channel);
static void UpdatePriority(void);
static bool Init(void); static bool Init(void);
static bool ReInit(void); static bool ReInit(void);

50
client/po/de_DE.po Normal file
View File

@ -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 <vdrdev@schmirler.de>, 2008
#
msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\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 <vdrdev@schmirler.de>\n"
"Language-Team: <vdr@linuxtv.org>\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 "Hauptmenüeintrag 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 Priorität"
msgid "Maximum Priority"
msgstr "Maximale Priorität"

50
client/po/fi_FI.po Normal file
View File

@ -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 <rahrenbe@cc.hut.fi>, 2008
#
msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\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 <rahrenbe@cc.hut.fi>\n"
"Language-Team: <vdr@linuxtv.org>\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 "Pysäytä palvelin"
msgid "Server is suspended"
msgstr "Palvelin on pysäytetty"
msgid "Couldn't suspend Server!"
msgstr "Palvelinta ei onnistuttu pysäyttämään!"
msgid "Hide Mainmenu Entry"
msgstr "Piilota valinta päävalikosta"
msgid "Start Client"
msgstr "Käynnistä VDR-asiakas"
msgid "Remote IP"
msgstr "Etäkoneen IP-osoite"
msgid "Remote Port"
msgstr "Etäkoneen portti"
msgid "Filter Streaming"
msgstr "Suodatetun tiedon suoratoisto"
msgid "Minimum Priority"
msgstr "Pienin prioriteetti"
msgid "Maximum Priority"
msgstr "Suurin prioriteetti"

50
client/po/fr_FR.po Normal file
View File

@ -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 <vdrdev@schmirler.de>, 2008
#
msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2010-06-14 13:05+0200\n"
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
"Last-Translator: micky979 <micky979@free.fr>\n"
"Language-Team: <vdr@linuxtv.org>\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 "Démarrage 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 ""

52
client/po/it_IT.po Normal file
View File

@ -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 <bertocar@tin.it>, 2001
# Antonio Ospite <ospite@studenti.unina.it>, 2003
# Sean Carlos <seanc@libero.it>, 2005
#
msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\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 <vdr-italian@tiscali.it>\n"
"Language-Team: <vdr@linuxtv.org>\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"

50
client/po/lt_LT.po Normal file
View File

@ -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 <vdrdev@schmirler.de>, 2008
#
msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\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 <varas@ambernet.lt>\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"

50
client/po/ru_RU.po Normal file
View File

@ -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 <vdrdev@schmirler.de>, 2008
#
msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\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 <oleg@roitburd.de>\n"
"Language-Team: <vdr@linuxtv.org>\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 ""

52
client/po/sk_SK.po Normal file
View File

@ -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 <hrala.milan@gmail.com>, 2009
#
msgid ""
msgstr ""
"Project-Id-Version: streamdev_SK\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2010-06-14 13:05+0200\n"
"PO-Revision-Date: \n"
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
"Language-Team: Slovak <hrala.milan@gmail.com>\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 prúdový klient"
msgid "Suspend Server"
msgstr "Server pozastavený"
msgid "Server is suspended"
msgstr "Server je doèasne preru¹ený"
msgid "Couldn't suspend Server!"
msgstr "Nepodarilo sa pozastavi» Server!"
msgid "Hide Mainmenu Entry"
msgstr "Schova» polo¾ku 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» prúdy"
msgid "Minimum Priority"
msgstr "minimálna priorita"
msgid "Maximum Priority"
msgstr "maximálna priorita"

View File

@ -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 <tools/select.h> #include <tools/select.h>
@ -20,6 +20,7 @@ cClientSocket ClientSocket;
cClientSocket::cClientSocket(void) cClientSocket::cClientSocket(void)
{ {
memset(m_DataSockets, 0, sizeof(cTBSocket*) * si_Count); memset(m_DataSockets, 0, sizeof(cTBSocket*) * si_Count);
m_Prio = false;
Reset(); Reset();
} }
@ -142,8 +143,14 @@ bool cClientSocket::CheckConnection(void) {
if(Command("CAPS FILTERS", 220)) if(Command("CAPS FILTERS", 220))
Filters = ",FILTERS"; Filters = ",FILTERS";
isyslog("Streamdev: Connected to server %s:%d using capabilities TSPIDS%s", const char *Prio = "";
RemoteIp().c_str(), RemotePort(), Filters); 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; return true;
} }
@ -251,6 +258,21 @@ bool cClientSocket::SetChannelDevice(const cChannel *Channel) {
return true; 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) { bool cClientSocket::SetPid(int Pid, bool On) {
if (!CheckConnection()) return false; 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); std::string command = (std::string)(On ? "ADDP " : "DELP ") + (const char*)itoa(Pid);
if (!Command(command, 220)) { if (!Command(command, 220)) {
if (errno == 0) if (errno == 0)
esyslog("Streamdev: Pid %d not available from %s:%d", Pid, LocalIp().c_str(), esyslog("Streamdev: Pid %d not available from %s:%d", Pid, RemoteIp().c_str(),
LocalPort()); RemotePort());
return false; return false;
} }
return true; return true;
@ -276,7 +298,7 @@ bool cClientSocket::SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On) {
if (!Command(command, 220)) { if (!Command(command, 220)) {
if (errno == 0) if (errno == 0)
esyslog("Streamdev: Filter %hu, %hhu, %hhu not available from %s:%d", 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 false;
} }
return true; return true;

View File

@ -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 #ifndef VDR_STREAMDEV_CLIENT_CONNECTION_H
@ -20,6 +20,7 @@ private:
cTBSocket *m_DataSockets[si_Count]; cTBSocket *m_DataSockets[si_Count];
cMutex m_Mutex; cMutex m_Mutex;
char m_Buffer[BUFSIZ + 1]; // various uses char m_Buffer[BUFSIZ + 1]; // various uses
bool m_Prio; // server supports command PRIO
protected: protected:
/* Send Command, and return true if the command results in Expected. /* Send Command, and return true if the command results in Expected.
@ -45,6 +46,8 @@ public:
bool CreateDataConnection(eSocketId Id); bool CreateDataConnection(eSocketId Id);
bool CloseDataConnection(eSocketId Id); bool CloseDataConnection(eSocketId Id);
bool SetChannelDevice(const cChannel *Channel); bool SetChannelDevice(const cChannel *Channel);
bool SupportsPrio() { return m_Prio; }
bool SetPriority(int Priority);
bool SetPid(int Pid, bool On); bool SetPid(int Pid, bool On);
bool SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On); bool SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On);
bool CloseDvr(void); bool CloseDvr(void);

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * 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 $ * $Id: streamdev-client.c,v 1.3 2010/08/18 10:26:56 schmirl Exp $
*/ */
#include "streamdev-client.h" #include "streamdev-client.h"
@ -52,4 +52,8 @@ bool cPluginStreamdevClient::SetupParse(const char *Name, const char *Value) {
return StreamdevClientSetup.SetupParse(Name, Value); return StreamdevClientSetup.SetupParse(Name, Value);
} }
void cPluginStreamdevClient::MainThreadHook(void) {
cStreamdevDevice::UpdatePriority();
}
VDRPLUGINCREATOR(cPluginStreamdevClient); // Don't touch this! VDRPLUGINCREATOR(cPluginStreamdevClient); // Don't touch this!

View File

@ -1,5 +1,5 @@
/* /*
* $Id: streamdev-client.h,v 1.2 2010/06/08 05:55:16 schmirl Exp $ * $Id: streamdev-client.h,v 1.3 2010/08/18 10:26:56 schmirl Exp $
*/ */
#ifndef VDR_STREAMDEVCLIENT_H #ifndef VDR_STREAMDEVCLIENT_H
@ -23,6 +23,7 @@ public:
virtual cOsdObject *MainMenuAction(void); virtual cOsdObject *MainMenuAction(void);
virtual cMenuSetupPage *SetupMenu(void); virtual cMenuSetupPage *SetupMenu(void);
virtual bool SetupParse(const char *Name, const char *Value); virtual bool SetupParse(const char *Name, const char *Value);
virtual void MainThreadHook(void);
}; };
#endif // VDR_STREAMDEVCLIENT_H #endif // VDR_STREAMDEVCLIENT_H

View File

@ -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 <vdr/channels.h> #include <vdr/channels.h>
@ -10,7 +10,7 @@
using namespace std; using namespace std;
const char *VERSION = "0.5.0-pre"; const char *VERSION = "0.5.0-CVS";
const char cMenuEditIpItem::IpCharacters[] = "0123456789."; const char cMenuEditIpItem::IpCharacters[] = "0123456789.";

View File

@ -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 #ifndef VDR_STREAMDEV_COMMON_H
@ -37,7 +37,7 @@ enum eStreamType {
stPES, stPES,
stPS, stPS,
stES, stES,
stExtern, stEXT,
stTSPIDS, stTSPIDS,
st_Count st_Count
}; };

View File

@ -1,25 +1,38 @@
INCS = -I. #
CFLAGS = -g -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -fPIC # Makefile for a Video Disk Recorder plugin
MFLAG = -M #
OBJS = ctools.o ringbuffy.o remux.o transform.o # $Id: Makefile,v 1.5 2010/07/30 10:49:28 schmirl Exp $
SRC = $(wildcard *.c)
DESTDIR = /usr/local ### The object files (add further files here):
OBJS = ctools.o remux.o ringbuffy.o transform.o
### Disable attribute warn_unused_result
DEFINES += -U_FORTIFY_SOURCE
### The main target:
.PHONY: clean .PHONY: clean
clean:
- rm -f *.o *~ *.a .depend
libdvbmpegtools.a: $(OBJS) libdvbmpegtools.a: $(OBJS)
ar -rcs libdvbmpegtools.a $(OBJS) ar -rcs libdvbmpegtools.a $(OBJS)
### Implicit rules:
%.o: %.c %.o: %.c
$(CC) -c $(CFLAGS) $(INCS) $(DEFINES) $< $(CC) $(CFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
.depend: ### Dependencies:
$(CXX) $(DEFINES) $(MFLAG) $(SRC) $(INCS)> .depend
MAKEDEP = $(CC) -MM -MG
DEPFILE = .dependencies
$(DEPFILE): Makefile
@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
-include .depend -include $(DEPFILE)
### Targets:
clean:
@-rm -f $(OBJS) $(DEPFILE) *.a core* *~

34
remux/Makefile Normal file
View File

@ -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* *~

View File

@ -191,6 +191,11 @@ cTSExt::cTSExt(cRingBufferLinear *ResultBuffer, const cServerConnection *Connect
if (setpgid(0, 0) == -1) if (setpgid(0, 0) == -1)
esyslog("streamdev-server: externremux setpgid failed: %m"); 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) { if (execle("/bin/sh", "sh", "-c", opt_remux, NULL, env) == -1) {
esyslog("streamdev-server: externremux script '%s' execution failed: %m", opt_remux); esyslog("streamdev-server: externremux script '%s' execution failed: %m", opt_remux);
_exit(-1); _exit(-1);

View File

@ -5,6 +5,9 @@
#include <vdr/ringbuffer.h> #include <vdr/ringbuffer.h>
#include <string> #include <string>
class cChannel;
class cServerConnection;
namespace Streamdev { namespace Streamdev {
class cTSExt; class cTSExt;
@ -15,7 +18,7 @@ private:
cTSExt *m_Remux; cTSExt *m_Remux;
public: 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(); virtual ~cExternRemux();
int Put(const uchar *Data, int Count); int Put(const uchar *Data, int Count);

82
server/Makefile Normal file
View File

@ -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='<http://www.vdr-developer.org/mantisbt/>' -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* *~

View File

@ -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" #include "server/connection.h"
@ -8,6 +8,7 @@
#include "common.h" #include "common.h"
#include <vdr/tools.h> #include <vdr/tools.h>
#include <vdr/transfer.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <errno.h> #include <errno.h>
@ -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; const cChannel *channel = NULL;
char *string = strdup(String); char *string = strdup(String);
char *ptr, *end; char *ptr, *end;
@ -58,7 +59,8 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
} }
if (channel != NULL && apididx > 0) { 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) { for (int i = 0; channel->Apid(i) != 0; ++i, ++index) {
if (index == apididx) { if (index == apididx) {
@ -70,7 +72,7 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
if (apid == 0) { if (apid == 0) {
for (int i = 0; channel->Dpid(i) != 0; ++i, ++index) { for (int i = 0; channel->Dpid(i) != 0; ++i, ++index) {
if (index == apididx) { if (index == apididx) {
apid = channel->Dpid(i); dpid = channel->Dpid(i);
break; break;
} }
} }
@ -78,6 +80,8 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
if (Apid != NULL) if (Apid != NULL)
*Apid = apid; *Apid = apid;
if (Dpid != NULL)
*Dpid = dpid;
} }
free(string); free(string);
@ -182,74 +186,171 @@ bool cServerConnection::Respond(const char *Message, bool Last, ...)
return true; 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 *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()
&& !cSuspendCtl::IsActive()
&& StreamdevServerSetup.SuspendMode != smAlways)) {
// 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()); const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel());
isyslog("streamdev-server: Detaching current receiver");
// turn off the streams of this connection
Detach(); Detach();
device = cDevice::GetDevice(Channel, Priority, false); // 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
&& 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(); Attach();
Dprintf(" * Found following device: %p (%d)\n", device, dsyslog("streamdev: GetDevice failed for channel %s at priority %d", Channel->Name(), Priority);
device ? device->CardIndex() + 1 : 0); }
if (device == cDevice::ActualDevice()) return device;
Dprintf(" * is actual device\n"); }
if (!cSuspendCtl::IsActive()
&& StreamdevServerSetup.SuspendMode != smAlways) bool cServerConnection::ProvidesChannel(const cChannel *Channel, int Priority)
Dprintf(" * NOT suspended\n"); {
if (current && !TRANSPONDER(Channel, current)) const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel());
Dprintf(" * NOT same transponder\n");
if (device && (device == cDevice::ActualDevice() cDevice *device = CheckDevice(Channel, Priority, false);
if (!device || (device == cDevice::ActualDevice()
&& !cSuspendCtl::IsActive() && !cSuspendCtl::IsActive()
&& StreamdevServerSetup.SuspendMode != smAlways && StreamdevServerSetup.SuspendMode != smAlways
&& current != NULL && current != NULL
&& !TRANSPONDER(Channel, current))) { && !TRANSPONDER(Channel, current))) {
// mustn't switch actual device
// maybe a device would be free if THIS connection did turn off its streams?
Detach();
device = CheckDevice(Channel, Priority, false);
Attach();
if (device && device == cDevice::ActualDevice()
&& !cSuspendCtl::IsActive()
&& StreamdevServerSetup.SuspendMode != smAlways
&& current != NULL
&& !TRANSPONDER(Channel, current)) {
// now we would have to switch away live tv...let's see if live tv // now we would have to switch away live tv...let's see if live tv
// can be handled by another device // can be handled by another device
cDevice *newdev = NULL; cDevice *newdev = CheckDevice(current, 0, true, device);
for (int i = 0; i < cDevice::NumDevices(); ++i) { if (!newdev) {
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...
device = NULL; device = NULL;
else dsyslog("streamdev: Not providing channel %s at priority %d - live TV not suspended", Channel->Name(), Priority);
newdev->SwitchChannel(current, true);
} }
} }
else if (!device)
dsyslog("streamdev: No device provides channel %s at priority %d", Channel->Name(), Priority);
}
return device; return device;
} }

View File

@ -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 #ifndef VDR_STREAMDEV_SERVER_CONNECTION_H
@ -8,6 +8,11 @@
#include "tools/socket.h" #include "tools/socket.h"
#include "common.h" #include "common.h"
#include <map>
typedef std::map<std::string,std::string> tStrStrMap;
typedef std::pair<std::string,std::string> tStrStr;
class cChannel; class cChannel;
class cDevice; class cDevice;
@ -28,6 +33,13 @@ private:
uint m_WriteBytes; uint m_WriteBytes;
uint m_WriteIndex; 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: protected:
/* Will be called when a command terminated by a newline has been /* Will be called when a command terminated by a newline has been
received */ received */
@ -41,7 +53,10 @@ protected:
virtual bool Respond(const char *Message, bool Last = true, ...); virtual bool Respond(const char *Message, bool Last = true, ...);
//__attribute__ ((format (printf, 2, 4))); //__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: public:
/* If you derive, specify a short string such as HTTP for Protocol, which /* 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 */ /* Will make the socket close after sending all queued output data */
void DeferClose(void) { m_DeferClose = true; } 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 in a following call to StartTransfer */
cDevice *GetDevice(const cChannel *Channel, int Priority); 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 Flushed(void) {}
virtual void Detach(void) = 0; virtual void Detach(void) = 0;
virtual void Attach(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 inline bool cServerConnection::HasData(void) const

View File

@ -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 <ctype.h> #include <ctype.h>
@ -149,7 +149,9 @@ bool cConnectionHTTP::ProcessRequest(void)
if (m_ChannelList) if (m_ChannelList)
return Respond("%s", true, m_ChannelList->HttpHeader().c_str()); return Respond("%s", true, m_ChannelList->HttpHeader().c_str());
else if (m_Channel != NULL) { 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) { if (device != NULL) {
device->SwitchChannel(m_Channel, false); device->SwitchChannel(m_Channel, false);
m_LiveStreamer = new cStreamdevLiveStreamer(0, this); m_LiveStreamer = new cStreamdevLiveStreamer(0, this);
@ -186,8 +188,7 @@ bool cConnectionHTTP::ProcessRequest(void)
if (m_ChannelList) if (m_ChannelList)
return Respond("%s", true, m_ChannelList->HttpHeader().c_str()); return Respond("%s", true, m_ChannelList->HttpHeader().c_str());
else if (m_Channel != NULL) { else if (m_Channel != NULL) {
cDevice *device = GetDevice(m_Channel, 0); if (ProvidesChannel(m_Channel, 0)) {
if (device != NULL) {
if (m_StreamType == stEXT) { if (m_StreamType == stEXT) {
// TODO // TODO
return Respond("HTTP/1.0 200 OK") return Respond("HTTP/1.0 200 OK")

View File

@ -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 #ifndef VDR_STREAMDEV_SERVERS_CONNECTIONHTTP_H
@ -8,6 +8,7 @@
#include "connection.h" #include "connection.h"
#include "server/livestreamer.h" #include "server/livestreamer.h"
#include <map>
#include <tools/select.h> #include <tools/select.h>
class cChannel; class cChannel;
@ -23,26 +24,19 @@ private:
hsFinished, hsFinished,
}; };
enum eHTTPJob {
hjTransfer,
hjListing,
};
std::string m_Request;
std::string m_Host;
std::string m_Authorization; std::string m_Authorization;
//std::map<std::string,std::string> m_Headers; TODO: later?
eHTTPStatus m_Status; eHTTPStatus m_Status;
eHTTPJob m_Job;
// job: transfer // job: transfer
cStreamdevLiveStreamer *m_LiveStreamer; cStreamdevLiveStreamer *m_LiveStreamer;
std::string m_StreamerParameter;
const cChannel *m_Channel; const cChannel *m_Channel;
int m_Apid; int m_Apid[2];
int m_Dpid[2];
eStreamType m_StreamType; eStreamType m_StreamType;
// job: listing // job: listing
cChannelList *m_ChannelList; 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: protected:
bool ProcessRequest(void); bool ProcessRequest(void);
@ -56,7 +50,6 @@ public:
virtual bool CanAuthenticate(void); virtual bool CanAuthenticate(void);
virtual bool Command(char *Cmd); virtual bool Command(char *Cmd);
bool CmdGET(const std::string &Opts);
virtual bool Abort(void) const; virtual bool Abort(void) const;
virtual void Flushed(void); virtual void Flushed(void);

View File

@ -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 <ctype.h> #include <ctype.h>
@ -25,13 +25,15 @@ cConnectionIGMP::~cConnectionIGMP()
bool cConnectionIGMP::Start(cChannel *Channel, in_addr_t Dst) bool cConnectionIGMP::Start(cChannel *Channel, in_addr_t Dst)
{ {
if (Channel != NULL) { if (Channel != NULL) {
cDevice *device = GetDevice(Channel, 0); cDevice *device = NULL;
if (ProvidesChannel(Channel, 0))
device = GetDevice(Channel, 0);
if (device != NULL) { if (device != NULL) {
device->SwitchChannel(Channel, false); device->SwitchChannel(Channel, false);
struct in_addr ip; struct in_addr ip;
ip.s_addr = Dst; ip.s_addr = Dst;
if (Connect(inet_ntoa(ip), m_ClientPort)) { 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)) { if (m_LiveStreamer->SetChannel(Channel, m_StreamType)) {
m_LiveStreamer->SetDevice(device); m_LiveStreamer->SetDevice(device);
if (!SetDSCP()) if (!SetDSCP())

View File

@ -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" #include "server/connectionVTP.h"
@ -746,6 +746,8 @@ cConnectionVTP::cConnectionVTP(void):
m_StreamType(stTSPIDS), m_StreamType(stTSPIDS),
m_FiltersSupport(false), m_FiltersSupport(false),
m_RecPlayer(NULL), m_RecPlayer(NULL),
m_TuneChannel(NULL),
m_TunePriority(0),
m_LSTEHandler(NULL), m_LSTEHandler(NULL),
m_LSTCHandler(NULL), m_LSTCHandler(NULL),
m_LSTTHandler(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, "READ") == 0) return CmdREAD(param);
else if (strcasecmp(Cmd, "TUNE") == 0) return CmdTUNE(param); else if (strcasecmp(Cmd, "TUNE") == 0) return CmdTUNE(param);
else if (strcasecmp(Cmd, "PLAY") == 0) return CmdPLAY(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, "ADDP") == 0) return CmdADDP(param);
else if (strcasecmp(Cmd, "DELP") == 0) return CmdDELP(param); else if (strcasecmp(Cmd, "DELP") == 0) return CmdDELP(param);
else if (strcasecmp(Cmd, "ADDF") == 0) return CmdADDF(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); return Respond(220, "Capability \"%s\" accepted", Opts);
} }
if (strcasecmp(Opts, "EXTERN") == 0) { if (strcasecmp(Opts, "EXT") == 0) {
m_StreamType = stExtern; m_StreamType = stEXT;
return Respond(220, "Capability \"%s\" accepted", Opts); return Respond(220, "Capability \"%s\" accepted", Opts);
} }
@ -894,6 +897,11 @@ bool cConnectionVTP::CmdCAPS(char *Opts)
return Respond(220, "Capability \"%s\" accepted", 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); return Respond(561, "Capability \"%s\" not known", Opts);
} }
@ -911,9 +919,15 @@ bool cConnectionVTP::CmdPROV(char *Opts)
if ((chan = ChannelFromString(Opts)) == NULL) if ((chan = ChannelFromString(Opts)) == NULL)
return Respond(550, "Undefined channel \"%s\"", Opts); return Respond(550, "Undefined channel \"%s\"", Opts);
return GetDevice(chan, prio) != NULL if (ProvidesChannel(chan, prio)) {
? Respond(220, "Channel available") m_TuneChannel = chan;
: Respond(560, "Channel not available"); m_TunePriority = prio;
return Respond(220, "Channel available");
}
else {
m_TuneChannel = NULL;
return Respond(560, "Channel not available");
}
} }
bool cConnectionVTP::CmdPORT(char *Opts) bool cConnectionVTP::CmdPORT(char *Opts)
@ -1067,18 +1081,23 @@ bool cConnectionVTP::CmdTUNE(char *Opts)
{ {
const cChannel *chan; const cChannel *chan;
cDevice *dev; cDevice *dev;
int prio = m_TunePriority;
if ((chan = ChannelFromString(Opts)) == NULL) if ((chan = ChannelFromString(Opts)) == NULL)
return Respond(550, "Undefined channel \"%s\"", Opts); 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"); return Respond(560, "Channel not available");
if (!dev->SwitchChannel(chan, false)) if (!dev->SwitchChannel(chan, false))
return Respond(560, "Channel not available"); return Respond(560, "Channel not available");
delete m_LiveStreamer; delete m_LiveStreamer;
m_LiveStreamer = new cStreamdevLiveStreamer(1); m_LiveStreamer = new cStreamdevLiveStreamer(prio, this);
m_LiveStreamer->SetChannel(chan, m_StreamType); m_LiveStreamer->SetChannel(chan, m_StreamType);
m_LiveStreamer->SetDevice(dev); m_LiveStreamer->SetDevice(dev);
if(m_LiveSocket) 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) bool cConnectionVTP::CmdADDP(char *Opts)
{ {
int pid; int pid;
@ -1243,6 +1278,7 @@ bool cConnectionVTP::CmdSUSP(void)
else if (StreamdevServerSetup.SuspendMode == smOffer else if (StreamdevServerSetup.SuspendMode == smOffer
&& StreamdevServerSetup.AllowSuspend) { && StreamdevServerSetup.AllowSuspend) {
cControl::Launch(new cSuspendCtl); cControl::Launch(new cSuspendCtl);
cControl::Attach();
return Respond(220, "Server is suspended"); return Respond(220, "Server is suspended");
} else } else
return Respond(550, "Client may not suspend server"); return Respond(550, "Client may not suspend server");

View File

@ -31,6 +31,11 @@ private:
bool m_FiltersSupport; bool m_FiltersSupport;
RecPlayer *m_RecPlayer; 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 // Members adopted for SVDRP
cLSTEHandler *m_LSTEHandler; cLSTEHandler *m_LSTEHandler;
cLSTCHandler *m_LSTCHandler; cLSTCHandler *m_LSTCHandler;
@ -59,6 +64,7 @@ public:
bool CmdREAD(char *Opts); bool CmdREAD(char *Opts);
bool CmdTUNE(char *Opts); bool CmdTUNE(char *Opts);
bool CmdPLAY(char *Opts); bool CmdPLAY(char *Opts);
bool CmdPRIO(char *Opts);
bool CmdADDP(char *Opts); bool CmdADDP(char *Opts);
bool CmdDELP(char *Opts); bool CmdDELP(char *Opts);
bool CmdADDF(char *Opts); bool CmdADDF(char *Opts);

View File

@ -289,7 +289,7 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
if (written != TS_SIZE) if (written != TS_SIZE)
siBuffer.ReportOverflow(TS_SIZE - written); siBuffer.ReportOverflow(TS_SIZE - written);
if (pmtPid != prevPmtPid) { if (pmtPid != prevPmtPid) {
m_Streamer->SetPids(pmtPid); m_Streamer->SetPid(pmtPid, true);
Add(pmtPid, 0x02); Add(pmtPid, 0x02);
pmtVersion = -1; pmtVersion = -1;
} }
@ -335,10 +335,9 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
// --- cStreamdevLiveStreamer ------------------------------------------------- // --- cStreamdevLiveStreamer -------------------------------------------------
cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority, std::string Parameter): cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority, const cServerConnection *Connection):
cStreamdevStreamer("streamdev-livestreaming"), cStreamdevStreamer("streamdev-livestreaming", Connection),
m_Priority(Priority), m_Priority(Priority),
m_Parameter(Parameter),
m_NumPids(0), m_NumPids(0),
m_StreamType(stTSPIDS), m_StreamType(stTSPIDS),
m_Channel(NULL), m_Channel(NULL),
@ -435,53 +434,58 @@ bool cStreamdevLiveStreamer::SetPids(int Pid, const int *Pids1, const int *Pids2
return true; return true;
} }
void cStreamdevLiveStreamer::StartReceiver(void) void cStreamdevLiveStreamer::SetPriority(int Priority)
{ {
DELETENULL(m_Receiver); m_Priority = Priority;
if (m_NumPids > 0) { StartReceiver();
Dprintf("Creating Receiver to respect changed pids\n");
m_Receiver = new cStreamdevLiveReceiver(this, m_Channel->GetChannelID(), m_Priority, m_Pids);
if (IsRunning() && m_Device != NULL) {
Dprintf("Attaching new receiver\n");
Attach();
}
}
} }
bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid) void cStreamdevLiveStreamer::StartReceiver(void)
{
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);
cThreadLock ThreadLock(m_Device);
Attach();
delete current;
}
else
DELETENULL(m_Receiver);
}
bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, const int* Apid, const int *Dpid)
{ {
Dprintf("Initializing Remuxer for full channel transfer\n"); Dprintf("Initializing Remuxer for full channel transfer\n");
//printf("ca pid: %d\n", Channel->Ca()); //printf("ca pid: %d\n", Channel->Ca());
m_Channel = Channel; m_Channel = Channel;
m_StreamType = StreamType; m_StreamType = StreamType;
int apid[2] = { Apid, 0 }; const int *Apids = Apid ? Apid : m_Channel->Apids();
const int *Apids = Apid ? apid : m_Channel->Apids(); const int *Dpids = Dpid ? Dpid : m_Channel->Dpids();
const int *Dpids = Apid ? NULL : m_Channel->Dpids();
switch (m_StreamType) { switch (m_StreamType) {
case stES: case stES:
{ {
int pid = ISRADIO(m_Channel) ? m_Channel->Apid(0) : m_Channel->Vpid(); int pid = ISRADIO(m_Channel) ? m_Channel->Apid(0) : m_Channel->Vpid();
if (Apid != 0) if (Apid && Apid[0])
pid = Apid; pid = Apid[0];
else if (Dpid && Dpid[0])
pid = Dpid[0];
m_Remux = new cTS2ESRemux(pid); m_Remux = new cTS2ESRemux(pid);
return SetPids(pid); return SetPids(pid);
} }
case stPES: case stPES:
m_Remux = new cTS2PESRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(), m_Remux = new cTS2PESRemux(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
m_Channel->Spids());
return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids()); return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
case stPS: case stPS:
m_Remux = new cTS2PSRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(), m_Remux = new cTS2PSRemux(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
m_Channel->Spids());
return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids()); return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
case stExtern: case stEXT:
m_Remux = new cExternRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(), m_Remux = new cExternRemux(Connection(), m_Channel, Apids, Dpids);
m_Channel->Spids(), m_Parameter);
// fall through // fall through
case stTS: case stTS:
// This should never happen, but ... // This should never happen, but ...
@ -634,13 +638,11 @@ void cStreamdevFilterStreamer::SetDevice(cDevice *Device)
{ {
Dprintf("cStreamdevFilterStreamer::SetDevice()\n"); Dprintf("cStreamdevFilterStreamer::SetDevice()\n");
LOCK_THREAD; LOCK_THREAD;
if(Device != m_Device) {
Detach(); Detach();
m_Device = Device; m_Device = Device;
//m_Channel = NULL; //m_Channel = NULL;
Attach(); Attach();
} }
}
bool cStreamdevFilterStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On) bool cStreamdevFilterStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On)
{ {

View File

@ -18,7 +18,6 @@ class cStreamdevLiveReceiver;
class cStreamdevLiveStreamer: public cStreamdevStreamer { class cStreamdevLiveStreamer: public cStreamdevStreamer {
private: private:
int m_Priority; int m_Priority;
std::string m_Parameter;
int m_Pids[MAXRECEIVEPIDS + 1]; int m_Pids[MAXRECEIVEPIDS + 1];
int m_NumPids; int m_NumPids;
eStreamType m_StreamType; eStreamType m_StreamType;
@ -32,13 +31,14 @@ private:
bool HasPid(int Pid); bool HasPid(int Pid);
public: public:
cStreamdevLiveStreamer(int Priority, std::string Parameter = ""); cStreamdevLiveStreamer(int Priority, const cServerConnection *Connection);
virtual ~cStreamdevLiveStreamer(); virtual ~cStreamdevLiveStreamer();
void SetDevice(cDevice *Device) { m_Device = Device; } void SetDevice(cDevice *Device) { m_Device = Device; }
bool SetPid(int Pid, bool On); bool SetPid(int Pid, bool On);
bool SetPids(int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL); 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 int Put(const uchar *Data, int Count);
virtual uchar *Get(int &Count); virtual uchar *Get(int &Count);

View File

@ -2,7 +2,7 @@
#include "server/menuHTTP.h" #include "server/menuHTTP.h"
//**************************** cChannelIterator ************** //**************************** cChannelIterator **************
cChannelIterator::cChannelIterator(cChannel *First): channel(First) cChannelIterator::cChannelIterator(const cChannel *First): channel(First)
{} {}
const cChannel* cChannelIterator::Next() const cChannel* cChannelIterator::Next()
@ -19,7 +19,7 @@ cListAll::cListAll(): cChannelIterator(Channels.First())
const cChannel* cListAll::NextChannel(const cChannel *Channel) const cChannel* cListAll::NextChannel(const cChannel *Channel)
{ {
if (Channel) if (Channel)
Channel = Channels.Next(Channel); Channel = SkipFakeGroups(Channels.Next(Channel));
return Channel; return Channel;
} }
@ -46,14 +46,19 @@ const cChannel* cListGroups::NextChannel(const cChannel *Channel)
} }
// //
// ********************* cListGroup **************** // ********************* 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::GetNextChannelInGroup(const cChannel *Channel)
{
if (Channel)
Channel = SkipFakeGroups(Channels.Next(Channel));
return Channel && !Channel->GroupSep() ? Channel : NULL;
}
const cChannel* cListGroup::NextChannel(const cChannel *Channel) const cChannel* cListGroup::NextChannel(const cChannel *Channel)
{ {
if (Channel) return GetNextChannelInGroup(Channel);
Channel = Channels.Next(Channel);
return (Channel && !Channel->GroupSep()) ? Channel : NULL;
} }
// //
// ********************* cListTree **************** // ********************* cListTree ****************
@ -68,7 +73,7 @@ const cChannel* cListTree::NextChannel(const cChannel *Channel)
if (currentGroup == selectedGroup) if (currentGroup == selectedGroup)
{ {
if (Channel) if (Channel)
Channel = Channels.Next(Channel); Channel = SkipFakeGroups(Channels.Next(Channel));
if (Channel && Channel->GroupSep()) if (Channel && Channel->GroupSep())
currentGroup = Channel; currentGroup = Channel;
} }
@ -205,8 +210,8 @@ std::string cHtmlChannelList::StreamTypeMenu()
(std::string) "[<a href=\"/PES/" + self + "\">PES</a>] "); (std::string) "[<a href=\"/PES/" + self + "\">PES</a>] ");
typeMenu += (streamType == stES ? (std::string) "[ES] " : typeMenu += (streamType == stES ? (std::string) "[ES] " :
(std::string) "[<a href=\"/ES/" + self + "\">ES</a>] "); (std::string) "[<a href=\"/ES/" + self + "\">ES</a>] ");
typeMenu += (streamType == stExtern ? (std::string) "[Extern] " : typeMenu += (streamType == stEXT ? (std::string) "[EXT] " :
(std::string) "[<a href=\"/Extern/" + self + "\">Extern</a>] "); (std::string) "[<a href=\"/EXT/" + self + "\">EXT</a>] ");
return typeMenu; return typeMenu;
} }

View File

@ -13,9 +13,10 @@ class cChannelIterator
const cChannel *channel; const cChannel *channel;
protected: protected:
virtual const cChannel* NextChannel(const cChannel *Channel) = 0; virtual const cChannel* NextChannel(const cChannel *Channel) = 0;
static inline const cChannel* SkipFakeGroups(const cChannel *Channel);
public: public:
const cChannel* Next(); const cChannel* Next();
cChannelIterator(cChannel *First); cChannelIterator(const cChannel *First);
virtual ~cChannelIterator() {}; virtual ~cChannelIterator() {};
}; };
@ -48,6 +49,8 @@ class cListGroups: public cChannelIterator
class cListGroup: public cChannelIterator class cListGroup: public cChannelIterator
{ {
private:
static const cChannel* GetNextChannelInGroup(const cChannel *Channel);
protected: protected:
virtual const cChannel* NextChannel(const cChannel *Channel); virtual const cChannel* NextChannel(const cChannel *Channel);
public: public:
@ -140,4 +143,11 @@ class cM3uChannelList: public cChannelList
virtual ~cM3uChannelList(); virtual ~cM3uChannelList();
}; };
inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group)
{
while (Group && Group->GroupSep() && !*Group->Name())
Group = Channels.Next(Group);
return Group;
}
#endif #endif

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: streamdev 0.5.0\n" "Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n" "Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2009-02-13 11:53+0100\n" "POT-Creation-Date: 2010-06-14 13:06+0200\n"
"PO-Revision-Date: 2008-03-30 02:11+0200\n" "PO-Revision-Date: 2008-03-30 02:11+0200\n"
"Last-Translator: Frank Schmirler <vdrdev@schmirler.de>\n" "Last-Translator: Frank Schmirler <vdrdev@schmirler.de>\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: <vdr@linuxtv.org>\n"
@ -15,39 +15,6 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8bit\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 "Hauptmenüeintrag 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 Priorität"
msgid "Maximum Priority"
msgstr "Maximale Priorität"
msgid "VDR Streaming Server" msgid "VDR Streaming Server"
msgstr "VDR Streaming Server" msgstr "VDR Streaming Server"
@ -57,6 +24,15 @@ msgstr "Streamen im Gange"
msgid "Suspend Live TV" msgid "Suspend Live TV"
msgstr "Live-TV pausieren" 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" msgid "Common Settings"
msgstr "Allgemeines" msgstr "Allgemeines"
@ -105,11 +81,3 @@ msgstr "Port des Multicast Clients"
msgid "Multicast Streamtype" msgid "Multicast Streamtype"
msgstr "Multicast Streamtyp" msgstr "Multicast Streamtyp"
msgid "Offer suspend mode"
msgstr "Pausieren anbieten"
msgid "Always suspended"
msgstr "Immer pausiert"
msgid "Never suspended"
msgstr "Nie pausiert"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: streamdev 0.5.0\n" "Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n" "Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2009-02-13 11:53+0100\n" "POT-Creation-Date: 2010-06-14 13:06+0200\n"
"PO-Revision-Date: 2008-03-30 02:11+0200\n" "PO-Revision-Date: 2008-03-30 02:11+0200\n"
"Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n" "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: <vdr@linuxtv.org>\n"
@ -15,39 +15,6 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
msgid "VTP Streaming Client"
msgstr "VTP-suoratoistoasiakas"
msgid "Suspend Server"
msgstr "Pysäytä palvelin"
msgid "Server is suspended"
msgstr "Palvelin on pysäytetty"
msgid "Couldn't suspend Server!"
msgstr "Palvelinta ei onnistuttu pysäyttämään!"
msgid "Hide Mainmenu Entry"
msgstr "Piilota valinta päävalikosta"
msgid "Start Client"
msgstr "Käynnistä VDR-asiakas"
msgid "Remote IP"
msgstr "Etäkoneen IP-osoite"
msgid "Remote Port"
msgstr "Etäkoneen portti"
msgid "Filter Streaming"
msgstr "Suodatetun tiedon suoratoisto"
msgid "Minimum Priority"
msgstr "Pienin prioriteetti"
msgid "Maximum Priority"
msgstr "Suurin prioriteetti"
msgid "VDR Streaming Server" msgid "VDR Streaming Server"
msgstr "VDR-suoratoistopalvelin" msgstr "VDR-suoratoistopalvelin"
@ -57,6 +24,15 @@ msgstr "Suoratoistopalvelin aktiivinen"
msgid "Suspend Live TV" msgid "Suspend Live TV"
msgstr "Pysäytä suora TV-lähetys" msgstr "Pysäytä suora TV-lähetys"
msgid "Offer suspend mode"
msgstr "tyrkytä"
msgid "Always suspended"
msgstr "aina"
msgid "Never suspended"
msgstr "ei koskaan"
msgid "Common Settings" msgid "Common Settings"
msgstr "Yleiset asetukset" msgstr "Yleiset asetukset"
@ -105,11 +81,3 @@ msgstr "Multicast-portti"
msgid "Multicast Streamtype" msgid "Multicast Streamtype"
msgstr "Multicast-lähetysmuoto" msgstr "Multicast-lähetysmuoto"
msgid "Offer suspend mode"
msgstr "tyrkytä"
msgid "Always suspended"
msgstr "aina"
msgid "Never suspended"
msgstr "ei koskaan"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: streamdev 0.5.0\n" "Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n" "Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2009-02-13 11:53+0100\n" "POT-Creation-Date: 2010-06-14 13:06+0200\n"
"PO-Revision-Date: 2008-03-30 02:11+0200\n" "PO-Revision-Date: 2008-03-30 02:11+0200\n"
"Last-Translator: micky979 <micky979@free.fr>\n" "Last-Translator: micky979 <micky979@free.fr>\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: <vdr@linuxtv.org>\n"
@ -15,39 +15,6 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8bit\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 "Démarrage 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" msgid "VDR Streaming Server"
msgstr "Serveur de streaming VDR" msgstr "Serveur de streaming VDR"
@ -57,6 +24,15 @@ msgstr "Streaming actif"
msgid "Suspend Live TV" msgid "Suspend Live TV"
msgstr "Suspendre 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" msgid "Common Settings"
msgstr "Paramètres communs" msgstr "Paramètres communs"
@ -105,11 +81,3 @@ msgstr ""
msgid "Multicast Streamtype" msgid "Multicast Streamtype"
msgstr "" msgstr ""
msgid "Offer suspend mode"
msgstr "Offrir le mode suspendre"
msgid "Always suspended"
msgstr "Toujours suspendre"
msgid "Never suspended"
msgstr "Jamais suspendre"

62
po/it_IT.po → server/po/it_IT.po Executable file → Normal file
View File

@ -9,47 +9,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: streamdev 0.5.0\n" "Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n" "Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2009-02-13 11:53+0100\n" "POT-Creation-Date: 2010-06-14 13:06+0200\n"
"PO-Revision-Date: 2008-04-13 23:42+0100\n" "PO-Revision-Date: 2010-06-19 03:58+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: <vdr@linuxtv.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8bit\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" msgid "VDR Streaming Server"
msgstr "Server trasmissione VDR" msgstr "Server trasmissione VDR"
@ -59,6 +26,15 @@ msgstr "Trasmissione attiva"
msgid "Suspend Live TV" msgid "Suspend Live TV"
msgstr "Sospendi TV dal vivo" 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" msgid "Common Settings"
msgstr "Impostazioni comuni" msgstr "Impostazioni comuni"
@ -96,22 +72,14 @@ msgid "HTTP Streamtype"
msgstr "Tipo flusso HTTP" msgstr "Tipo flusso HTTP"
msgid "Multicast Streaming Server" msgid "Multicast Streaming Server"
msgstr "" msgstr "Server trasmissione Multicast"
msgid "Start IGMP Server" msgid "Start IGMP Server"
msgstr "" msgstr "Avvia Server IGMP"
msgid "Multicast Client Port" msgid "Multicast Client Port"
msgstr "" msgstr "Porta Client Multicast"
msgid "Multicast Streamtype" msgid "Multicast Streamtype"
msgstr "" msgstr "Tipo flusso Multicast"
msgid "Offer suspend mode"
msgstr "Offri mod. sospensione"
msgid "Always suspended"
msgstr "Sempre sospeso"
msgid "Never suspended"
msgstr "Mai sospeso"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: streamdev 0.5.0\n" "Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n" "Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2009-02-13 11:53+0100\n" "POT-Creation-Date: 2010-06-14 13:06+0200\n"
"PO-Revision-Date: 2009-11-26 21:57+0200\n" "PO-Revision-Date: 2009-11-26 21:57+0200\n"
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n" "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
"Language-Team: Lietuvių\n" "Language-Team: Lietuvių\n"
@ -15,39 +15,6 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\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" msgid "VDR Streaming Server"
msgstr "VDR transliavimo serveris" msgstr "VDR transliavimo serveris"
@ -57,6 +24,15 @@ msgstr "Transliavimas vyksta"
msgid "Suspend Live TV" msgid "Suspend Live TV"
msgstr "Pristabdyti 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" msgid "Common Settings"
msgstr "Bendri nustatymai" msgstr "Bendri nustatymai"
@ -105,11 +81,3 @@ msgstr "Multicast kliento portas"
msgid "Multicast Streamtype" msgid "Multicast Streamtype"
msgstr "Multicast transliavimo tipas" 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"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: streamdev 0.5.0\n" "Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n" "Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2009-02-13 11:53+0100\n" "POT-Creation-Date: 2010-06-14 13:06+0200\n"
"PO-Revision-Date: 2008-06-26 15:36+0100\n" "PO-Revision-Date: 2008-06-26 15:36+0100\n"
"Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n" "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: <vdr@linuxtv.org>\n"
@ -15,39 +15,6 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-5\n" "Content-Type: text/plain; charset=ISO-8859-5\n"
"Content-Transfer-Encoding: 8bit\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" msgid "VDR Streaming Server"
msgstr "VDR Streaming áÕàÒÕà" msgstr "VDR Streaming áÕàÒÕà"
@ -57,6 +24,15 @@ msgstr "
msgid "Suspend Live TV" msgid "Suspend Live TV"
msgstr "¾áâÐÝÞÒÚÐ Live TV" msgstr "¾áâÐÝÞÒÚÐ Live TV"
msgid "Offer suspend mode"
msgstr "Предлагать остановку"
msgid "Always suspended"
msgstr "Всегда остановлен"
msgid "Never suspended"
msgstr "Никогда не остановлен"
msgid "Common Settings" msgid "Common Settings"
msgstr "½ÐáâàÞÙÚØ" msgstr "½ÐáâàÞÙÚØ"
@ -105,11 +81,3 @@ msgstr ""
msgid "Multicast Streamtype" msgid "Multicast Streamtype"
msgstr "" msgstr ""
msgid "Offer suspend mode"
msgstr "¿àÕÔÛÐÓÐâì ÞáâÐÝÞÒÚã"
msgid "Always suspended"
msgstr "²áÕÓÔÐ ÞáâÐÝÞÒÛÕÝ"
msgid "Never suspended"
msgstr "½ØÚÞÓÔÐ ÝÕ ÞáâÐÝÞÒÛÕÝ"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: streamdev_SK\n" "Project-Id-Version: streamdev_SK\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n" "Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2009-09-23 13:59+0200\n" "POT-Creation-Date: 2010-06-14 13:06+0200\n"
"PO-Revision-Date: \n" "PO-Revision-Date: \n"
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n" "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
"Language-Team: Slovak <hrala.milan@gmail.com>\n" "Language-Team: Slovak <hrala.milan@gmail.com>\n"
@ -17,39 +17,6 @@ msgstr ""
"X-Poedit-Language: Slovak\n" "X-Poedit-Language: Slovak\n"
"X-Poedit-Country: SLOVAKIA\n" "X-Poedit-Country: SLOVAKIA\n"
msgid "VTP Streaming Client"
msgstr "VTP prúdový klient"
msgid "Suspend Server"
msgstr "Server pozastavený"
msgid "Server is suspended"
msgstr "Server je doèasne preru¹ený"
msgid "Couldn't suspend Server!"
msgstr "Nepodarilo sa pozastavi» Server!"
msgid "Hide Mainmenu Entry"
msgstr "Schova» polo¾ku 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» prúdy"
msgid "Minimum Priority"
msgstr "minimálna priorita"
msgid "Maximum Priority"
msgstr "maximálna priorita"
msgid "VDR Streaming Server" msgid "VDR Streaming Server"
msgstr "VDR prúdový server" msgstr "VDR prúdový server"
@ -59,6 +26,15 @@ msgstr "streamovanie aktivne"
msgid "Suspend Live TV" msgid "Suspend Live TV"
msgstr "Pozastavenie ¾ivého vysielania" msgstr "Pozastavenie ¾ivého vysielania"
msgid "Offer suspend mode"
msgstr "Výber re¾ímu pozastavenia"
msgid "Always suspended"
msgstr "V¾dy pozastavi»"
msgid "Never suspended"
msgstr "Nikdy nepozastavi»"
msgid "Common Settings" msgid "Common Settings"
msgstr "V¹eobecné nastavenia" msgstr "V¹eobecné nastavenia"
@ -107,12 +83,3 @@ msgstr "Port klienta Multicast"
msgid "Multicast Streamtype" msgid "Multicast Streamtype"
msgstr "Multicast typ streamu" msgstr "Multicast typ streamu"
msgid "Offer suspend mode"
msgstr "Výber re¾ímu pozastavenia"
msgid "Always suspended"
msgstr "V¾dy pozastavi»"
msgid "Never suspended"
msgstr "Nikdy nepozastavi»"

View File

@ -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 <vdr/menuitems.h> #include <vdr/menuitems.h>
@ -50,7 +50,7 @@ const char* cStreamdevServerMenuSetupPage::StreamTypes[st_Count - 1] = {
"PES", "PES",
"PS", "PS",
"ES", "ES",
"Extern" "EXT"
}; };
const char* cStreamdevServerMenuSetupPage::SuspendModes[sm_Count] = { const char* cStreamdevServerMenuSetupPage::SuspendModes[sm_Count] = {
@ -62,14 +62,24 @@ const char* cStreamdevServerMenuSetupPage::SuspendModes[sm_Count] = {
cStreamdevServerMenuSetupPage::cStreamdevServerMenuSetupPage(void) { cStreamdevServerMenuSetupPage::cStreamdevServerMenuSetupPage(void) {
m_NewSetup = StreamdevServerSetup; m_NewSetup = StreamdevServerSetup;
Set();
}
cStreamdevServerMenuSetupPage::~cStreamdevServerMenuSetupPage() {
}
void cStreamdevServerMenuSetupPage::Set(void) {
static const char* modes[sm_Count]; static const char* modes[sm_Count];
for (int i = 0; i < sm_Count; i++) for (int i = 0; i < sm_Count; i++)
modes[i] = tr(SuspendModes[i]); modes[i] = tr(SuspendModes[i]);
int current = Current();
Clear();
AddCategory (tr("Common Settings")); AddCategory (tr("Common Settings"));
Add(new cMenuEditIntItem (tr("Maximum Number of Clients"), &m_NewSetup.MaxClients, 0, 100)); 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 cMenuEditStraItem(tr("Suspend behaviour"), &m_NewSetup.SuspendMode, sm_Count, modes));
if (m_NewSetup.SuspendMode == smOffer)
Add(new cMenuEditBoolItem(tr("Client may suspend"), &m_NewSetup.AllowSuspend)); Add(new cMenuEditBoolItem(tr("Client may suspend"), &m_NewSetup.AllowSuspend));
AddCategory (tr("VDR-to-VDR Server")); AddCategory (tr("VDR-to-VDR Server"));
@ -87,10 +97,8 @@ cStreamdevServerMenuSetupPage::cStreamdevServerMenuSetupPage(void) {
Add(new cMenuEditIntItem (tr("Multicast Client Port"), &m_NewSetup.IGMPClientPort, 0, 65535)); 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 cMenuEditStraItem(tr("Multicast Streamtype"), &m_NewSetup.IGMPStreamType, st_Count - 1, StreamTypes));
Add(new cMenuEditIpItem (tr("Bind to IP"), m_NewSetup.IGMPBindIP)); Add(new cMenuEditIpItem (tr("Bind to IP"), m_NewSetup.IGMPBindIP));
SetCurrent(Get(1)); SetCurrent(Get(current));
} Display();
cStreamdevServerMenuSetupPage::~cStreamdevServerMenuSetupPage() {
} }
void cStreamdevServerMenuSetupPage::AddCategory(const char *Title) { void cStreamdevServerMenuSetupPage::AddCategory(const char *Title) {
@ -139,3 +147,10 @@ void cStreamdevServerMenuSetupPage::Store(void) {
cStreamdevServer::Initialize(); 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;
}

View File

@ -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 #ifndef VDR_STREAMDEV_SETUPSERVER_H
@ -37,8 +37,10 @@ private:
cStreamdevServerSetup m_NewSetup; cStreamdevServerSetup m_NewSetup;
void AddCategory(const char *Title); void AddCategory(const char *Title);
void Set();
protected: protected:
virtual void Store(void); virtual void Store(void);
virtual eOSState ProcessKey(eKeys Key);
public: public:
cStreamdevServerMenuSetupPage(void); cStreamdevServerMenuSetupPage(void);

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * 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 $ * $Id: streamdev-server.c,v 1.2 2010/07/19 13:49:32 schmirl Exp $
*/ */
#include <getopt.h> #include <getopt.h>

View File

@ -1,5 +1,5 @@
/* /*
* $Id: streamdev-server.h,v 1.4 2007/02/19 12:08:16 schmirl Exp $ * $Id: streamdev-server.h,v 1.2 2010/07/19 13:49:32 schmirl Exp $
*/ */
#ifndef VDR_STREAMDEVSERVER_H #ifndef VDR_STREAMDEVSERVER_H

View File

@ -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 <vdr/ringbuffer.h> #include <vdr/ringbuffer.h>
@ -46,6 +46,9 @@ void cStreamdevWriter::Action(void)
uchar *block = NULL; uchar *block = NULL;
int count, offset = 0; int count, offset = 0;
#if APIVERSNUM >= 10705
SetPriority(-3);
#endif
sel.Clear(); sel.Clear();
sel.Add(*m_Socket, true); sel.Add(*m_Socket, true);
while (Running()) { while (Running()) {
@ -100,8 +103,9 @@ void cStreamdevWriter::Action(void)
// --- cStreamdevStreamer ----------------------------------------------------- // --- cStreamdevStreamer -----------------------------------------------------
cStreamdevStreamer::cStreamdevStreamer(const char *Name): cStreamdevStreamer::cStreamdevStreamer(const char *Name, const cServerConnection *Connection):
cThread(Name), cThread(Name),
m_Connection(Connection),
m_Writer(NULL), m_Writer(NULL),
m_RingBuffer(new cStreamdevBuffer(STREAMERBUFSIZE, TS_SIZE * 2, m_RingBuffer(new cStreamdevBuffer(STREAMERBUFSIZE, TS_SIZE * 2,
true, "streamdev-streamer")), true, "streamdev-streamer")),
@ -148,6 +152,9 @@ void cStreamdevStreamer::Stop(void)
void cStreamdevStreamer::Action(void) void cStreamdevStreamer::Action(void)
{ {
#if APIVERSNUM >= 10705
SetPriority(-3);
#endif
while (Running()) { while (Running()) {
int got; int got;
uchar *block = m_RingBuffer->Get(got); uchar *block = m_RingBuffer->Get(got);

View File

@ -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 #ifndef VDR_STREAMDEV_STREAMER_H
@ -11,6 +11,7 @@
class cTBSocket; class cTBSocket;
class cStreamdevStreamer; class cStreamdevStreamer;
class cServerConnection;
#ifndef TS_SIZE #ifndef TS_SIZE
#define TS_SIZE 188 #define TS_SIZE 188
@ -64,6 +65,7 @@ public:
class cStreamdevStreamer: public cThread { class cStreamdevStreamer: public cThread {
private: private:
const cServerConnection *m_Connection;
cStreamdevWriter *m_Writer; cStreamdevWriter *m_Writer;
cStreamdevBuffer *m_RingBuffer; cStreamdevBuffer *m_RingBuffer;
cStreamdevBuffer *m_SendBuffer; cStreamdevBuffer *m_SendBuffer;
@ -74,9 +76,11 @@ protected:
bool IsRunning(void) const { return m_Writer; } bool IsRunning(void) const { return m_Writer; }
public: public:
cStreamdevStreamer(const char *Name); cStreamdevStreamer(const char *Name, const cServerConnection *Connection = NULL);
virtual ~cStreamdevStreamer(); virtual ~cStreamdevStreamer();
const cServerConnection* Connection(void) const { return m_Connection; }
virtual void Start(cTBSocket *Socket); virtual void Start(cTBSocket *Socket);
virtual void Stop(void); virtual void Stop(void);
bool Abort(void); bool Abort(void);

View File

@ -16,6 +16,8 @@
# VBR video bitrate (kbit) # VBR video bitrate (kbit)
# VOPTS custom video options # VOPTS custom video options
# WIDTH scale video to width # WIDTH scale video to width
# HEIGHT scale video to height
# FPS output frames per second
# AC audio codec # AC audio codec
# ABR audio bitrate (kbit) # ABR audio bitrate (kbit)
# AOPTS custom audio options # AOPTS custom audio options
@ -42,14 +44,22 @@ ABR_MONO=64
### ###
# mencoder binary # mencoder binary
MENCODER=mencoder MENCODER=mencoder
### video part
# Default video codec (e.g. lavc/x264/copy) # Default video codec (e.g. lavc/x264/copy)
MENCODER_VC=lavc 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) # Default audio codec (e.g. lavc/mp3lame/faac/copy)
MENCODER_AC=mp3lame MENCODER_AC=mp3lame
# Default video codec if lavc is used (-ovc lavc -lavcopts vcodec=) # Default audio options if lavc is used (-oac lavc -lavcopts ...)
MENCODER_LAVC_VC=mpeg4 MENCODER_LAVC_AOPTS=acodec=mp2
# Default audio codec if lavc is used (-oac lavc -lavcopts acodec=) # Default audio options if mp3lame is used (-oac mp3lame -lameopts ...)
MENCODER_LAVC_AC=mp2 MENCODER_LAME_AOPTS=
# Default audio options if faac is used (-oac faac -faacopts ...)
MENCODER_FAAC_AOPTS=
### ###
### MENCODER CONFIG END ### MENCODER CONFIG END
@ -63,6 +73,8 @@ OGG_SPEED=1
OGG_VQUALITY=0 OGG_VQUALITY=0
# audioquality - higher value gives better quality but is slower (0..10) # audioquality - higher value gives better quality but is slower (0..10)
OGG_AQUALITY=0 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 ### OGG CONFIG END
@ -70,7 +82,19 @@ OGG_AQUALITY=0
function hasOpt { echo "$1" | grep -q "\b${2}\b"; } 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 function remux_cat
{ {
@ -87,20 +111,31 @@ function remux_mencoder
# Assemble video options # Assemble video options
VC=${REMUX_PARAM_VC:-$MENCODER_VC} VC=${REMUX_PARAM_VC:-$MENCODER_VC}
VOPTS=${REMUX_PARAM_VOPTS} 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 case "$VC" in
lavc) lavc)
LAVCOPTS=( LAVCOPTS=(
${VOPTS} ${VOPTS}
$(hasOpt "$VOPTS" vcodec || echo "vcodec=$MENCODER_LAVC_VC") $(IFS=$IFS:; addOpts "$VOPTS" $MENCODER_LAVC_VOPTS)
${VBR:+vbitrate=$VBR} ${VBR:+vbitrate=$VBR}
) )
[ ${#LAVCOPTS[*]} -gt 0 ] && VOPTS=$(IFS=:; echo -lavcopts "${LAVCOPTS[*]}") [ ${#LAVCOPTS[*]} -gt 0 ] && VOPTS=$(IFS=:; echo -lavcopts "${LAVCOPTS[*]}")
;; ;;
x264) x264)
isNumeric "$HEIGHT" && [ $HEIGHT -lt 0 -a $HEIGHT -gt -8 ] && ((HEIGHT-=8))
isNumeric "$WIDTH" && [ $WIDTH -lt 0 -a $WIDTH -gt -8 ] && ((WIDTH-=8))
X264OPTS=( X264OPTS=(
${VOPTS} ${VOPTS}
$(hasOpt "$VOPTS" threads || echo "threads=auto") $(IFS=$IFS:; addOpts "$VOPTS" $MENCODER_X264_VOPTS)
${VBR:+bitrate=$VBR} ${VBR:+bitrate=$VBR}
) )
[ ${#X264OPTS[*]} -gt 0 ] && VOPTS=$(IFS=:; echo -x264encopts "${X264OPTS[*]}") [ ${#X264OPTS[*]} -gt 0 ] && VOPTS=$(IFS=:; echo -x264encopts "${X264OPTS[*]}")
@ -121,7 +156,7 @@ function remux_mencoder
LAVCOPTS=( LAVCOPTS=(
${LAVCOPTS[*]} ${LAVCOPTS[*]}
${AOPTS} ${AOPTS}
$(hasOpt "$AOPTS" acodec || echo "acodec=$MENCODER_LAVC_AC") $(IFS=$IFS:; addOpts "$AOPTS" $MENCODER_LAVC_AOPTS)
${ABR:+abitrate=$ABR} ${ABR:+abitrate=$ABR}
) )
@ -133,6 +168,7 @@ function remux_mencoder
LAMEOPTS=( LAMEOPTS=(
${AOPTS} ${AOPTS}
$(isNumeric "${ABR}" && [ "${ABR}" -lt "$ABR_MONO" ] && ! hasOpt "${AOPTS}" mode ] && echo 'mode=3') $(isNumeric "${ABR}" && [ "${ABR}" -lt "$ABR_MONO" ] && ! hasOpt "${AOPTS}" mode ] && echo 'mode=3')
$(IFS=$IFS:; addOpts "$AOPTS" $MENCODER_LAME_AOPTS)
${ABR:+preset=$ABR} ${ABR:+preset=$ABR}
) )
[ ${#LAMEOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -lameopts "${LAMEOPTS[*]}") [ ${#LAMEOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -lameopts "${LAMEOPTS[*]}")
@ -140,6 +176,7 @@ function remux_mencoder
faac) faac)
FAACOPTS=( FAACOPTS=(
${AOPTS} ${AOPTS}
$(IFS=$IFS:; addOpts "$AOPTS" $MENCODER_FAAC_AOPTS)
${ABR:+br=$ABR} ${ABR:+br=$ABR}
) )
[ ${#FAACOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -faacopts "${FAACOPTS[*]}") [ ${#FAACOPTS[*]} -gt 0 ] && AOPTS=$(IFS=:; echo -faacopts "${FAACOPTS[*]}")
@ -155,15 +192,17 @@ function remux_mencoder
startReply startReply
exec 3<&0 exec 3<&0
echo "$MENCODER" \ echo $MENCODER \
-ovc $VC $VOPTS \ -ovc $VC $VOPTS \
-oac $AC $AOPTS \ -oac $AC $AOPTS \
${WIDTH:+-vf scale -zoom -xy $WIDTH} \ ${WIDTH:+-vf scale=$WIDTH:$HEIGHT -zoom} \
${FPS:+-ofps $FPS} \
-o "$FIFO" -- - >&2 -o "$FIFO" -- - >&2
"$MENCODER" \ $MENCODER \
-ovc $VC $VOPTS \ -ovc $VC $VOPTS \
-oac $AC $AOPTS \ -oac $AC $AOPTS \
${WIDTH:+-vf scale -zoom -xy $WIDTH} \ ${WIDTH:+-vf scale=$WIDTH:$HEIGHT -zoom} \
${FPS:+-ofps $FPS} \
-o "$FIFO" -- - 0<&3 >/dev/null & -o "$FIFO" -- - 0<&3 >/dev/null &
} }
@ -171,7 +210,15 @@ function remux_ogg
{ {
VOPTS=${REMUX_PARAM_VOPTS//[:=]/ } VOPTS=${REMUX_PARAM_VOPTS//[:=]/ }
AOPTS=${REMUX_PARAM_AOPTS//[:=]/ } 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=( OGGOPTS=(
${VOPTS} ${VOPTS}
@ -187,14 +234,14 @@ function remux_ogg
startReply startReply
exec 3<&0 exec 3<&0
echo "$OGG" --format ts \ echo $OGG --format ts \
${OGGOPTS[*]} \ ${OGGOPTS[*]} \
${WIDTH:+--width $WIDTH --height $(($WIDTH * 3 / 4 / 8 * 8))} \ ${WIDTH:+--width $WIDTH --height $HEIGHT} \
--title "VDR Streamdev: ${REMUX_CHANNEL_NAME}" \ --title "VDR Streamdev: ${REMUX_CHANNEL_NAME}" \
--output "$FIFO" -- - 0<&3 >&2 --output "$FIFO" -- - 0<&3 >&2
"$OGG" --format ts \ $OGG --format ts \
${OGGOPTS[*]} \ ${OGGOPTS[*]} \
${WIDTH:+--width $WIDTH --height $(($WIDTH * 3 / 4 / 8 * 8))} \ ${WIDTH:+--width $WIDTH --height $HEIGHT} \
--title "VDR Streamdev: ${REMUX_CHANNEL_NAME}" \ --title "VDR Streamdev: ${REMUX_CHANNEL_NAME}" \
--output "$FIFO" -- - 0<&3 >/dev/null & --output "$FIFO" -- - 0<&3 >/dev/null &
} }
@ -254,6 +301,7 @@ esac
ABR=${REMUX_PARAM_ABR:-$ABR} ABR=${REMUX_PARAM_ABR:-$ABR}
VBR=${REMUX_PARAM_VBR:-$VBR} VBR=${REMUX_PARAM_VBR:-$VBR}
WIDTH=${REMUX_PARAM_WIDTH:-$WIDTH} WIDTH=${REMUX_PARAM_WIDTH:-$WIDTH}
HEIGHT=${REMUX_PARAM_HEIGHT:-$HEIGHT}
PROG=${REMUX_PARAM_PROG:-$PROG} PROG=${REMUX_PARAM_PROG:-$PROG}
case "$PROG" in case "$PROG" in

View File

@ -11,4 +11,4 @@
#192.168.100.0/24 # any host on the local net #192.168.100.0/24 # any host on the local net
#204.152.189.113 # a specific host #204.152.189.113 # a specific host
#239.255.0.0/16 # uncomment for IGMP multicast streaming #239.255.0.0/16 # uncomment for IGMP multicast streaming
#0.0.0.0/0 # any host on any net (USE THIS WITH CARE!) #0.0.0.0/0 # any host on any net (DON'T DO THAT! USE AUTHENTICATION)

View File

@ -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

34
tools/Makefile Normal file
View File

@ -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* *~