summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/Makefile82
-rw-r--r--server/connection.c221
-rw-r--r--server/connection.h31
-rw-r--r--server/connectionHTTP.c9
-rw-r--r--server/connectionHTTP.h19
-rw-r--r--server/connectionIGMP.c8
-rw-r--r--server/connectionVTP.c52
-rw-r--r--server/connectionVTP.h6
-rw-r--r--server/livestreamer.c60
-rw-r--r--server/livestreamer.h6
-rw-r--r--server/menuHTTP.c23
-rw-r--r--server/menuHTTP.h12
-rw-r--r--server/po/de_DE.po83
-rw-r--r--server/po/fi_FI.po83
-rw-r--r--server/po/fr_FR.po83
-rw-r--r--server/po/it_IT.po85
-rw-r--r--server/po/lt_LT.po83
-rw-r--r--server/po/ru_RU.po83
-rw-r--r--server/po/sk_SK.po85
-rw-r--r--server/setup.c29
-rw-r--r--server/setup.h4
-rw-r--r--server/streamdev-server.c143
-rw-r--r--server/streamdev-server.h33
-rw-r--r--server/streamer.c11
-rw-r--r--server/streamer.h8
25 files changed, 1197 insertions, 145 deletions
diff --git a/server/Makefile b/server/Makefile
new file mode 100644
index 0000000..8f512ac
--- /dev/null
+++ b/server/Makefile
@@ -0,0 +1,82 @@
+#
+# Makefile for a Video Disk Recorder plugin
+#
+# $Id: Makefile,v 1.2 2010/07/19 13:49:31 schmirl Exp $
+
+# The official name of this plugin.
+# This name will be used in the '-P...' option of VDR to load the plugin.
+# By default the main source file also carries this name.
+#
+PLUGIN = streamdev-server
+
+### Includes and Defines (add further entries here):
+
+DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+
+### The object files (add further files here):
+
+COMMONOBJS = ../common.o
+
+SERVEROBJS = $(PLUGIN).o \
+ server.o component.o connection.o \
+ componentVTP.o connectionVTP.o \
+ componentHTTP.o connectionHTTP.o menuHTTP.o \
+ componentIGMP.o connectionIGMP.o \
+ streamer.o livestreamer.o livefilter.o recplayer.o \
+ suspend.o setup.o
+
+### The main target:
+
+.PHONY: all i18n clean
+all: libvdr-$(PLUGIN).so i18n
+
+### Implicit rules:
+
+%.o: %.c
+ $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
+
+### Dependencies:
+
+MAKEDEP = $(CXX) -MM -MG
+DEPFILE = .dependencies
+
+$(DEPFILE): Makefile
+ @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(SERVEROBJS:%.o=%.c) $(COMMONOBJS:%.o=%.c) > $@
+
+-include $(DEPFILE)
+
+### Internationalization (I18N):
+
+PODIR = po
+LOCALEDIR = $(VDRDIR)/locale
+I18Npo = $(wildcard $(PODIR)/*.po)
+I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
+I18Npot = $(PODIR)/$(PLUGIN).pot
+
+%.mo: %.po
+ msgfmt -c -o $@ $<
+
+$(I18Npot): $(SERVEROBJS:%.o=%.c)
+ xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<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* *~
diff --git a/server/connection.c b/server/connection.c
index eccb3c4..2ba99f3 100644
--- a/server/connection.c
+++ b/server/connection.c
@@ -1,5 +1,5 @@
/*
- * $Id: connection.c,v 1.13 2009/09/18 10:43:26 schmirl Exp $
+ * $Id: connection.c,v 1.16 2010/08/03 10:51:53 schmirl Exp $
*/
#include "server/connection.h"
@@ -8,6 +8,7 @@
#include "common.h"
#include <vdr/tools.h>
+#include <vdr/transfer.h>
#include <string.h>
#include <stdarg.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;
char *string = strdup(String);
char *ptr, *end;
@@ -58,7 +59,8 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
}
if (channel != NULL && apididx > 0) {
- int apid = 0, index = 1;
+ int apid = 0, dpid = 0;
+ int index = 1;
for (int i = 0; channel->Apid(i) != 0; ++i, ++index) {
if (index == apididx) {
@@ -70,7 +72,7 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
if (apid == 0) {
for (int i = 0; channel->Dpid(i) != 0; ++i, ++index) {
if (index == apididx) {
- apid = channel->Dpid(i);
+ dpid = channel->Dpid(i);
break;
}
}
@@ -78,6 +80,8 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
if (Apid != NULL)
*Apid = apid;
+ if (Dpid != NULL)
+ *Dpid = dpid;
}
free(string);
@@ -181,75 +185,172 @@ bool cServerConnection::Respond(const char *Message, bool Last, ...)
m_Pending = !Last;
return true;
}
-
+
+#if APIVERSNUM >= 10700
+static int GetClippedNumProvidedSystems(int AvailableBits, cDevice *Device)
+{
+ int MaxNumProvidedSystems = 1 << AvailableBits;
+ int NumProvidedSystems = Device->NumProvidedSystems();
+ if (NumProvidedSystems > MaxNumProvidedSystems) {
+ esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->CardIndex() + 1, NumProvidedSystems, MaxNumProvidedSystems);
+ NumProvidedSystems = MaxNumProvidedSystems;
+ }
+ else if (NumProvidedSystems <= 0) {
+ esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->CardIndex() + 1, NumProvidedSystems);
+ NumProvidedSystems = 1;
+ }
+ return NumProvidedSystems;
+}
+#endif
+
+/*
+ * copy of cDevice::GetDevice(...) but without side effects (not detaching receivers)
+ */
+cDevice* cServerConnection::CheckDevice(const cChannel *Channel, int Priority, bool LiveView, const cDevice *AvoidDevice)
+{
+ //cDevice *AvoidDevice = avoidDevice;
+ //avoidDevice = NULL;
+ // Collect the current priorities of all CAM slots that can decrypt the channel:
+ int NumCamSlots = CamSlots.Count();
+ int SlotPriority[NumCamSlots];
+ int NumUsableSlots = 0;
+ if (Channel->Ca() >= CA_ENCRYPTED_MIN) {
+ for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) {
+ SlotPriority[CamSlot->Index()] = MAXPRIORITY + 1; // assumes it can't be used
+ if (CamSlot->ModuleStatus() == msReady) {
+ if (CamSlot->ProvidesCa(Channel->Caids())) {
+ if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->SlotNumber())) {
+ SlotPriority[CamSlot->Index()] = CamSlot->Priority();
+ NumUsableSlots++;
+ }
+ }
+ }
+ }
+ if (!NumUsableSlots)
+ return NULL; // no CAM is able to decrypt this channel
+ }
+
+ bool NeedsDetachReceivers = false;
+ cDevice *d = NULL;
+ //cCamSlot *s = NULL;
+
+ uint32_t Impact = 0xFFFFFFFF; // we're looking for a device with the least impact
+ for (int j = 0; j < NumCamSlots || !NumUsableSlots; j++) {
+ if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY)
+ continue; // there is no CAM available in this slot
+ for (int i = 0; i < cDevice::NumDevices(); i++) {
+ cDevice *device = cDevice::GetDevice(i);
+ if (device == AvoidDevice)
+ continue; // we've been asked to skip this device
+ if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device->CardIndex() + 1)
+ continue; // a specific card was requested, but not this one
+ if (NumUsableSlots && !CamSlots.Get(j)->Assign(device, true))
+ continue; // CAM slot can't be used with this device
+ bool ndr;
+ if (device->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basicly able to do the job
+ if (NumUsableSlots && device->CamSlot() && device->CamSlot() != CamSlots.Get(j))
+ ndr = true; // using a different CAM slot requires detaching receivers
+ // Put together an integer number that reflects the "impact" using
+ // this device would have on the overall system. Each condition is represented
+ // by one bit in the number (or several bits, if the condition is actually
+ // a numeric value). The sequence in which the conditions are listed corresponds
+ // to their individual severity, where the one listed first will make the most
+ // difference, because it results in the most significant bit of the result.
+ uint32_t imp = 0;
+ imp <<= 1; imp |= LiveView ? !device->IsPrimaryDevice() || ndr : 0; // prefer the primary device for live viewing if we don't need to detach existing receivers
+ imp <<= 1; imp |= !device->Receiving() && (device != cTransferControl::ReceiverDevice() || device->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode
+ imp <<= 1; imp |= device->Receiving(); // avoid devices that are receiving
+#if APIVERSNUM >= 10700
+ imp <<= 2; imp |= GetClippedNumProvidedSystems(2, device) - 1; // avoid cards which support multiple delivery systems
+#endif
+ imp <<= 1; imp |= device == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device
+ imp <<= 8; imp |= min(max(device->Priority() + MAXPRIORITY, 0), 0xFF); // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used)
+ imp <<= 8; imp |= min(max((NumUsableSlots ? SlotPriority[j] : 0) + MAXPRIORITY, 0), 0xFF); // use the CAM slot with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used)
+ imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers
+ imp <<= 1; imp |= device->IsPrimaryDevice(); // avoid the primary device
+ imp <<= 1; imp |= NumUsableSlots ? 0 : device->HasCi(); // avoid cards with Common Interface for FTA channels
+ imp <<= 1; imp |= device->HasDecoder(); // avoid full featured cards
+ imp <<= 1; imp |= NumUsableSlots ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel
+ if (imp < Impact) {
+ // This device has less impact than any previous one, so we take it.
+ Impact = imp;
+ d = device;
+ NeedsDetachReceivers = ndr;
+ }
+ }
+ }
+ if (!NumUsableSlots)
+ break; // no CAM necessary, so just one loop over the devices
+ }
+ return d;
+}
+
cDevice *cServerConnection::GetDevice(const cChannel *Channel, int Priority)
{
- cDevice *device = NULL;
-
- /*Dprintf("+ Statistics:\n");
- Dprintf("+ Current Channel: %d\n", cDevice::CurrentChannel());
- Dprintf("+ Current Device: %d\n", cDevice::ActualDevice()->CardIndex());
- Dprintf("+ Transfer Mode: %s\n", cDevice::ActualDevice()
- == cDevice::PrimaryDevice() ? "false" : "true");
- Dprintf("+ Replaying: %s\n", cDevice::PrimaryDevice()->Replaying() ? "true"
- : "false");*/
-
- Dprintf(" * GetDevice(const cChannel*, int)\n");
- Dprintf(" * -------------------------------\n");
-
- device = cDevice::GetDevice(Channel, Priority, false);
-
- Dprintf(" * Found following device: %p (%d)\n", device,
- device ? device->CardIndex() + 1 : 0);
- if (device == cDevice::ActualDevice())
- Dprintf(" * is actual device\n");
- if (!cSuspendCtl::IsActive() && StreamdevServerSetup.SuspendMode != smAlways)
- Dprintf(" * NOT suspended\n");
-
- if (!device || (device == cDevice::ActualDevice()
+ const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel());
+
+ // turn off the streams of this connection
+ Detach();
+ // This call may detach receivers of the device it returns
+ cDevice *device = cDevice::GetDevice(Channel, Priority, false);
+
+ if (device && device == cDevice::ActualDevice()
&& !cSuspendCtl::IsActive()
- && StreamdevServerSetup.SuspendMode != smAlways)) {
+ && StreamdevServerSetup.SuspendMode != smAlways
+ && current != NULL
+ && !TRANSPONDER(Channel, current)) {
+ // now we would have to switch away live tv...let's see if live tv
+ // can be handled by another device
+#if VDRVERSNUM >= 10516
+ cDevice::SetAvoidDevice(device);
+ cDevice *newdev = cDevice::GetDevice(current, 0, true);
+#else
+ cDevice *newdev = CheckDevice(current, 0, true, device);
+#endif
+ if (newdev)
+ newdev->SwitchChannel(current, true);
+ else
+ device = NULL;
+ }
+
+ if (!device) {
+ // can't switch - continue the current stream
+ Attach();
+ dsyslog("streamdev: GetDevice failed for channel %s at priority %d", Channel->Name(), Priority);
+ }
+ return device;
+}
+
+bool cServerConnection::ProvidesChannel(const cChannel *Channel, int Priority)
+{
+ const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel());
+
+ cDevice *device = CheckDevice(Channel, Priority, false);
+ if (!device || (device == cDevice::ActualDevice()
+ && !cSuspendCtl::IsActive()
+ && StreamdevServerSetup.SuspendMode != smAlways
+ && current != NULL
+ && !TRANSPONDER(Channel, current))) {
// mustn't switch actual device
// maybe a device would be free if THIS connection did turn off its streams?
- Dprintf(" * trying again...\n");
- const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel());
- isyslog("streamdev-server: Detaching current receiver");
Detach();
- device = cDevice::GetDevice(Channel, Priority, false);
+ device = CheckDevice(Channel, Priority, false);
Attach();
- Dprintf(" * Found following device: %p (%d)\n", device,
- device ? device->CardIndex() + 1 : 0);
- if (device == cDevice::ActualDevice())
- Dprintf(" * is actual device\n");
- if (!cSuspendCtl::IsActive()
- && StreamdevServerSetup.SuspendMode != smAlways)
- Dprintf(" * NOT suspended\n");
- if (current && !TRANSPONDER(Channel, current))
- Dprintf(" * NOT same transponder\n");
- if (device && (device == cDevice::ActualDevice()
- && !cSuspendCtl::IsActive()
+ if (device && device == cDevice::ActualDevice()
+ && !cSuspendCtl::IsActive()
&& StreamdevServerSetup.SuspendMode != smAlways
&& current != NULL
- && !TRANSPONDER(Channel, current))) {
+ && !TRANSPONDER(Channel, current)) {
// now we would have to switch away live tv...let's see if live tv
// can be handled by another device
- cDevice *newdev = NULL;
- for (int i = 0; i < cDevice::NumDevices(); ++i) {
- cDevice *dev = cDevice::GetDevice(i);
- if (dev->ProvidesChannel(current, 0) && dev != device) {
- newdev = dev;
- break;
- }
- }
- Dprintf(" * Found device for live tv: %p (%d)\n", newdev,
- newdev ? newdev->CardIndex() + 1 : 0);
- if (newdev == NULL || newdev == device)
- // no suitable device to continue live TV, giving up...
+ cDevice *newdev = CheckDevice(current, 0, true, device);
+ if (!newdev) {
device = NULL;
- else
- newdev->SwitchChannel(current, true);
+ dsyslog("streamdev: Not providing channel %s at priority %d - live TV not suspended", Channel->Name(), Priority);
+ }
}
+ else if (!device)
+ dsyslog("streamdev: No device provides channel %s at priority %d", Channel->Name(), Priority);
}
-
return device;
}
diff --git a/server/connection.h b/server/connection.h
index 73cb3d5..22301b1 100644
--- a/server/connection.h
+++ b/server/connection.h
@@ -1,5 +1,5 @@
/*
- * $Id: connection.h,v 1.8 2009/09/18 10:43:26 schmirl Exp $
+ * $Id: connection.h,v 1.10 2010/08/03 10:46:41 schmirl Exp $
*/
#ifndef VDR_STREAMDEV_SERVER_CONNECTION_H
@@ -8,6 +8,11 @@
#include "tools/socket.h"
#include "common.h"
+#include <map>
+
+typedef std::map<std::string,std::string> tStrStrMap;
+typedef std::pair<std::string,std::string> tStrStr;
+
class cChannel;
class cDevice;
@@ -28,6 +33,13 @@ private:
uint m_WriteBytes;
uint m_WriteIndex;
+ tStrStrMap m_Headers;
+
+ /* Check if a device would be available for transfering the given
+ channel. This call has no side effects except for temporarily
+ detaching this connection's receivers. */
+ cDevice *CheckDevice(const cChannel *Channel, int Priority, bool LiveView, const cDevice *AvoidDevice = NULL);
+
protected:
/* Will be called when a command terminated by a newline has been
received */
@@ -41,7 +53,10 @@ protected:
virtual bool Respond(const char *Message, bool Last = true, ...);
//__attribute__ ((format (printf, 2, 4)));
- static const cChannel *ChannelFromString(const char *String, int *Apid = NULL);
+ /* Add a request header */
+ void SetHeader(const char *Name, const char *Value, const char *Prefix = "") { m_Headers.insert(tStrStr(std::string(Prefix) + Name, Value)); }
+
+ static const cChannel *ChannelFromString(const char *String, int *Apid = NULL, int *Dpid = NULL);
public:
/* If you derive, specify a short string such as HTTP for Protocol, which
@@ -81,14 +96,24 @@ public:
/* Will make the socket close after sending all queued output data */
void DeferClose(void) { m_DeferClose = true; }
- /* Will retrieve an unused device for transmitting data. Use the returned
+ /* Will retrieve an unused device for transmitting data. Receivers have
+ already been attached from the device if necessary. Use the returned
cDevice in a following call to StartTransfer */
cDevice *GetDevice(const cChannel *Channel, int Priority);
+ /* Test if a call to GetDevice would return a usable device. */
+ bool ProvidesChannel(const cChannel *Channel, int Priority);
+
virtual void Flushed(void) {}
virtual void Detach(void) = 0;
virtual void Attach(void) = 0;
+
+ /* This connections protocol name */
+ virtual const char* Protocol(void) const { return m_Protocol; }
+
+ /* std::map with additional information */
+ const tStrStrMap& Headers(void) const { return m_Headers; }
};
inline bool cServerConnection::HasData(void) const
diff --git a/server/connectionHTTP.c b/server/connectionHTTP.c
index 16a2af7..54ccf5a 100644
--- a/server/connectionHTTP.c
+++ b/server/connectionHTTP.c
@@ -1,5 +1,5 @@
/*
- * $Id: connectionHTTP.c,v 1.20 2010/07/22 14:18:18 schmirl Exp $
+ * $Id: connectionHTTP.c,v 1.21 2010/08/03 10:46:41 schmirl Exp $
*/
#include <ctype.h>
@@ -149,7 +149,9 @@ bool cConnectionHTTP::ProcessRequest(void)
if (m_ChannelList)
return Respond("%s", true, m_ChannelList->HttpHeader().c_str());
else if (m_Channel != NULL) {
- cDevice *device = GetDevice(m_Channel, 0);
+ cDevice *device = NULL;
+ if (ProvidesChannel(m_Channel, 0))
+ device = GetDevice(m_Channel, 0);
if (device != NULL) {
device->SwitchChannel(m_Channel, false);
m_LiveStreamer = new cStreamdevLiveStreamer(0, this);
@@ -186,8 +188,7 @@ bool cConnectionHTTP::ProcessRequest(void)
if (m_ChannelList)
return Respond("%s", true, m_ChannelList->HttpHeader().c_str());
else if (m_Channel != NULL) {
- cDevice *device = GetDevice(m_Channel, 0);
- if (device != NULL) {
+ if (ProvidesChannel(m_Channel, 0)) {
if (m_StreamType == stEXT) {
// TODO
return Respond("HTTP/1.0 200 OK")
diff --git a/server/connectionHTTP.h b/server/connectionHTTP.h
index 0548959..56f89b0 100644
--- a/server/connectionHTTP.h
+++ b/server/connectionHTTP.h
@@ -1,5 +1,5 @@
/*
- * $Id: connectionHTTP.h,v 1.6 2008/10/14 11:05:48 schmirl Exp $
+ * $Id: connectionHTTP.h,v 1.7 2010/07/19 13:49:31 schmirl Exp $
*/
#ifndef VDR_STREAMDEV_SERVERS_CONNECTIONHTTP_H
@@ -8,6 +8,7 @@
#include "connection.h"
#include "server/livestreamer.h"
+#include <map>
#include <tools/select.h>
class cChannel;
@@ -23,26 +24,19 @@ private:
hsFinished,
};
- enum eHTTPJob {
- hjTransfer,
- hjListing,
- };
-
- std::string m_Request;
- std::string m_Host;
std::string m_Authorization;
- //std::map<std::string,std::string> m_Headers; TODO: later?
eHTTPStatus m_Status;
- eHTTPJob m_Job;
// job: transfer
cStreamdevLiveStreamer *m_LiveStreamer;
- std::string m_StreamerParameter;
const cChannel *m_Channel;
- int m_Apid;
+ int m_Apid[2];
+ int m_Dpid[2];
eStreamType m_StreamType;
// job: listing
cChannelList *m_ChannelList;
+ cChannelList* ChannelListFromString(const std::string &PathInfo, const std::string &Filebase, const std::string &Fileext) const;
+ bool ProcessURI(const std::string &PathInfo);
protected:
bool ProcessRequest(void);
@@ -56,7 +50,6 @@ public:
virtual bool CanAuthenticate(void);
virtual bool Command(char *Cmd);
- bool CmdGET(const std::string &Opts);
virtual bool Abort(void) const;
virtual void Flushed(void);
diff --git a/server/connectionIGMP.c b/server/connectionIGMP.c
index dc08798..708f41c 100644
--- a/server/connectionIGMP.c
+++ b/server/connectionIGMP.c
@@ -1,5 +1,5 @@
/*
- * $Id: connectionIGMP.c,v 1.1 2009/02/13 10:39:22 schmirl Exp $
+ * $Id: connectionIGMP.c,v 1.3 2010/08/03 10:46:41 schmirl Exp $
*/
#include <ctype.h>
@@ -25,13 +25,15 @@ cConnectionIGMP::~cConnectionIGMP()
bool cConnectionIGMP::Start(cChannel *Channel, in_addr_t Dst)
{
if (Channel != NULL) {
- cDevice *device = GetDevice(Channel, 0);
+ cDevice *device = NULL;
+ if (ProvidesChannel(Channel, 0))
+ device = GetDevice(Channel, 0);
if (device != NULL) {
device->SwitchChannel(Channel, false);
struct in_addr ip;
ip.s_addr = Dst;
if (Connect(inet_ntoa(ip), m_ClientPort)) {
- m_LiveStreamer = new cStreamdevLiveStreamer(0);
+ m_LiveStreamer = new cStreamdevLiveStreamer(0, this);
if (m_LiveStreamer->SetChannel(Channel, m_StreamType)) {
m_LiveStreamer->SetDevice(device);
if (!SetDSCP())
diff --git a/server/connectionVTP.c b/server/connectionVTP.c
index 7ff60e5..0f92db0 100644
--- a/server/connectionVTP.c
+++ b/server/connectionVTP.c
@@ -1,5 +1,5 @@
/*
- * $Id: connectionVTP.c,v 1.27 2010/01/29 12:03:02 schmirl Exp $
+ * $Id: connectionVTP.c,v 1.31 2010/08/18 10:26:54 schmirl Exp $
*/
#include "server/connectionVTP.h"
@@ -746,6 +746,8 @@ cConnectionVTP::cConnectionVTP(void):
m_StreamType(stTSPIDS),
m_FiltersSupport(false),
m_RecPlayer(NULL),
+ m_TuneChannel(NULL),
+ m_TunePriority(0),
m_LSTEHandler(NULL),
m_LSTCHandler(NULL),
m_LSTTHandler(NULL),
@@ -836,6 +838,7 @@ bool cConnectionVTP::Command(char *Cmd)
else if (strcasecmp(Cmd, "READ") == 0) return CmdREAD(param);
else if (strcasecmp(Cmd, "TUNE") == 0) return CmdTUNE(param);
else if (strcasecmp(Cmd, "PLAY") == 0) return CmdPLAY(param);
+ else if (strcasecmp(Cmd, "PRIO") == 0) return CmdPRIO(param);
else if (strcasecmp(Cmd, "ADDP") == 0) return CmdADDP(param);
else if (strcasecmp(Cmd, "DELP") == 0) return CmdDELP(param);
else if (strcasecmp(Cmd, "ADDF") == 0) return CmdADDF(param);
@@ -881,8 +884,8 @@ bool cConnectionVTP::CmdCAPS(char *Opts)
return Respond(220, "Capability \"%s\" accepted", Opts);
}
- if (strcasecmp(Opts, "EXTERN") == 0) {
- m_StreamType = stExtern;
+ if (strcasecmp(Opts, "EXT") == 0) {
+ m_StreamType = stEXT;
return Respond(220, "Capability \"%s\" accepted", Opts);
}
@@ -894,6 +897,11 @@ bool cConnectionVTP::CmdCAPS(char *Opts)
return Respond(220, "Capability \"%s\" accepted", Opts);
}
+ // Command PRIO is known
+ if (strcasecmp(Opts, "PRIO") == 0) {
+ return Respond(220, "Capability \"%s\" accepted", Opts);
+ }
+
return Respond(561, "Capability \"%s\" not known", Opts);
}
@@ -911,9 +919,15 @@ bool cConnectionVTP::CmdPROV(char *Opts)
if ((chan = ChannelFromString(Opts)) == NULL)
return Respond(550, "Undefined channel \"%s\"", Opts);
- return GetDevice(chan, prio) != NULL
- ? Respond(220, "Channel available")
- : Respond(560, "Channel not available");
+ if (ProvidesChannel(chan, prio)) {
+ m_TuneChannel = chan;
+ m_TunePriority = prio;
+ return Respond(220, "Channel available");
+ }
+ else {
+ m_TuneChannel = NULL;
+ return Respond(560, "Channel not available");
+ }
}
bool cConnectionVTP::CmdPORT(char *Opts)
@@ -1067,18 +1081,23 @@ bool cConnectionVTP::CmdTUNE(char *Opts)
{
const cChannel *chan;
cDevice *dev;
+ int prio = m_TunePriority;
if ((chan = ChannelFromString(Opts)) == NULL)
return Respond(550, "Undefined channel \"%s\"", Opts);
- if ((dev = GetDevice(chan, 0)) == NULL)
+ if (chan != m_TuneChannel) {
+ esyslog("streamdev-server TUNE %s: Priority unknown - using 0", Opts);
+ prio = 0;
+ }
+ if ((dev = GetDevice(chan, prio)) == NULL)
return Respond(560, "Channel not available");
if (!dev->SwitchChannel(chan, false))
return Respond(560, "Channel not available");
delete m_LiveStreamer;
- m_LiveStreamer = new cStreamdevLiveStreamer(1);
+ m_LiveStreamer = new cStreamdevLiveStreamer(prio, this);
m_LiveStreamer->SetChannel(chan, m_StreamType);
m_LiveStreamer->SetDevice(dev);
if(m_LiveSocket)
@@ -1119,6 +1138,22 @@ bool cConnectionVTP::CmdPLAY(char *Opts)
}
}
+bool cConnectionVTP::CmdPRIO(char *Opts)
+{
+ int prio;
+ char *end;
+
+ prio = strtoul(Opts, &end, 10);
+ if (end == Opts || (*end != '\0' && *end != ' '))
+ return Respond(500, "Use: PRIO Priority");
+
+ if (m_LiveStreamer) {
+ m_LiveStreamer->SetPriority(prio);
+ return Respond(220, "Priority changed to %d", prio);
+ }
+ return Respond(550, "Priority not applicable");
+}
+
bool cConnectionVTP::CmdADDP(char *Opts)
{
int pid;
@@ -1243,6 +1278,7 @@ bool cConnectionVTP::CmdSUSP(void)
else if (StreamdevServerSetup.SuspendMode == smOffer
&& StreamdevServerSetup.AllowSuspend) {
cControl::Launch(new cSuspendCtl);
+ cControl::Attach();
return Respond(220, "Server is suspended");
} else
return Respond(550, "Client may not suspend server");
diff --git a/server/connectionVTP.h b/server/connectionVTP.h
index b938fe6..ee842fe 100644
--- a/server/connectionVTP.h
+++ b/server/connectionVTP.h
@@ -31,6 +31,11 @@ private:
bool m_FiltersSupport;
RecPlayer *m_RecPlayer;
+ // Priority is only known in PROV command
+ // Store in here for later use in TUNE call
+ const cChannel *m_TuneChannel;
+ int m_TunePriority;
+
// Members adopted for SVDRP
cLSTEHandler *m_LSTEHandler;
cLSTCHandler *m_LSTCHandler;
@@ -59,6 +64,7 @@ public:
bool CmdREAD(char *Opts);
bool CmdTUNE(char *Opts);
bool CmdPLAY(char *Opts);
+ bool CmdPRIO(char *Opts);
bool CmdADDP(char *Opts);
bool CmdDELP(char *Opts);
bool CmdADDF(char *Opts);
diff --git a/server/livestreamer.c b/server/livestreamer.c
index ab7c6b4..1286abd 100644
--- a/server/livestreamer.c
+++ b/server/livestreamer.c
@@ -289,7 +289,7 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
if (written != TS_SIZE)
siBuffer.ReportOverflow(TS_SIZE - written);
if (pmtPid != prevPmtPid) {
- m_Streamer->SetPids(pmtPid);
+ m_Streamer->SetPid(pmtPid, true);
Add(pmtPid, 0x02);
pmtVersion = -1;
}
@@ -335,10 +335,9 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
// --- cStreamdevLiveStreamer -------------------------------------------------
-cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority, std::string Parameter):
- cStreamdevStreamer("streamdev-livestreaming"),
+cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority, const cServerConnection *Connection):
+ cStreamdevStreamer("streamdev-livestreaming", Connection),
m_Priority(Priority),
- m_Parameter(Parameter),
m_NumPids(0),
m_StreamType(stTSPIDS),
m_Channel(NULL),
@@ -435,53 +434,58 @@ bool cStreamdevLiveStreamer::SetPids(int Pid, const int *Pids1, const int *Pids2
return true;
}
+void cStreamdevLiveStreamer::SetPriority(int Priority)
+{
+ m_Priority = Priority;
+ StartReceiver();
+}
+
void cStreamdevLiveStreamer::StartReceiver(void)
{
- DELETENULL(m_Receiver);
- if (m_NumPids > 0) {
+ if (m_Device != NULL && m_NumPids > 0 && IsRunning()) {
Dprintf("Creating Receiver to respect changed pids\n");
+ cReceiver *current = m_Receiver;
m_Receiver = new cStreamdevLiveReceiver(this, m_Channel->GetChannelID(), m_Priority, m_Pids);
- if (IsRunning() && m_Device != NULL) {
- Dprintf("Attaching new receiver\n");
- Attach();
- }
+ cThreadLock ThreadLock(m_Device);
+ Attach();
+ delete current;
}
+ else
+ DELETENULL(m_Receiver);
}
-bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid)
+bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, const int* Apid, const int *Dpid)
{
Dprintf("Initializing Remuxer for full channel transfer\n");
//printf("ca pid: %d\n", Channel->Ca());
m_Channel = Channel;
m_StreamType = StreamType;
- int apid[2] = { Apid, 0 };
- const int *Apids = Apid ? apid : m_Channel->Apids();
- const int *Dpids = Apid ? NULL : m_Channel->Dpids();
+ const int *Apids = Apid ? Apid : m_Channel->Apids();
+ const int *Dpids = Dpid ? Dpid : m_Channel->Dpids();
switch (m_StreamType) {
case stES:
{
int pid = ISRADIO(m_Channel) ? m_Channel->Apid(0) : m_Channel->Vpid();
- if (Apid != 0)
- pid = Apid;
+ if (Apid && Apid[0])
+ pid = Apid[0];
+ else if (Dpid && Dpid[0])
+ pid = Dpid[0];
m_Remux = new cTS2ESRemux(pid);
return SetPids(pid);
}
case stPES:
- m_Remux = new cTS2PESRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
- m_Channel->Spids());
+ m_Remux = new cTS2PESRemux(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
case stPS:
- m_Remux = new cTS2PSRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
- m_Channel->Spids());
+ m_Remux = new cTS2PSRemux(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
- case stExtern:
- m_Remux = new cExternRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
- m_Channel->Spids(), m_Parameter);
+ case stEXT:
+ m_Remux = new cExternRemux(Connection(), m_Channel, Apids, Dpids);
// fall through
case stTS:
// This should never happen, but ...
@@ -634,12 +638,10 @@ void cStreamdevFilterStreamer::SetDevice(cDevice *Device)
{
Dprintf("cStreamdevFilterStreamer::SetDevice()\n");
LOCK_THREAD;
- if(Device != m_Device) {
- Detach();
- m_Device = Device;
- //m_Channel = NULL;
- Attach();
- }
+ Detach();
+ m_Device = Device;
+ //m_Channel = NULL;
+ Attach();
}
bool cStreamdevFilterStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On)
diff --git a/server/livestreamer.h b/server/livestreamer.h
index 92448bb..71feb4c 100644
--- a/server/livestreamer.h
+++ b/server/livestreamer.h
@@ -18,7 +18,6 @@ class cStreamdevLiveReceiver;
class cStreamdevLiveStreamer: public cStreamdevStreamer {
private:
int m_Priority;
- std::string m_Parameter;
int m_Pids[MAXRECEIVEPIDS + 1];
int m_NumPids;
eStreamType m_StreamType;
@@ -32,13 +31,14 @@ private:
bool HasPid(int Pid);
public:
- cStreamdevLiveStreamer(int Priority, std::string Parameter = "");
+ cStreamdevLiveStreamer(int Priority, const cServerConnection *Connection);
virtual ~cStreamdevLiveStreamer();
void SetDevice(cDevice *Device) { m_Device = Device; }
bool SetPid(int Pid, bool On);
bool SetPids(int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL);
- bool SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid = 0);
+ bool SetChannel(const cChannel *Channel, eStreamType StreamType, const int* Apid = NULL, const int* Dpid = NULL);
+ void SetPriority(int Priority);
virtual int Put(const uchar *Data, int Count);
virtual uchar *Get(int &Count);
diff --git a/server/menuHTTP.c b/server/menuHTTP.c
index 84a4fb7..d7fb817 100644
--- a/server/menuHTTP.c
+++ b/server/menuHTTP.c
@@ -2,7 +2,7 @@
#include "server/menuHTTP.h"
//**************************** cChannelIterator **************
-cChannelIterator::cChannelIterator(cChannel *First): channel(First)
+cChannelIterator::cChannelIterator(const cChannel *First): channel(First)
{}
const cChannel* cChannelIterator::Next()
@@ -19,7 +19,7 @@ cListAll::cListAll(): cChannelIterator(Channels.First())
const cChannel* cListAll::NextChannel(const cChannel *Channel)
{
if (Channel)
- Channel = Channels.Next(Channel);
+ Channel = SkipFakeGroups(Channels.Next(Channel));
return Channel;
}
@@ -46,14 +46,19 @@ const cChannel* cListGroups::NextChannel(const cChannel *Channel)
}
//
// ********************* cListGroup ****************
-cListGroup::cListGroup(const cChannel *Group): cChannelIterator((Group && Group->GroupSep() && Channels.Next(Group) && !Channels.Next(Group)->GroupSep()) ? Channels.Next(Group) : NULL)
+cListGroup::cListGroup(const cChannel *Group): cChannelIterator(GetNextChannelInGroup(Group))
{}
-const cChannel* cListGroup::NextChannel(const cChannel *Channel)
+const cChannel* cListGroup::GetNextChannelInGroup(const cChannel *Channel)
{
if (Channel)
- Channel = Channels.Next(Channel);
- return (Channel && !Channel->GroupSep()) ? Channel : NULL;
+ Channel = SkipFakeGroups(Channels.Next(Channel));
+ return Channel && !Channel->GroupSep() ? Channel : NULL;
+}
+
+const cChannel* cListGroup::NextChannel(const cChannel *Channel)
+{
+ return GetNextChannelInGroup(Channel);
}
//
// ********************* cListTree ****************
@@ -68,7 +73,7 @@ const cChannel* cListTree::NextChannel(const cChannel *Channel)
if (currentGroup == selectedGroup)
{
if (Channel)
- Channel = Channels.Next(Channel);
+ Channel = SkipFakeGroups(Channels.Next(Channel));
if (Channel && Channel->GroupSep())
currentGroup = Channel;
}
@@ -205,8 +210,8 @@ std::string cHtmlChannelList::StreamTypeMenu()
(std::string) "[<a href=\"/PES/" + self + "\">PES</a>] ");
typeMenu += (streamType == stES ? (std::string) "[ES] " :
(std::string) "[<a href=\"/ES/" + self + "\">ES</a>] ");
- typeMenu += (streamType == stExtern ? (std::string) "[Extern] " :
- (std::string) "[<a href=\"/Extern/" + self + "\">Extern</a>] ");
+ typeMenu += (streamType == stEXT ? (std::string) "[EXT] " :
+ (std::string) "[<a href=\"/EXT/" + self + "\">EXT</a>] ");
return typeMenu;
}
diff --git a/server/menuHTTP.h b/server/menuHTTP.h
index cbd7b59..4ef6363 100644
--- a/server/menuHTTP.h
+++ b/server/menuHTTP.h
@@ -13,9 +13,10 @@ class cChannelIterator
const cChannel *channel;
protected:
virtual const cChannel* NextChannel(const cChannel *Channel) = 0;
+ static inline const cChannel* SkipFakeGroups(const cChannel *Channel);
public:
const cChannel* Next();
- cChannelIterator(cChannel *First);
+ cChannelIterator(const cChannel *First);
virtual ~cChannelIterator() {};
};
@@ -48,6 +49,8 @@ class cListGroups: public cChannelIterator
class cListGroup: public cChannelIterator
{
+ private:
+ static const cChannel* GetNextChannelInGroup(const cChannel *Channel);
protected:
virtual const cChannel* NextChannel(const cChannel *Channel);
public:
@@ -140,4 +143,11 @@ class cM3uChannelList: public cChannelList
virtual ~cM3uChannelList();
};
+inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group)
+{
+ while (Group && Group->GroupSep() && !*Group->Name())
+ Group = Channels.Next(Group);
+ return Group;
+}
+
#endif
diff --git a/server/po/de_DE.po b/server/po/de_DE.po
new file mode 100644
index 0000000..5fb611d
--- /dev/null
+++ b/server/po/de_DE.po
@@ -0,0 +1,83 @@
+# VDR streamdev plugin language source file.
+# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org
+# This file is distributed under the same license as the VDR streamdev package.
+# Frank Schmirler <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:06+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 "VDR Streaming Server"
+msgstr "VDR Streaming Server"
+
+msgid "Streaming active"
+msgstr "Streamen im Gange"
+
+msgid "Suspend Live TV"
+msgstr "Live-TV pausieren"
+
+msgid "Offer suspend mode"
+msgstr "Pausieren anbieten"
+
+msgid "Always suspended"
+msgstr "Immer pausiert"
+
+msgid "Never suspended"
+msgstr "Nie pausiert"
+
+msgid "Common Settings"
+msgstr "Allgemeines"
+
+msgid "Maximum Number of Clients"
+msgstr "Maximalanzahl an Clients"
+
+msgid "Suspend behaviour"
+msgstr "Pausierverhalten"
+
+msgid "Client may suspend"
+msgstr "Client darf pausieren"
+
+msgid "VDR-to-VDR Server"
+msgstr "VDR-zu-VDR Server"
+
+msgid "Start VDR-to-VDR Server"
+msgstr "VDR-zu-VDR Server starten"
+
+msgid "VDR-to-VDR Server Port"
+msgstr "Port des VDR-zu-VDR Servers"
+
+msgid "Bind to IP"
+msgstr "Binde an IP"
+
+msgid "HTTP Server"
+msgstr "HTTP Server"
+
+msgid "Start HTTP Server"
+msgstr "HTTP Server starten"
+
+msgid "HTTP Server Port"
+msgstr "Port des HTTP Servers"
+
+msgid "HTTP Streamtype"
+msgstr "HTTP Streamtyp"
+
+msgid "Multicast Streaming Server"
+msgstr "Multicast Streaming Server"
+
+msgid "Start IGMP Server"
+msgstr "IGMP Server starten"
+
+msgid "Multicast Client Port"
+msgstr "Port des Multicast Clients"
+
+msgid "Multicast Streamtype"
+msgstr "Multicast Streamtyp"
+
diff --git a/server/po/fi_FI.po b/server/po/fi_FI.po
new file mode 100644
index 0000000..99c6ee5
--- /dev/null
+++ b/server/po/fi_FI.po
@@ -0,0 +1,83 @@
+# VDR streamdev plugin language source file.
+# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org
+# This file is distributed under the same license as the VDR streamdev package.
+# Rolf Ahrenberg <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:06+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 "VDR Streaming Server"
+msgstr "VDR-suoratoistopalvelin"
+
+msgid "Streaming active"
+msgstr "Suoratoistopalvelin aktiivinen"
+
+msgid "Suspend Live TV"
+msgstr "Pysyt suora TV-lhetys"
+
+msgid "Offer suspend mode"
+msgstr "tyrkyt"
+
+msgid "Always suspended"
+msgstr "aina"
+
+msgid "Never suspended"
+msgstr "ei koskaan"
+
+msgid "Common Settings"
+msgstr "Yleiset asetukset"
+
+msgid "Maximum Number of Clients"
+msgstr "Suurin sallittu asiakkaiden mr"
+
+msgid "Suspend behaviour"
+msgstr "Pysytystoiminto"
+
+msgid "Client may suspend"
+msgstr "Asiakas saa pysytt palvelimen"
+
+msgid "VDR-to-VDR Server"
+msgstr "VDR-palvelin"
+
+msgid "Start VDR-to-VDR Server"
+msgstr "Kynnist VDR-palvelin"
+
+msgid "VDR-to-VDR Server Port"
+msgstr "VDR-palvelimen portti"
+
+msgid "Bind to IP"
+msgstr "Sido osoitteeseen"
+
+msgid "HTTP Server"
+msgstr "HTTP-palvelin"
+
+msgid "Start HTTP Server"
+msgstr "Kynnist HTTP-palvelin"
+
+msgid "HTTP Server Port"
+msgstr "HTTP-palvelimen portti"
+
+msgid "HTTP Streamtype"
+msgstr "HTTP-lhetysmuoto"
+
+msgid "Multicast Streaming Server"
+msgstr "Multicast-suoratoistopalvelin"
+
+msgid "Start IGMP Server"
+msgstr "Kynnist IGMP-palvelin"
+
+msgid "Multicast Client Port"
+msgstr "Multicast-portti"
+
+msgid "Multicast Streamtype"
+msgstr "Multicast-lhetysmuoto"
+
diff --git a/server/po/fr_FR.po b/server/po/fr_FR.po
new file mode 100644
index 0000000..c4b458e
--- /dev/null
+++ b/server/po/fr_FR.po
@@ -0,0 +1,83 @@
+# VDR streamdev plugin language source file.
+# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org
+# This file is distributed under the same license as the VDR streamdev package.
+# Frank Schmirler <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:06+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 "VDR Streaming Server"
+msgstr "Serveur de streaming VDR"
+
+msgid "Streaming active"
+msgstr "Streaming actif"
+
+msgid "Suspend Live TV"
+msgstr "Suspendre Live TV"
+
+msgid "Offer suspend mode"
+msgstr "Offrir le mode suspendre"
+
+msgid "Always suspended"
+msgstr "Toujours suspendre"
+
+msgid "Never suspended"
+msgstr "Jamais suspendre"
+
+msgid "Common Settings"
+msgstr "Paramtres communs"
+
+msgid "Maximum Number of Clients"
+msgstr "Nombre maximun de clients"
+
+msgid "Suspend behaviour"
+msgstr "Suspendre"
+
+msgid "Client may suspend"
+msgstr "Le client peut suspendre"
+
+msgid "VDR-to-VDR Server"
+msgstr "VDR-to-VDR Serveur"
+
+msgid "Start VDR-to-VDR Server"
+msgstr "Dmarrer le serveur VDR-to-VDR"
+
+msgid "VDR-to-VDR Server Port"
+msgstr "Port du serveur VDR-to-VDR"
+
+msgid "Bind to IP"
+msgstr "Attacher aux IP"
+
+msgid "HTTP Server"
+msgstr "Serveur HTTP"
+
+msgid "Start HTTP Server"
+msgstr "Dmarrer le serveur HTTP"
+
+msgid "HTTP Server Port"
+msgstr "Port du serveur HTTP"
+
+msgid "HTTP Streamtype"
+msgstr "Type de Streaming HTTP"
+
+msgid "Multicast Streaming Server"
+msgstr ""
+
+msgid "Start IGMP Server"
+msgstr ""
+
+msgid "Multicast Client Port"
+msgstr ""
+
+msgid "Multicast Streamtype"
+msgstr ""
+
diff --git a/server/po/it_IT.po b/server/po/it_IT.po
new file mode 100644
index 0000000..c5eed57
--- /dev/null
+++ b/server/po/it_IT.po
@@ -0,0 +1,85 @@
+# VDR streamdev plugin language source file.
+# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org
+# This file is distributed under the same license as the VDR streamdev package.
+# Alberto Carraro <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:06+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 "VDR Streaming Server"
+msgstr "Server trasmissione VDR"
+
+msgid "Streaming active"
+msgstr "Trasmissione attiva"
+
+msgid "Suspend Live TV"
+msgstr "Sospendi TV dal vivo"
+
+msgid "Offer suspend mode"
+msgstr "Offri mod. sospensione"
+
+msgid "Always suspended"
+msgstr "Sempre sospeso"
+
+msgid "Never suspended"
+msgstr "Mai sospeso"
+
+msgid "Common Settings"
+msgstr "Impostazioni comuni"
+
+msgid "Maximum Number of Clients"
+msgstr "Numero massimo di Client"
+
+msgid "Suspend behaviour"
+msgstr "Tipo sospensione"
+
+msgid "Client may suspend"
+msgstr "Permetti sospensione al Client"
+
+msgid "VDR-to-VDR Server"
+msgstr "Server VDR-a-VDR"
+
+msgid "Start VDR-to-VDR Server"
+msgstr "Avvia Server VDR-a-VDR"
+
+msgid "VDR-to-VDR Server Port"
+msgstr "Porta Server VDR-a-VDR"
+
+msgid "Bind to IP"
+msgstr "IP associati"
+
+msgid "HTTP Server"
+msgstr "Server HTTP"
+
+msgid "Start HTTP Server"
+msgstr "Avvia Server HTTP"
+
+msgid "HTTP Server Port"
+msgstr "Porta Server HTTP"
+
+msgid "HTTP Streamtype"
+msgstr "Tipo flusso HTTP"
+
+msgid "Multicast Streaming Server"
+msgstr "Server trasmissione Multicast"
+
+msgid "Start IGMP Server"
+msgstr "Avvia Server IGMP"
+
+msgid "Multicast Client Port"
+msgstr "Porta Client Multicast"
+
+msgid "Multicast Streamtype"
+msgstr "Tipo flusso Multicast"
+
diff --git a/server/po/lt_LT.po b/server/po/lt_LT.po
new file mode 100644
index 0000000..f12de4d
--- /dev/null
+++ b/server/po/lt_LT.po
@@ -0,0 +1,83 @@
+# VDR streamdev plugin language source file.
+# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org
+# This file is distributed under the same license as the VDR streamdev package.
+# Frank Schmirler <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:06+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 "VDR Streaming Server"
+msgstr "VDR transliavimo serveris"
+
+msgid "Streaming active"
+msgstr "Transliavimas vyksta"
+
+msgid "Suspend Live TV"
+msgstr "Pristabdyti Live TV"
+
+msgid "Offer suspend mode"
+msgstr "Klausti dėl sustabdymo"
+
+msgid "Always suspended"
+msgstr "Visada stabdyti"
+
+msgid "Never suspended"
+msgstr "Niekada nestabdyti"
+
+msgid "Common Settings"
+msgstr "Bendri nustatymai"
+
+msgid "Maximum Number of Clients"
+msgstr "Maksimalus klientų skaičius"
+
+msgid "Suspend behaviour"
+msgstr "Pristabdyti veikimą"
+
+msgid "Client may suspend"
+msgstr "Klientas gali pristabdyti"
+
+msgid "VDR-to-VDR Server"
+msgstr "VDR-su-VDR Serveris"
+
+msgid "Start VDR-to-VDR Server"
+msgstr "Paleisti VDR-su-VDR serverį"
+
+msgid "VDR-to-VDR Server Port"
+msgstr "VDR-su-VDR Serverio portas"
+
+msgid "Bind to IP"
+msgstr "Pririšti IP"
+
+msgid "HTTP Server"
+msgstr "HTTP Serveris"
+
+msgid "Start HTTP Server"
+msgstr "Paleisti HTTP serverį"
+
+msgid "HTTP Server Port"
+msgstr "HTTP serverio portas"
+
+msgid "HTTP Streamtype"
+msgstr "HTTP transliavimo tipas"
+
+msgid "Multicast Streaming Server"
+msgstr "Multicast transliavimo serveris"
+
+msgid "Start IGMP Server"
+msgstr "Paleisti IGMP serverį"
+
+msgid "Multicast Client Port"
+msgstr "Multicast kliento portas"
+
+msgid "Multicast Streamtype"
+msgstr "Multicast transliavimo tipas"
+
diff --git a/server/po/ru_RU.po b/server/po/ru_RU.po
new file mode 100644
index 0000000..21abeaf
--- /dev/null
+++ b/server/po/ru_RU.po
@@ -0,0 +1,83 @@
+# VDR streamdev plugin language source file.
+# Copyright (C) 2008 streamdev development team. See http://streamdev.vdr-developer.org
+# This file is distributed under the same license as the VDR streamdev package.
+# Frank Schmirler <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:06+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 "VDR Streaming Server"
+msgstr "VDR Streaming "
+
+msgid "Streaming active"
+msgstr " "
+
+msgid "Suspend Live TV"
+msgstr " Live TV"
+
+msgid "Offer suspend mode"
+msgstr " "
+
+msgid "Always suspended"
+msgstr " "
+
+msgid "Never suspended"
+msgstr " "
+
+msgid "Common Settings"
+msgstr ""
+
+msgid "Maximum Number of Clients"
+msgstr ". "
+
+msgid "Suspend behaviour"
+msgstr " "
+
+msgid "Client may suspend"
+msgstr " "
+
+msgid "VDR-to-VDR Server"
+msgstr "VDR-to-VDR "
+
+msgid "Start VDR-to-VDR Server"
+msgstr " VDR-to-VDR "
+
+msgid "VDR-to-VDR Server Port"
+msgstr "VDR-to-VDR "
+
+msgid "Bind to IP"
+msgstr " IP"
+
+msgid "HTTP Server"
+msgstr "HTTP "
+
+msgid "Start HTTP Server"
+msgstr " HTTP "
+
+msgid "HTTP Server Port"
+msgstr "HTTP "
+
+msgid "HTTP Streamtype"
+msgstr " HTTP "
+
+msgid "Multicast Streaming Server"
+msgstr ""
+
+msgid "Start IGMP Server"
+msgstr ""
+
+msgid "Multicast Client Port"
+msgstr ""
+
+msgid "Multicast Streamtype"
+msgstr ""
+
diff --git a/server/po/sk_SK.po b/server/po/sk_SK.po
new file mode 100644
index 0000000..78d98c9
--- /dev/null
+++ b/server/po/sk_SK.po
@@ -0,0 +1,85 @@
+# VDR streamdev plugin language source file.
+# Copyright (C) 2009 streamdev development team. See http://streamdev.vdr-developer.org
+# This file is distributed under the same license as the VDR streamdev package.
+# Milan Hrala <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:06+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 "VDR Streaming Server"
+msgstr "VDR prdov server"
+
+msgid "Streaming active"
+msgstr "streamovanie aktivne"
+
+msgid "Suspend Live TV"
+msgstr "Pozastavenie ivho vysielania"
+
+msgid "Offer suspend mode"
+msgstr "Vber remu pozastavenia"
+
+msgid "Always suspended"
+msgstr "Vdy pozastavi"
+
+msgid "Never suspended"
+msgstr "Nikdy nepozastavi"
+
+msgid "Common Settings"
+msgstr "Veobecn nastavenia"
+
+msgid "Maximum Number of Clients"
+msgstr "Maximly poet klientov"
+
+msgid "Suspend behaviour"
+msgstr "Sprvanie preruenia"
+
+msgid "Client may suspend"
+msgstr "Klient me pozastavi"
+
+msgid "VDR-to-VDR Server"
+msgstr "VDR-do-VDR server"
+
+msgid "Start VDR-to-VDR Server"
+msgstr "Spusti VDR-do-VDR Server"
+
+msgid "VDR-to-VDR Server Port"
+msgstr "Port serveru pre VDR-do-VDR"
+
+msgid "Bind to IP"
+msgstr "viaza na IP"
+
+msgid "HTTP Server"
+msgstr "server HTTP"
+
+msgid "Start HTTP Server"
+msgstr "Spusti HTTP Server"
+
+msgid "HTTP Server Port"
+msgstr "Port serveru HTTP"
+
+msgid "HTTP Streamtype"
+msgstr "typ prdu HTTP"
+
+msgid "Multicast Streaming Server"
+msgstr "Multicast prdov server"
+
+msgid "Start IGMP Server"
+msgstr "Spusti IGMP Server"
+
+msgid "Multicast Client Port"
+msgstr "Port klienta Multicast"
+
+msgid "Multicast Streamtype"
+msgstr "Multicast typ streamu"
+
diff --git a/server/setup.c b/server/setup.c
index db709db..8c9b8ad 100644
--- a/server/setup.c
+++ b/server/setup.c
@@ -1,5 +1,5 @@
/*
- * $Id: setup.c,v 1.9 2009/10/13 06:38:47 schmirl Exp $
+ * $Id: setup.c,v 1.10 2010/07/19 13:49:31 schmirl Exp $
*/
#include <vdr/menuitems.h>
@@ -50,7 +50,7 @@ const char* cStreamdevServerMenuSetupPage::StreamTypes[st_Count - 1] = {
"PES",
"PS",
"ES",
- "Extern"
+ "EXT"
};
const char* cStreamdevServerMenuSetupPage::SuspendModes[sm_Count] = {
@@ -62,15 +62,25 @@ const char* cStreamdevServerMenuSetupPage::SuspendModes[sm_Count] = {
cStreamdevServerMenuSetupPage::cStreamdevServerMenuSetupPage(void) {
m_NewSetup = StreamdevServerSetup;
+ Set();
+}
+
+cStreamdevServerMenuSetupPage::~cStreamdevServerMenuSetupPage() {
+}
+
+void cStreamdevServerMenuSetupPage::Set(void) {
static const char* modes[sm_Count];
for (int i = 0; i < sm_Count; i++)
modes[i] = tr(SuspendModes[i]);
+ int current = Current();
+ Clear();
AddCategory (tr("Common Settings"));
Add(new cMenuEditIntItem (tr("Maximum Number of Clients"), &m_NewSetup.MaxClients, 0, 100));
Add(new cMenuEditStraItem(tr("Suspend behaviour"), &m_NewSetup.SuspendMode, sm_Count, modes));
- Add(new cMenuEditBoolItem(tr("Client may suspend"), &m_NewSetup.AllowSuspend));
+ if (m_NewSetup.SuspendMode == smOffer)
+ Add(new cMenuEditBoolItem(tr("Client may suspend"), &m_NewSetup.AllowSuspend));
AddCategory (tr("VDR-to-VDR Server"));
Add(new cMenuEditBoolItem(tr("Start VDR-to-VDR Server"), &m_NewSetup.StartVTPServer));
@@ -87,10 +97,8 @@ cStreamdevServerMenuSetupPage::cStreamdevServerMenuSetupPage(void) {
Add(new cMenuEditIntItem (tr("Multicast Client Port"), &m_NewSetup.IGMPClientPort, 0, 65535));
Add(new cMenuEditStraItem(tr("Multicast Streamtype"), &m_NewSetup.IGMPStreamType, st_Count - 1, StreamTypes));
Add(new cMenuEditIpItem (tr("Bind to IP"), m_NewSetup.IGMPBindIP));
- SetCurrent(Get(1));
-}
-
-cStreamdevServerMenuSetupPage::~cStreamdevServerMenuSetupPage() {
+ SetCurrent(Get(current));
+ Display();
}
void cStreamdevServerMenuSetupPage::AddCategory(const char *Title) {
@@ -139,3 +147,10 @@ void cStreamdevServerMenuSetupPage::Store(void) {
cStreamdevServer::Initialize();
}
+eOSState cStreamdevServerMenuSetupPage::ProcessKey(eKeys Key) {
+ int oldMode = m_NewSetup.SuspendMode;
+ eOSState state = cMenuSetupPage::ProcessKey(Key);
+ if (oldMode != m_NewSetup.SuspendMode)
+ Set();
+ return state;
+}
diff --git a/server/setup.h b/server/setup.h
index d22ab34..9f06aac 100644
--- a/server/setup.h
+++ b/server/setup.h
@@ -1,5 +1,5 @@
/*
- * $Id: setup.h,v 1.3 2009/09/18 10:43:26 schmirl Exp $
+ * $Id: setup.h,v 1.4 2010/07/19 13:49:31 schmirl Exp $
*/
#ifndef VDR_STREAMDEV_SETUPSERVER_H
@@ -37,8 +37,10 @@ private:
cStreamdevServerSetup m_NewSetup;
void AddCategory(const char *Title);
+ void Set();
protected:
virtual void Store(void);
+ virtual eOSState ProcessKey(eKeys Key);
public:
cStreamdevServerMenuSetupPage(void);
diff --git a/server/streamdev-server.c b/server/streamdev-server.c
new file mode 100644
index 0000000..b444df7
--- /dev/null
+++ b/server/streamdev-server.c
@@ -0,0 +1,143 @@
+/*
+ * streamdev.c: A plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: streamdev-server.c,v 1.2 2010/07/19 13:49:32 schmirl Exp $
+ */
+
+#include <getopt.h>
+#include <vdr/tools.h>
+#include "streamdev-server.h"
+#include "server/setup.h"
+#include "server/server.h"
+#include "server/suspend.h"
+
+#if !defined(APIVERSNUM) || APIVERSNUM < 10509
+#error "VDR-1.5.9 API version or greater is required!"
+#endif
+
+const char *cPluginStreamdevServer::DESCRIPTION = trNOOP("VDR Streaming Server");
+
+cPluginStreamdevServer::cPluginStreamdevServer(void)
+{
+}
+
+cPluginStreamdevServer::~cPluginStreamdevServer()
+{
+ free(opt_auth);
+ free(opt_remux);
+}
+
+const char *cPluginStreamdevServer::Description(void)
+{
+ return tr(DESCRIPTION);
+}
+
+const char *cPluginStreamdevServer::CommandLineHelp(void)
+{
+ // return a string that describes all known command line options.
+ return
+ " -a <LOGIN:PASSWORD>, --auth=<LOGIN:PASSWORD> Credentials for HTTP authentication.\n"
+ " -r <CMD>, --remux=<CMD> Define an external command for remuxing.\n"
+ ;
+}
+
+bool cPluginStreamdevServer::ProcessArgs(int argc, char *argv[])
+{
+ // implement command line argument processing here if applicable.
+ static const struct option long_options[] = {
+ { "auth", required_argument, NULL, 'a' },
+ { "remux", required_argument, NULL, 'r' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ int c;
+ while((c = getopt_long(argc, argv, "a:r:", long_options, NULL)) != -1) {
+ switch (c) {
+ case 'a':
+ {
+ if (opt_auth)
+ free(opt_auth);
+ int l = strlen(optarg);
+ cBase64Encoder Base64((uchar*) optarg, l, l * 4 / 3 + 3);
+ const char *s = Base64.NextLine();
+ if (s)
+ opt_auth = strdup(s);
+ }
+ break;
+ case 'r':
+ if (opt_remux)
+ free(opt_remux);
+ opt_remux = strdup(optarg);
+ break;
+ default:
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cPluginStreamdevServer::Start(void)
+{
+ I18nRegister(PLUGIN_NAME_I18N);
+ if (!StreamdevHosts.Load(STREAMDEVHOSTSPATH, true, true)) {
+ esyslog("streamdev-server: error while loading %s", STREAMDEVHOSTSPATH);
+ fprintf(stderr, "streamdev-server: error while loading %s\n", STREAMDEVHOSTSPATH);
+ if (access(STREAMDEVHOSTSPATH, F_OK) != 0) {
+ fprintf(stderr, " Please install streamdevhosts.conf into the path "
+ "printed above. Without it\n"
+ " no client will be able to access your streaming-"
+ "server. An example can be\n"
+ " found together with this plugin's sources.\n");
+ }
+ return false;
+ }
+ if (!opt_remux)
+ opt_remux = strdup(DEFAULT_EXTERNREMUX);
+
+ cStreamdevServer::Initialize();
+
+ return true;
+}
+
+void cPluginStreamdevServer::Stop(void)
+{
+ cStreamdevServer::Destruct();
+}
+
+cString cPluginStreamdevServer::Active(void)
+{
+ if (cStreamdevServer::Active())
+ {
+ static const char *Message = NULL;
+ if (!Message) Message = tr("Streaming active");
+ return Message;
+ }
+ return NULL;
+}
+
+const char *cPluginStreamdevServer::MainMenuEntry(void)
+{
+ if (StreamdevServerSetup.SuspendMode == smOffer && !cSuspendCtl::IsActive())
+ return tr("Suspend Live TV");
+ return NULL;
+}
+
+cOsdObject *cPluginStreamdevServer::MainMenuAction(void)
+{
+ cControl::Launch(new cSuspendCtl);
+ return NULL;
+}
+
+cMenuSetupPage *cPluginStreamdevServer::SetupMenu(void)
+{
+ return new cStreamdevServerMenuSetupPage;
+}
+
+bool cPluginStreamdevServer::SetupParse(const char *Name, const char *Value)
+{
+ return StreamdevServerSetup.SetupParse(Name, Value);
+}
+
+VDRPLUGINCREATOR(cPluginStreamdevServer); // Don't touch this!
diff --git a/server/streamdev-server.h b/server/streamdev-server.h
new file mode 100644
index 0000000..4083689
--- /dev/null
+++ b/server/streamdev-server.h
@@ -0,0 +1,33 @@
+/*
+ * $Id: streamdev-server.h,v 1.2 2010/07/19 13:49:32 schmirl Exp $
+ */
+
+#ifndef VDR_STREAMDEVSERVER_H
+#define VDR_STREAMDEVSERVER_H
+
+#include "common.h"
+
+#include <vdr/plugin.h>
+
+class cPluginStreamdevServer : public cPlugin {
+private:
+ static const char *DESCRIPTION;
+
+public:
+ cPluginStreamdevServer(void);
+ virtual ~cPluginStreamdevServer();
+
+ virtual const char *Version(void) { return VERSION; }
+ virtual const char *Description(void);
+ virtual const char *CommandLineHelp(void);
+ virtual bool ProcessArgs(int argc, char *argv[]);
+ virtual bool Start(void);
+ virtual void Stop(void);
+ virtual cString Active(void);
+ virtual const char *MainMenuEntry(void);
+ virtual cOsdObject *MainMenuAction(void);
+ virtual cMenuSetupPage *SetupMenu(void);
+ virtual bool SetupParse(const char *Name, const char *Value);
+};
+
+#endif // VDR_STREAMDEVSERVER_H
diff --git a/server/streamer.c b/server/streamer.c
index 42e7efa..ec7d3c3 100644
--- a/server/streamer.c
+++ b/server/streamer.c
@@ -1,5 +1,5 @@
/*
- * $Id: streamer.c,v 1.19 2009/06/19 06:32:45 schmirl Exp $
+ * $Id: streamer.c,v 1.21 2010/07/30 10:01:11 schmirl Exp $
*/
#include <vdr/ringbuffer.h>
@@ -46,6 +46,9 @@ void cStreamdevWriter::Action(void)
uchar *block = NULL;
int count, offset = 0;
+#if APIVERSNUM >= 10705
+ SetPriority(-3);
+#endif
sel.Clear();
sel.Add(*m_Socket, true);
while (Running()) {
@@ -100,8 +103,9 @@ void cStreamdevWriter::Action(void)
// --- cStreamdevStreamer -----------------------------------------------------
-cStreamdevStreamer::cStreamdevStreamer(const char *Name):
+cStreamdevStreamer::cStreamdevStreamer(const char *Name, const cServerConnection *Connection):
cThread(Name),
+ m_Connection(Connection),
m_Writer(NULL),
m_RingBuffer(new cStreamdevBuffer(STREAMERBUFSIZE, TS_SIZE * 2,
true, "streamdev-streamer")),
@@ -148,6 +152,9 @@ void cStreamdevStreamer::Stop(void)
void cStreamdevStreamer::Action(void)
{
+#if APIVERSNUM >= 10705
+ SetPriority(-3);
+#endif
while (Running()) {
int got;
uchar *block = m_RingBuffer->Get(got);
diff --git a/server/streamer.h b/server/streamer.h
index 6561bc2..988775a 100644
--- a/server/streamer.h
+++ b/server/streamer.h
@@ -1,5 +1,5 @@
/*
- * $Id: streamer.h,v 1.11 2009/06/19 06:32:45 schmirl Exp $
+ * $Id: streamer.h,v 1.12 2010/07/19 13:49:32 schmirl Exp $
*/
#ifndef VDR_STREAMDEV_STREAMER_H
@@ -11,6 +11,7 @@
class cTBSocket;
class cStreamdevStreamer;
+class cServerConnection;
#ifndef TS_SIZE
#define TS_SIZE 188
@@ -64,6 +65,7 @@ public:
class cStreamdevStreamer: public cThread {
private:
+ const cServerConnection *m_Connection;
cStreamdevWriter *m_Writer;
cStreamdevBuffer *m_RingBuffer;
cStreamdevBuffer *m_SendBuffer;
@@ -74,9 +76,11 @@ protected:
bool IsRunning(void) const { return m_Writer; }
public:
- cStreamdevStreamer(const char *Name);
+ cStreamdevStreamer(const char *Name, const cServerConnection *Connection = NULL);
virtual ~cStreamdevStreamer();
+ const cServerConnection* Connection(void) const { return m_Connection; }
+
virtual void Start(cTBSocket *Socket);
virtual void Stop(void);
bool Abort(void);