mirror of
https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
synced 2023-10-10 19:16:51 +02:00
Implemented multi-device support for streamdev client (closes #1207)
This commit is contained in:
parent
9135cde712
commit
525edc1ccf
1
HISTORY
1
HISTORY
@ -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
46
README
@ -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
|
||||
|
120
client/device.c
120
client/device.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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!
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user