Implemented multi-device support for streamdev client (closes #1207)

This commit is contained in:
Frank Schmirler 2013-01-29 00:02:17 +01:00
parent 9135cde712
commit 525edc1ccf
20 changed files with 154 additions and 156 deletions

View File

@ -1,6 +1,7 @@
VDR Plugin 'streamdev' Revision History
---------------------------------------
- Implemented multi-device support for streamdev client (suggested by johns)
- Basic support for HTTP streaming of recordings
- Close writer when streamer is finished
- Don't abort VTP connection if filter stream is broken

46
README
View File

@ -376,29 +376,26 @@ type "127001<OK>" on your remote. If you want to enter "192.168.1.12", type
"1921681<Right>12<OK>".
The parameters "Remote IP" and "Remote Port" in the client's setup specify the
address of the remote VDR-to-VDR server to connect to. Activate the client by
setting "Start Client" to yes. It is disabled by default, because it wouldn't
make much sense to start the client without specifying a server anyway. The
client is activated after you push the OK button, so there's no need to restart
VDR. Deactivation on-the-fly is not possible, so in order to deactivate the
client, you will have to restart VDR. However requests to switch channels will
be refused by streamdev-client once it has been deactivated. All other settings
can be changed without restarting VDR.
The client will try to connect to the server (in case it isn't yet) whenever
a remote channel is requested. Just activate the client and switch to a
channel that's not available by local devices. If anything goes wrong with the
connection between the two, you will see it in the logfile instantly. If you
now switch the client to a channel which isn't covered by it's own local
devices, it will ask the server for it. If the server can (currently) receive
that channel, the client will show it until you switch again, or until the
server needs that card (if no other is free) for a recording on a different
transponder.
address of the remote VDR-to-VDR server to connect to. The client is disabled
by default, because it wouldn't make much sense to start the client without
specifying a server anyway. Activate the client by setting "Simultaneously used
Devices" to at least 1. Streamdev-client will allocate as many VDR devices as
you configure here. Each of these devices opens one connection to the server
and becomes associated with one of the server's devices (typically a DVB card)
on demand.
Only the needed PIDs are transferred, and additional PIDs can be turned on
during an active transfer. This makes it possible to switch languages, receive
additional channels (for recording on the client) and use plugins that use
receivers themselves (like osdteletext).
additional channels on the same transponder and use plugins that use receivers
themselves (like osdteletext).
So for viewing live TV a single device is sufficient. But if the client needs
to receive channels from different transponders simultaneously (e.g. for PiP or
client side recordings) a second device becomes necessary.
To allocate additional devices, just increase the number and push the OK button.
There's no need to restart VDR. Deleting VDR devices on-the-fly is not possible.
However requests to switch channels will be refused by redundant devices.
The default timeout of 2 seconds for network operations should be sufficient in
most cases. Increase "Timeout" if you get frequent timeout errors in the log.
@ -435,12 +432,9 @@ higher, live TV will use your DVB card until a recordings kicks in. Then the
recording will take the DVB card and live TV will be shifted to streamdev
(you'll notice a short interruption of live TV).
Note that streamdev-client acts similar to a DVB card. It is possible to receive
multiple channels simultaneously, but only from the same transponder. Just add
additional instances of streamdev-client and you will be able to receive as many
transponders at a time. The same trick allows a client to receive channels from
different servers. To create an additional instance, copy the streamdev-client
binary to a different name (e.g. streamdev-client2):
To receive channels from multiple servers, create additional instances of the
streamdev-client plugin. Simply copy (don't link!) the binary to a different
name (e.g. streamdev-client2):
cd VDRPLUGINLIBDIR
cp libvdr-streamdev-client.so.1.X.X libvdr-streamdev-client2.so.1.X.X

View File

@ -29,30 +29,28 @@ using namespace std;
#define VIDEOBUFSIZE MEGABYTE(3)
cStreamdevDevice *cStreamdevDevice::m_Device = NULL;
const cChannel *cStreamdevDevice::m_DenyChannel = NULL;
cStreamdevDevice::cStreamdevDevice(void) {
m_Channel = NULL;
m_TSBuffer = NULL;
m_Disabled = false;
m_ClientSocket = new cClientSocket();
m_Channel = NULL;
m_TSBuffer = NULL;
m_Filters = new cStreamdevFilters;
m_Filters = new cStreamdevFilters(m_ClientSocket);
StartSectionHandler();
isyslog("streamdev-client: got device number %d", CardIndex() + 1);
m_Device = this;
m_Pids = 0;
m_Priority = -100;
}
cStreamdevDevice::~cStreamdevDevice() {
Dprintf("Device gets destructed\n");
Lock();
m_Device = NULL;
m_Filters->SetConnection(-1);
ClientSocket.Quit();
ClientSocket.Reset();
m_ClientSocket->Quit();
m_ClientSocket->Reset();
Unlock();
Cancel(3);
@ -60,6 +58,7 @@ cStreamdevDevice::~cStreamdevDevice() {
StopSectionHandler();
DELETENULL(m_Filters);
DELETENULL(m_TSBuffer);
delete m_ClientSocket;
}
#if APIVERSNUM >= 10700
@ -84,7 +83,7 @@ bool cStreamdevDevice::IsTunedToTransponder(const cChannel *Channel) const
bool cStreamdevDevice::IsTunedToTransponder(const cChannel *Channel)
#endif
{
return ClientSocket.DataSocket(siLive) != NULL &&
return m_ClientSocket->DataSocket(siLive) != NULL &&
m_Channel != NULL &&
Channel->Transponder() == m_Channel->Transponder();
}
@ -92,14 +91,14 @@ bool cStreamdevDevice::IsTunedToTransponder(const cChannel *Channel)
bool cStreamdevDevice::ProvidesChannel(const cChannel *Channel, int Priority,
bool *NeedsDetachReceivers) const {
#if APIVERSNUM >= 10725
bool prio = Priority == IDLEPRIORITY || Priority >= this->Priority();
bool prio = Priority == IDLEPRIORITY || Priority >= m_ClientSocket->Priority();
#else
bool prio = Priority < 0 || Priority > this->Priority();
bool prio = Priority < 0 || Priority > m_ClientSocket->Priority();
#endif
bool res = prio;
bool ndr = false;
if (!StreamdevClientSetup.StartClient || Channel == m_DenyChannel)
if (m_Disabled || Channel == m_DenyChannel)
return false;
Dprintf("ProvidesChannel, Channel=%s, Prio=%d\n", Channel->Name(), Priority);
@ -131,7 +130,7 @@ bool cStreamdevDevice::ProvidesChannel(const cChannel *Channel, int Priority,
}
else if (prio) {
if (Priority == LIVEPRIORITY) {
if (ClientSocket.ServerVersion() >= 100) {
if (m_ClientSocket->ServerVersion() >= 100) {
Priority = StreamdevClientSetup.LivePriority;
UpdatePriority(true);
}
@ -141,10 +140,10 @@ bool cStreamdevDevice::ProvidesChannel(const cChannel *Channel, int Priority,
}
}
res = ClientSocket.ProvidesChannel(Channel, Priority);
res = m_ClientSocket->ProvidesChannel(Channel, Priority);
ndr = Receiving();
if (ClientSocket.ServerVersion() >= 100)
if (m_ClientSocket->ServerVersion() >= 100)
UpdatePriority(false);
}
@ -175,9 +174,9 @@ bool cStreamdevDevice::SetChannelDevice(const cChannel *Channel,
m_Channel = Channel;
// Old servers delete cStreamdevLiveStreamer in ABRT.
// Delete it now or it will happen after we tuned to new channel
if (ClientSocket.ServerVersion() < 100)
if (m_ClientSocket->ServerVersion() < 100)
CloseDvr();
res = ClientSocket.SetChannelDevice(m_Channel);
res = m_ClientSocket->SetChannelDevice(m_Channel);
}
Dprintf("setchanneldevice res=%d\n", res);
return res;
@ -189,7 +188,7 @@ bool cStreamdevDevice::SetPid(cPidHandle *Handle, int Type, bool On) {
bool res = true;
if (Handle->pid && (On || !Handle->used)) {
res = ClientSocket.SetPid(Handle->pid, On);
res = m_ClientSocket->SetPid(Handle->pid, On);
m_Pids += (!res) ? 0 : On ? 1 : -1;
if (m_Pids < 0)
@ -203,8 +202,8 @@ bool cStreamdevDevice::OpenDvr(void) {
LOCK_THREAD;
CloseDvr();
if (ClientSocket.CreateDataConnection(siLive)) {
m_TSBuffer = new cTSBuffer(*ClientSocket.DataSocket(siLive), MEGABYTE(2), CardIndex() + 1);
if (m_ClientSocket->CreateDataConnection(siLive)) {
m_TSBuffer = new cTSBuffer(*m_ClientSocket->DataSocket(siLive), MEGABYTE(2), CardIndex() + 1);
}
else {
esyslog("cStreamdevDevice::OpenDvr(): DVR connection FAILED");
@ -217,26 +216,26 @@ void cStreamdevDevice::CloseDvr(void) {
Dprintf("CloseDvr\n");
LOCK_THREAD;
ClientSocket.CloseDvr();
m_ClientSocket->CloseDvr();
DELETENULL(m_TSBuffer);
}
bool cStreamdevDevice::GetTSPacket(uchar *&Data) {
if (m_TSBuffer && m_Device) {
if (m_TSBuffer) {
Data = m_TSBuffer->Get();
#if 1 // TODO: this should be fixed in vdr cTSBuffer
// simple disconnect detection
static int m_TSFails = 0;
if (!Data) {
LOCK_THREAD;
if(!ClientSocket.DataSocket(siLive)) {
if(!m_ClientSocket->DataSocket(siLive)) {
return false; // triggers CloseDvr() + OpenDvr() in cDevice
}
cPoller Poller(*ClientSocket.DataSocket(siLive));
cPoller Poller(*m_ClientSocket->DataSocket(siLive));
errno = 0;
if (Poller.Poll() && !errno) {
char tmp[1];
if (recv(*ClientSocket.DataSocket(siLive), tmp, 1, MSG_PEEK) == 0 && !errno) {
if (recv(*m_ClientSocket->DataSocket(siLive), tmp, 1, MSG_PEEK) == 0 && !errno) {
esyslog("cStreamDevice::GetTSPacket: GetChecked: NOTHING (%d)", m_TSFails);
m_TSFails++;
if (m_TSFails > 10) {
@ -264,61 +263,50 @@ int cStreamdevDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask) {
return -1;
if (!ClientSocket.DataSocket(siLiveFilter)) {
if (ClientSocket.CreateDataConnection(siLiveFilter)) {
m_Filters->SetConnection(*ClientSocket.DataSocket(siLiveFilter));
if (!m_ClientSocket->DataSocket(siLiveFilter)) {
if (m_ClientSocket->CreateDataConnection(siLiveFilter)) {
m_Filters->SetConnection(*m_ClientSocket->DataSocket(siLiveFilter));
} else {
isyslog("cStreamdevDevice::OpenFilter: connect failed: %m");
return -1;
}
}
if (ClientSocket.SetFilter(Pid, Tid, Mask, true))
if (m_ClientSocket->SetFilter(Pid, Tid, Mask, true))
return m_Filters->OpenFilter(Pid, Tid, Mask);
return -1;
}
bool cStreamdevDevice::Init(void) {
if (m_Device == NULL && StreamdevClientSetup.StartClient)
new cStreamdevDevice;
bool cStreamdevDevice::ReInit(bool Disable) {
LOCK_THREAD;
m_Disabled = Disable;
m_Filters->SetConnection(-1);
m_Pids = 0;
m_ClientSocket->Quit();
m_ClientSocket->Reset();
//DELETENULL(m_TSBuffer);
return true;
}
bool cStreamdevDevice::ReInit(void) {
if(m_Device) {
m_Device->Lock();
m_Device->m_Filters->SetConnection(-1);
m_Device->m_Pids = 0;
}
ClientSocket.Quit();
ClientSocket.Reset();
if (m_Device != NULL) {
//DELETENULL(m_Device->m_TSBuffer);
m_Device->Unlock();
}
return StreamdevClientSetup.StartClient ? Init() : true;
}
void cStreamdevDevice::UpdatePriority(bool SwitchingChannels) {
if (m_Device) {
m_Device->Lock();
if (ClientSocket.SupportsPrio() && ClientSocket.DataSocket(siLive)) {
int Priority = m_Device->Priority();
void cStreamdevDevice::UpdatePriority(bool SwitchingChannels) const {
if (!m_Disabled) {
//LOCK_THREAD;
const_cast<cStreamdevDevice*>(this)->Lock();
if (m_ClientSocket->SupportsPrio() && m_ClientSocket->DataSocket(siLive)) {
int Priority = this->Priority();
// override TRANSFERPRIORITY (-1) with live TV priority from setup
if (m_Device == cDevice::ActualDevice() && Priority == TRANSFERPRIORITY) {
Priority = StreamdevClientSetup.LivePriority;
if (this == cDevice::ActualDevice() && m_ClientSocket->Priority() == TRANSFERPRIORITY) {
int Priority = StreamdevClientSetup.LivePriority;
// temporarily lower priority
if (SwitchingChannels)
Priority--;
if (Priority < 0 && ClientSocket.ServerVersion() < 100)
if (Priority < 0 && m_ClientSocket->ServerVersion() < 100)
Priority = 0;
}
if (m_Device->m_Priority != Priority && ClientSocket.SetPriority(Priority))
m_Device->m_Priority = Priority;
m_ClientSocket->SetPriority(Priority);
}
m_Device->Unlock();
const_cast<cStreamdevDevice*>(this)->Unlock();
}
}
@ -330,8 +318,8 @@ cString cStreamdevDevice::DeviceType(void) const {
static int dev = -1;
static cString devType("STRDev");
int d = -1;
if (ClientSocket.DataSocket(siLive) != NULL)
ClientSocket.GetSignal(NULL, NULL, &d);
if (m_ClientSocket->DataSocket(siLive) != NULL)
m_ClientSocket->GetSignal(NULL, NULL, &d);
if (d != dev) {
dev = d;
devType = d < 0 ? "STRDev" : *cString::sprintf("STRD%2d", d);
@ -341,15 +329,15 @@ cString cStreamdevDevice::DeviceType(void) const {
int cStreamdevDevice::SignalStrength(void) const {
int strength = -1;
if (ClientSocket.DataSocket(siLive) != NULL)
ClientSocket.GetSignal(&strength, NULL, NULL);
if (m_ClientSocket->DataSocket(siLive) != NULL)
m_ClientSocket->GetSignal(&strength, NULL, NULL);
return strength;
}
int cStreamdevDevice::SignalQuality(void) const {
int quality = -1;
if (ClientSocket.DataSocket(siLive) != NULL)
ClientSocket.GetSignal(NULL, &quality, NULL);
if (m_ClientSocket->DataSocket(siLive) != NULL)
m_ClientSocket->GetSignal(NULL, &quality, NULL);
return quality;
}

View File

@ -17,13 +17,13 @@ class cTBString;
class cStreamdevDevice: public cDevice {
private:
bool m_Disabled;
cClientSocket *m_ClientSocket;
const cChannel *m_Channel;
cTSBuffer *m_TSBuffer;
cStreamdevFilters *m_Filters;
int m_Pids;
int m_Priority;
static cStreamdevDevice *m_Device;
static const cChannel *m_DenyChannel;
protected:
@ -67,12 +67,10 @@ public:
virtual int SignalStrength(void) const;
virtual int SignalQuality(void) const;
static void UpdatePriority(bool SwitchingChannels = false);
bool ReInit(bool Disable);
void UpdatePriority(bool SwitchingChannels = false) const;
bool SuspendServer() { return m_ClientSocket->SuspendServer(); }
static void DenyChannel(const cChannel *Channel) { m_DenyChannel = Channel; }
static bool Init(void);
static bool ReInit(void);
static cStreamdevDevice *GetDevice(void) { return m_Device; }
};
#endif // VDR_STREAMDEV_DEVICE_H

View File

@ -144,8 +144,9 @@ bool cStreamdevFilter::IsClosed(void) {
// --- cStreamdevFilters -----------------------------------------------------
cStreamdevFilters::cStreamdevFilters(void):
cStreamdevFilters::cStreamdevFilters(cClientSocket *ClientSocket):
cThread("streamdev-client: sections assembler") {
m_ClientSocket = ClientSocket;
m_TSBuffer = NULL;
}
@ -173,7 +174,7 @@ void cStreamdevFilters::CarbageCollect(void) {
if (errno == ECONNREFUSED ||
errno == ECONNRESET ||
errno == EPIPE) {
ClientSocket.SetFilter(fi->Pid(), fi->Tid(), fi->Mask(), false);
m_ClientSocket->SetFilter(fi->Pid(), fi->Tid(), fi->Mask(), false);
Dprintf("cStreamdevFilters::CarbageCollector: filter closed: Pid %4d, Tid %3d, Mask %2x (%d filters left)",
(int)fi->Pid(), (int)fi->Tid(), fi->Mask(), Count()-1);
@ -200,7 +201,7 @@ bool cStreamdevFilters::ReActivateFilters(void)
bool res = true;
CarbageCollect();
for (cStreamdevFilter *fi = First(); fi; fi = Next(fi)) {
res = ClientSocket.SetFilter(fi->Pid(), fi->Tid(), fi->Mask(), true) && res;
res = m_ClientSocket->SetFilter(fi->Pid(), fi->Tid(), fi->Mask(), true) && res;
Dprintf("ReActivateFilters(%d, %d, %d) -> %s", fi->Pid(), fi->Tid(), fi->Mask(), res ? "Ok" :"FAIL");
}
return res;
@ -251,7 +252,7 @@ void cStreamdevFilters::Action(void) {
Dprintf("FATAL ERROR: %m\n");
esyslog("streamdev-client: couldn't send section packet: %m");
}
ClientSocket.SetFilter(f->Pid(), f->Tid(), f->Mask(), false);
m_ClientSocket->SetFilter(f->Pid(), f->Tid(), f->Mask(), false);
Del(f);
// Filter was closed.
// - need to check remaining filters for another match
@ -261,7 +262,7 @@ void cStreamdevFilters::Action(void) {
} else {
#if 1 // TODO: this should be fixed in vdr cTSBuffer
// Check disconnection
int fd = *ClientSocket.DataSocket(siLiveFilter);
int fd = *m_ClientSocket->DataSocket(siLiveFilter);
if(fd < 0)
break;
cPoller Poller(fd);
@ -273,7 +274,7 @@ void cStreamdevFilters::Action(void) {
++fails;
if (fails >= 10) {
esyslog("cStreamdevFilters::Action(): stream disconnected ?");
ClientSocket.CloseDataConnection(siLiveFilter);
m_ClientSocket->CloseDataConnection(siLiveFilter);
break;
}
} else {

View File

@ -11,9 +11,11 @@
class cTSBuffer;
class cStreamdevFilter;
class cClientSocket;
class cStreamdevFilters: public cList<cStreamdevFilter>, public cThread {
private:
cClientSocket *m_ClientSocket;
cTSBuffer *m_TSBuffer;
protected:
@ -23,7 +25,7 @@ protected:
bool ReActivateFilters(void);
public:
cStreamdevFilters(void);
cStreamdevFilters(cClientSocket *ClientSocket);
virtual ~cStreamdevFilters();
void SetConnection(int Handle);

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2012-03-03 23:57+0100\n"
"POT-Creation-Date: 2013-01-20 23:46+0100\n"
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
"Last-Translator: Frank Schmirler <vdrdev@schmirler.de>\n"
"Language-Team: German <vdr@linuxtv.org>\n"
@ -31,8 +31,8 @@ msgstr "Konnte Server nicht pausieren!"
msgid "Hide Mainmenu Entry"
msgstr "Hauptmenüeintrag verstecken"
msgid "Start Client"
msgstr "Client starten"
msgid "Simultaneously used Devices"
msgstr "Gleichzeitig genutzte DVB-Karten"
msgid "Remote IP"
msgstr "IP der Gegenseite"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2012-03-03 23:57+0100\n"
"POT-Creation-Date: 2013-01-28 22:16+0100\n"
"PO-Revision-Date: 2010-06-19 03:58+0100\n"
"Last-Translator: Javier Bradineras <jbradi@hotmail.com>\n"
"Language-Team: Spanish <vdr@linuxtv.org>\n"
@ -31,8 +31,8 @@ msgstr "Imposible suspender el servidor!"
msgid "Hide Mainmenu Entry"
msgstr "Ocultar entrada en menú principal"
msgid "Start Client"
msgstr "Iniciar Cliente"
msgid "Simultaneously used Devices"
msgstr ""
msgid "Remote IP"
msgstr "Indicar IP del Servidor"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2012-03-03 23:57+0100\n"
"POT-Creation-Date: 2013-01-28 22:16+0100\n"
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
"Last-Translator: Rolf Ahrenberg\n"
"Language-Team: Finnish <vdr@linuxtv.org>\n"
@ -31,8 +31,8 @@ msgstr "Palvelinta ei onnistuttu pysäyttämään!"
msgid "Hide Mainmenu Entry"
msgstr "Piilota valinta päävalikosta"
msgid "Start Client"
msgstr "Käynnistä VDR-asiakas"
msgid "Simultaneously used Devices"
msgstr ""
msgid "Remote IP"
msgstr "Etäkoneen IP-osoite"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2012-03-03 23:57+0100\n"
"POT-Creation-Date: 2013-01-28 22:16+0100\n"
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
"Last-Translator: micky979 <micky979@free.fr>\n"
"Language-Team: French <vdr@linuxtv.org>\n"
@ -31,8 +31,8 @@ msgstr "Impossible de suspendre le serveur!"
msgid "Hide Mainmenu Entry"
msgstr "Masquer dans le menu principal"
msgid "Start Client"
msgstr "Démarrage du client"
msgid "Simultaneously used Devices"
msgstr ""
msgid "Remote IP"
msgstr "Adresse IP du serveur"

View File

@ -9,14 +9,14 @@ msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2012-06-13 08:50+0200\n"
"POT-Creation-Date: 2013-01-28 22:16+0100\n"
"PO-Revision-Date: 2012-06-10 20:34+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: Italian <vdr@linuxtv.org>\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
msgid "VTP Streaming Client"
msgstr "Client trasmissione VTP"
@ -33,8 +33,8 @@ msgstr "Impossibile sospendere il server!"
msgid "Hide Mainmenu Entry"
msgstr "Nascondi voce menu principale"
msgid "Start Client"
msgstr "Avvia Client"
msgid "Simultaneously used Devices"
msgstr ""
msgid "Remote IP"
msgstr "Indirizzo IP del Server"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2012-03-03 23:57+0100\n"
"POT-Creation-Date: 2013-01-28 22:16+0100\n"
"PO-Revision-Date: 2009-11-26 21:57+0200\n"
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
@ -31,8 +31,8 @@ msgstr "Negali sustabdyti serverio!"
msgid "Hide Mainmenu Entry"
msgstr "Paslėpti pagrindinio meniu įrašą"
msgid "Start Client"
msgstr "Paleisti klientą"
msgid "Simultaneously used Devices"
msgstr ""
msgid "Remote IP"
msgstr "Nuotolinis IP adresas"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: streamdev 0.5.0\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2012-03-03 23:57+0100\n"
"POT-Creation-Date: 2013-01-28 22:16+0100\n"
"PO-Revision-Date: 2008-06-26 15:36+0100\n"
"Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
"Language-Team: Russian <vdr@linuxtv.org>\n"
@ -31,8 +31,8 @@ msgstr "
msgid "Hide Mainmenu Entry"
msgstr "ÁßàïâÐâì Ò ÓÛÐÒÝÞÜ ÜÕÝî"
msgid "Start Client"
msgstr "ÁâÐàâ ÚÛØÕÝâÐ"
msgid "Simultaneously used Devices"
msgstr ""
msgid "Remote IP"
msgstr "ÃÔÐÛÕÝÝëÙ IP"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: streamdev_SK\n"
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
"POT-Creation-Date: 2012-03-03 23:57+0100\n"
"POT-Creation-Date: 2013-01-28 22:16+0100\n"
"PO-Revision-Date: \n"
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
"Language-Team: Slovak <hrala.milan@gmail.com>\n"
@ -33,8 +33,8 @@ msgstr "Nepodarilo sa pozastavi
msgid "Hide Mainmenu Entry"
msgstr "Schova» polo¾ku v hlavnom menu"
msgid "Start Client"
msgstr "Spusti» Klienta"
msgid "Simultaneously used Devices"
msgstr ""
msgid "Remote IP"
msgstr "Vzdialená IP"

View File

@ -5,7 +5,7 @@
#include <vdr/menuitems.h>
#include "client/setup.h"
#include "client/device.h"
#include "client/streamdev-client.h"
#ifndef MINPRIORITY
#define MINPRIORITY -MAXPRIORITY
@ -50,11 +50,12 @@ bool cStreamdevClientSetup::SetupParse(const char *Name, const char *Value) {
return true;
}
cStreamdevClientMenuSetupPage::cStreamdevClientMenuSetupPage(void) {
cStreamdevClientMenuSetupPage::cStreamdevClientMenuSetupPage(cPluginStreamdevClient *Plugin) {
m_Plugin = Plugin;
m_NewSetup = StreamdevClientSetup;
Add(new cMenuEditBoolItem(tr("Hide Mainmenu Entry"), &m_NewSetup.HideMenuEntry));
Add(new cMenuEditBoolItem(tr("Start Client"), &m_NewSetup.StartClient));
Add(new cMenuEditIntItem (tr("Simultaneously used Devices"), &m_NewSetup.StartClient, 0, STREAMDEV_MAXDEVICES));
Add(new cMenuEditIpItem (tr("Remote IP"), m_NewSetup.RemoteIp));
Add(new cMenuEditIntItem (tr("Remote Port"), &m_NewSetup.RemotePort, 0, 65535));
Add(new cMenuEditIntItem (tr("Timeout (s)"), &m_NewSetup.Timeout, 1, 15));
@ -74,11 +75,6 @@ cStreamdevClientMenuSetupPage::~cStreamdevClientMenuSetupPage() {
}
void cStreamdevClientMenuSetupPage::Store(void) {
if (m_NewSetup.StartClient != StreamdevClientSetup.StartClient) {
if (m_NewSetup.StartClient)
cStreamdevDevice::Init();
}
SetupStore("StartClient", m_NewSetup.StartClient);
if (strcmp(m_NewSetup.RemoteIp, "") == 0)
SetupStore("RemoteIp", "-none-");
@ -97,6 +93,6 @@ void cStreamdevClientMenuSetupPage::Store(void) {
StreamdevClientSetup = m_NewSetup;
cStreamdevDevice::ReInit();
m_Plugin->Initialize();
}

View File

@ -28,15 +28,18 @@ struct cStreamdevClientSetup {
extern cStreamdevClientSetup StreamdevClientSetup;
class cPluginStreamdevClient;
class cStreamdevClientMenuSetupPage: public cMenuSetupPage {
private:
cStreamdevClientSetup m_NewSetup;
cPluginStreamdevClient *m_Plugin;
cStreamdevClientSetup m_NewSetup;
protected:
virtual void Store(void);
public:
cStreamdevClientMenuSetupPage(void);
cStreamdevClientMenuSetupPage(cPluginStreamdevClient *Plugin);
virtual ~cStreamdevClientMenuSetupPage();
};

View File

@ -18,12 +18,11 @@
#include "client/socket.h"
#include "common.h"
cClientSocket ClientSocket;
cClientSocket::cClientSocket(void)
{
memset(m_DataSockets, 0, sizeof(cTBSocket*) * si_Count);
m_ServerVersion = 0;
m_Priority = -100;
m_Prio = false;
m_Abort = false;
m_LastSignalUpdate = 0;
@ -284,12 +283,19 @@ bool cClientSocket::SetChannelDevice(const cChannel *Channel) {
}
bool cClientSocket::SetPriority(int Priority) {
if (Priority == m_Priority)
return true;
if (!CheckConnection()) return false;
CMD_LOCK;
std::string command = (std::string)"PRIO " + (const char*)itoa(Priority);
return Command(command, 220);
if (!Command(command, 220))
return false;
m_Priority = Priority;
return true;
}
bool cClientSocket::GetSignal(int *SignalStrength, int *SignalQuality, int *Dev) {

View File

@ -23,6 +23,7 @@ private:
char m_Buffer[BUFSIZ + 1]; // various uses
unsigned int m_ServerVersion;
bool m_Prio; // server supports command PRIO
int m_Priority; // current device priority
bool m_Abort; // quit command pending
time_t m_LastSignalUpdate;
@ -55,6 +56,7 @@ public:
bool SetChannelDevice(const cChannel *Channel);
bool SupportsPrio() { return m_Prio; }
unsigned int ServerVersion() { return m_ServerVersion; }
int Priority() const { return m_Priority; }
bool SetPriority(int Priority);
bool SetPid(int Pid, bool On);
bool SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On);
@ -66,6 +68,4 @@ public:
cTBSocket *DataSocket(eSocketId Id) const;
};
extern class cClientSocket ClientSocket;
#endif // VDR_STREAMDEV_CLIENT_CONNECTION_H

View File

@ -16,7 +16,7 @@
const char *cPluginStreamdevClient::DESCRIPTION = trNOOP("VTP Streaming Client");
cPluginStreamdevClient::cPluginStreamdevClient(void) {
cPluginStreamdevClient::cPluginStreamdevClient(void): m_Devices() {
}
cPluginStreamdevClient::~cPluginStreamdevClient() {
@ -26,9 +26,13 @@ const char *cPluginStreamdevClient::Description(void) {
return tr(DESCRIPTION);
}
bool cPluginStreamdevClient::Start(void) {
I18nRegister(PLUGIN_NAME_I18N);
cStreamdevDevice::Init();
bool cPluginStreamdevClient::Initialize(void) {
for (int i = 0; i < STREAMDEV_MAXDEVICES; i++) {
if (m_Devices[i])
m_Devices[i]->ReInit(i >= StreamdevClientSetup.StartClient);
else if (i < StreamdevClientSetup.StartClient)
m_Devices[i] = new cStreamdevDevice();
}
return true;
}
@ -37,7 +41,7 @@ const char *cPluginStreamdevClient::MainMenuEntry(void) {
}
cOsdObject *cPluginStreamdevClient::MainMenuAction(void) {
if (ClientSocket.SuspendServer())
if (StreamdevClientSetup.StartClient && m_Devices[0]->SuspendServer())
Skins.Message(mtInfo, tr("Server is suspended"));
else
Skins.Message(mtError, tr("Couldn't suspend Server!"));
@ -45,7 +49,7 @@ cOsdObject *cPluginStreamdevClient::MainMenuAction(void) {
}
cMenuSetupPage *cPluginStreamdevClient::SetupMenu(void) {
return new cStreamdevClientMenuSetupPage;
return new cStreamdevClientMenuSetupPage(this);
}
bool cPluginStreamdevClient::SetupParse(const char *Name, const char *Value) {
@ -61,7 +65,8 @@ bool cPluginStreamdevClient::Service(const char *Id, void *Data) {
}
void cPluginStreamdevClient::MainThreadHook(void) {
cStreamdevDevice::UpdatePriority();
for (int i = 0; i < StreamdevClientSetup.StartClient; i++)
m_Devices[i]->UpdatePriority();
}
VDRPLUGINCREATOR(cPluginStreamdevClient); // Don't touch this!

View File

@ -9,16 +9,20 @@
#include <vdr/plugin.h>
#define STREAMDEV_MAXDEVICES 8
class cStreamdevDevice;
class cPluginStreamdevClient : public cPlugin {
private:
static const char *DESCRIPTION;
static const char *DESCRIPTION;
cStreamdevDevice *m_Devices[STREAMDEV_MAXDEVICES];
public:
cPluginStreamdevClient(void);
virtual ~cPluginStreamdevClient();
virtual const char *Version(void) { return VERSION; }
virtual const char *Description(void);
virtual bool Start(void);
virtual bool Initialize(void);
virtual const char *MainMenuEntry(void);
virtual cOsdObject *MainMenuAction(void);
virtual cMenuSetupPage *SetupMenu(void);