mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
				synced 2023-10-10 17:16:51 +00:00 
			
		
		
		
	Merge branch 'master' of projects.vdr-developer.org:vdr-plugin-streamdev
Conflicts: HISTORY
This commit is contained in:
		
							
								
								
									
										2
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,9 +49,7 @@ cStreamdevDevice::~cStreamdevDevice() {
 | 
			
		||||
 | 
			
		||||
	Cancel(3);
 | 
			
		||||
 | 
			
		||||
#if APIVERSNUM >= 10515
 | 
			
		||||
	StopSectionHandler();
 | 
			
		||||
#endif
 | 
			
		||||
	DELETENULL(m_Filters);
 | 
			
		||||
	DELETENULL(m_TSBuffer);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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");
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,60 @@
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#include <vdr/tools.h>
 | 
			
		||||
#include <vdr/thread.h>
 | 
			
		||||
#include <vdr/transfer.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ typedef std::pair<std::string,std::string> 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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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) 
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user