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

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"
@@ -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;
const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel());
/*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");*/
// 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);
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()
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());
isyslog("streamdev-server: Detaching current receiver");
Detach();
device = cDevice::GetDevice(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()
&& 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
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...
device = NULL;
else
newdev->SwitchChannel(current, true);
}
&& 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?
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
// can be handled by another device
cDevice *newdev = CheckDevice(current, 0, true, device);
if (!newdev) {
device = NULL;
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;
}

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

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

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

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

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"
@@ -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");

View File

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

View File

@@ -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::StartReceiver(void)
void cStreamdevLiveStreamer::SetPriority(int Priority)
{
DELETENULL(m_Receiver);
if (m_NumPids > 0) {
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();
}
}
m_Priority = Priority;
StartReceiver();
}
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");
//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)

View File

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

View File

@@ -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::GetNextChannelInGroup(const cChannel *Channel)
{
if (Channel)
Channel = SkipFakeGroups(Channels.Next(Channel));
return Channel && !Channel->GroupSep() ? Channel : NULL;
}
const cChannel* cListGroup::NextChannel(const cChannel *Channel)
{
if (Channel)
Channel = Channels.Next(Channel);
return (Channel && !Channel->GroupSep()) ? Channel : NULL;
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;
}

View File

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

83
server/po/de_DE.po Normal file
View File

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

83
server/po/fi_FI.po Normal file
View File

@@ -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 "Pys<79>yt<79> suora TV-l<>hetys"
msgid "Offer suspend mode"
msgstr "tyrkyt<79>"
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 m<><6D>r<EFBFBD>"
msgid "Suspend behaviour"
msgstr "Pys<79>ytystoiminto"
msgid "Client may suspend"
msgstr "Asiakas saa pys<79>ytt<74><74> palvelimen"
msgid "VDR-to-VDR Server"
msgstr "VDR-palvelin"
msgid "Start VDR-to-VDR Server"
msgstr "K<>ynnist<73> 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 "K<>ynnist<73> HTTP-palvelin"
msgid "HTTP Server Port"
msgstr "HTTP-palvelimen portti"
msgid "HTTP Streamtype"
msgstr "HTTP-l<>hetysmuoto"
msgid "Multicast Streaming Server"
msgstr "Multicast-suoratoistopalvelin"
msgid "Start IGMP Server"
msgstr "K<>ynnist<73> IGMP-palvelin"
msgid "Multicast Client Port"
msgstr "Multicast-portti"
msgid "Multicast Streamtype"
msgstr "Multicast-l<>hetysmuoto"

83
server/po/fr_FR.po Normal file
View File

@@ -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 "Param<61>tres 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 "D<>marrer 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 "D<>marrer 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 ""

85
server/po/it_IT.po Normal file
View File

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

83
server/po/lt_LT.po Normal file
View File

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

83
server/po/ru_RU.po Normal file
View File

@@ -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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Streaming active"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Suspend Live TV"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Live TV"
msgid "Offer suspend mode"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Always suspended"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Never suspended"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Common Settings"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Maximum Number of Clients"
msgstr "<22><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Suspend behaviour"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Client may suspend"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "VDR-to-VDR Server"
msgstr "VDR-to-VDR <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Start VDR-to-VDR Server"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD> VDR-to-VDR <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "VDR-to-VDR Server Port"
msgstr "VDR-to-VDR <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Bind to IP"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> IP"
msgid "HTTP Server"
msgstr "HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Start HTTP Server"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "HTTP Server Port"
msgstr "HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>"
msgid "HTTP Streamtype"
msgstr "<22><><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
msgid "Multicast Streaming Server"
msgstr ""
msgid "Start IGMP Server"
msgstr ""
msgid "Multicast Client Port"
msgstr ""
msgid "Multicast Streamtype"
msgstr ""

85
server/po/sk_SK.po Normal file
View File

@@ -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 pr<70>dov<6F> server"
msgid "Streaming active"
msgstr "streamovanie aktivne"
msgid "Suspend Live TV"
msgstr "Pozastavenie <20>iv<69>ho vysielania"
msgid "Offer suspend mode"
msgstr "V<>ber re<72><65>mu pozastavenia"
msgid "Always suspended"
msgstr "V<>dy pozastavi<76>"
msgid "Never suspended"
msgstr "Nikdy nepozastavi<76>"
msgid "Common Settings"
msgstr "V<>eobecn<63> nastavenia"
msgid "Maximum Number of Clients"
msgstr "Maxim<69>ly po<70>et klientov"
msgid "Suspend behaviour"
msgstr "Spr<70>vanie preru<72>enia"
msgid "Client may suspend"
msgstr "Klient m<><6D>e pozastavi<76>"
msgid "VDR-to-VDR Server"
msgstr "VDR-do-VDR server"
msgid "Start VDR-to-VDR Server"
msgstr "Spusti<74> VDR-do-VDR Server"
msgid "VDR-to-VDR Server Port"
msgstr "Port serveru pre VDR-do-VDR"
msgid "Bind to IP"
msgstr "viaza<7A> na IP"
msgid "HTTP Server"
msgstr "server HTTP"
msgid "Start HTTP Server"
msgstr "Spusti<74> HTTP Server"
msgid "HTTP Server Port"
msgstr "Port serveru HTTP"
msgid "HTTP Streamtype"
msgstr "typ pr<70>du HTTP"
msgid "Multicast Streaming Server"
msgstr "Multicast pr<70>dov<6F> server"
msgid "Start IGMP Server"
msgstr "Spusti<74> IGMP Server"
msgid "Multicast Client Port"
msgstr "Port klienta Multicast"
msgid "Multicast Streamtype"
msgstr "Multicast typ streamu"

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

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

143
server/streamdev-server.c Normal file
View File

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

33
server/streamdev-server.h Normal file
View File

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

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

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