diff --git a/HISTORY b/HISTORY index cc16e99..35f9f39 100644 --- a/HISTORY +++ b/HISTORY @@ -2,6 +2,8 @@ VDR Plugin 'streamdev' Revision History --------------------------------------- - added Spanish translation (thanks to Javier Bradineras) +- live TV must be switched in VDR main thread +- dropped compatibility with VDR < 1.5.16 - return value of streamdev-clients cDevice::NumProvidedSystems() now configurable in plugin setup diff --git a/client/device.c b/client/device.c index 9e78f80..7f39bbe 100644 --- a/client/device.c +++ b/client/device.c @@ -49,9 +49,7 @@ cStreamdevDevice::~cStreamdevDevice() { Cancel(3); -#if APIVERSNUM >= 10515 StopSectionHandler(); -#endif DELETENULL(m_Filters); DELETENULL(m_TSBuffer); } diff --git a/client/streamdev-client.c b/client/streamdev-client.c index 00fa90c..62c57bd 100644 --- a/client/streamdev-client.c +++ b/client/streamdev-client.c @@ -10,8 +10,8 @@ #include "client/device.h" #include "client/setup.h" -#if !defined(APIVERSNUM) || APIVERSNUM < 10509 -#error "VDR-1.5.9 API version or greater is required!" +#if !defined(APIVERSNUM) || APIVERSNUM < 10516 +#error "VDR-1.5.16 API version or greater is required!" #endif const char *cPluginStreamdevClient::DESCRIPTION = trNOOP("VTP Streaming Client"); diff --git a/server/connection.c b/server/connection.c index 78a023a..3bf0ad5 100644 --- a/server/connection.c +++ b/server/connection.c @@ -8,11 +8,60 @@ #include "common.h" #include +#include #include #include #include #include +class cSwitchLive { +private: + cMutex mutex; + cCondWait switched; + cDevice *device; + const cChannel *channel; +public: + cDevice* Switch(cDevice *Device, const cChannel *Channel); + void Switch(void); + cSwitchLive(void); +}; + +cSwitchLive::cSwitchLive(): device(NULL), channel(NULL) +{ +} + +cDevice* cSwitchLive::Switch(cDevice *Device, const cChannel *Channel) +{ + mutex.Lock(); + device = Device; + channel = Channel; + mutex.Unlock(); + switched.Wait(); + return device; +} + +void cSwitchLive::Switch(void) +{ + mutex.Lock(); + if (channel && device) { + cDevice::SetAvoidDevice(device); + if (!Channels.SwitchTo(cDevice::CurrentChannel())) { + if (StreamdevServerSetup.SuspendMode == smAlways) { + Channels.SwitchTo(channel->Number()); + Skins.Message(mtInfo, tr("Streaming active")); + } + else { + esyslog("streamdev: Can't receive channel %d (%s) from device %d. Moving live TV to other device failed (PrimaryDevice=%d, ActualDevice=%d)", channel->Number(), channel->Name(), device->CardIndex(), cDevice::PrimaryDevice()->CardIndex(), cDevice::ActualDevice()->CardIndex()); + device = NULL; + } + } + // make sure we don't come in here next time + channel = NULL; + switched.Signal(); + } + mutex.Unlock(); +} + cServerConnection::cServerConnection(const char *Protocol, int Type): cTBSocket(Type), m_Protocol(Protocol), @@ -22,10 +71,12 @@ cServerConnection::cServerConnection(const char *Protocol, int Type): m_WriteBytes(0), m_WriteIndex(0) { + m_SwitchLive = new cSwitchLive(); } cServerConnection::~cServerConnection() { + delete m_SwitchLive; } const cChannel* cServerConnection::ChannelFromString(const char *String, int *Apid, int *Dpid) { @@ -302,34 +353,7 @@ cDevice *cServerConnection::GetDevice(const cChannel *Channel, int Priority) && UsedByLiveTV(device)) { // 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); - if (!Channels.SwitchTo(cDevice::CurrentChannel())) { - if (StreamdevServerSetup.SuspendMode == smAlways) { - Channels.SwitchTo(Channel->Number()); - Skins.QueueMessage(mtInfo, tr("Streaming active")); - } - else { - dsyslog("streamdev: GetDevice: Live TV not suspended"); - device = NULL; - } - } -#else - const cChannel *current = Channels.GetByNumber(cDevice::CurrentChannel()); - cDevice *newdev = current ? CheckDevice(current, 0, true, device) : NULL; - if (newdev) { - dsyslog("streamdev: GetDevice: Trying to move live TV to device %d", newdev->CardIndex()); - newdev->SwitchChannel(current, true); - } - else if (StreamdevServerSetup.SuspendMode == smAlways) { - Channels.SwitchTo(Channel->Number()); - Skins.QueueMessage(mtInfo, tr("Streaming active")); - } - else { - dsyslog("streamdev: GetDevice: Live TV not suspended"); - device = NULL; - } -#endif + device = m_SwitchLive->Switch(device, Channel); } if (!device) { @@ -371,3 +395,8 @@ bool cServerConnection::ProvidesChannel(const cChannel *Channel, int Priority) } return device; } + +void cServerConnection::MainThreadHook() +{ + m_SwitchLive->Switch(); +} diff --git a/server/connection.h b/server/connection.h index 01a070c..6cc6764 100644 --- a/server/connection.h +++ b/server/connection.h @@ -15,6 +15,7 @@ typedef std::pair tStrStr; class cChannel; class cDevice; +class cSwitchLive; /* Basic capabilities of a straight text-based protocol, most functions virtual to support more complicated protocols */ @@ -33,6 +34,8 @@ private: uint m_WriteBytes; uint m_WriteIndex; + cSwitchLive *m_SwitchLive; + tStrStrMap m_Headers; /* Check if a device would be available for transfering the given @@ -108,6 +111,9 @@ public: /* Test if a call to GetDevice would return a usable device. */ bool ProvidesChannel(const cChannel *Channel, int Priority); + /* Do things which must be done in VDR's main loop */ + void MainThreadHook(); + virtual void Flushed(void) {} virtual void Detach(void) = 0; diff --git a/server/connectionVTP.c b/server/connectionVTP.c index 0f92db0..411f3fd 100644 --- a/server/connectionVTP.c +++ b/server/connectionVTP.c @@ -1783,14 +1783,7 @@ bool cConnectionVTP::Respond(int Code, const char *Message, ...) { va_list ap; va_start(ap, Message); -#if APIVERSNUM < 10515 - char *buffer; - if (vasprintf(&buffer, Message, ap) < 0) - buffer = strdup("???"); - cString str(buffer, true); -#else cString str = cString::sprintf(Message, ap); -#endif va_end(ap); if (Code >= 0 && m_LastCommand != NULL) { diff --git a/server/server.c b/server/server.c index 1bdb20a..c7fa96f 100644 --- a/server/server.c +++ b/server/server.c @@ -121,7 +121,9 @@ void cStreamdevServer::Action(void) cServerConnection *client = c->Accept(); if (!client) continue; + Lock(); m_Clients.Add(client); + Unlock(); if (m_Clients.Count() > StreamdevServerSetup.MaxClients) { esyslog("streamdev: too many clients, rejecting %s:%d", @@ -153,17 +155,21 @@ void cStreamdevServer::Action(void) isyslog("streamdev: closing streamdev connection to %s:%d", s->RemoteIp().c_str(), s->RemotePort()); s->Close(); + Lock(); m_Clients.Del(s); + Unlock(); } s = next; } } + Lock(); while (m_Clients.Count() > 0) { cServerConnection *s = m_Clients.First(); s->Close(); m_Clients.Del(s); } + Unlock(); while (m_Servers.Count() > 0) { cServerComponent *c = m_Servers.First(); @@ -171,3 +177,10 @@ void cStreamdevServer::Action(void) m_Servers.Del(c); } } + +void cStreamdevServer::MainThreadHook(void) +{ + cThreadLock lock(m_Instance); + for (cServerConnection *s = m_Clients.First(); s; s = m_Clients.Next(s)) + s->MainThreadHook(); +} diff --git a/server/server.h b/server/server.h index a44df1c..dfe9cc1 100644 --- a/server/server.h +++ b/server/server.h @@ -36,6 +36,7 @@ public: static void Initialize(void); static void Destruct(void); static bool Active(void); + static void MainThreadHook(void); }; inline bool cStreamdevServer::Active(void) diff --git a/server/streamdev-server.c b/server/streamdev-server.c index b444df7..0a98394 100644 --- a/server/streamdev-server.c +++ b/server/streamdev-server.c @@ -13,8 +13,8 @@ #include "server/server.h" #include "server/suspend.h" -#if !defined(APIVERSNUM) || APIVERSNUM < 10509 -#error "VDR-1.5.9 API version or greater is required!" +#if !defined(APIVERSNUM) || APIVERSNUM < 10516 +#error "VDR-1.5.16 API version or greater is required!" #endif const char *cPluginStreamdevServer::DESCRIPTION = trNOOP("VDR Streaming Server"); @@ -130,6 +130,11 @@ cOsdObject *cPluginStreamdevServer::MainMenuAction(void) return NULL; } +void cPluginStreamdevServer::MainThreadHook(void) +{ + cStreamdevServer::MainThreadHook(); +} + cMenuSetupPage *cPluginStreamdevServer::SetupMenu(void) { return new cStreamdevServerMenuSetupPage; diff --git a/server/streamdev-server.h b/server/streamdev-server.h index 4083689..f1be8aa 100644 --- a/server/streamdev-server.h +++ b/server/streamdev-server.h @@ -26,6 +26,7 @@ public: virtual cString Active(void); virtual const char *MainMenuEntry(void); virtual cOsdObject *MainMenuAction(void); + virtual void MainThreadHook(void); virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value); };