[vdr-plugin-streamdev] 01/06: New upstream version 0.6.1+git20170911

Tobias Grimm tiber-guest at moszumanska.debian.org
Wed Dec 27 17:25:44 UTC 2017


This is an automated email from the git hooks/post-receive script.

tiber-guest pushed a commit to branch master
in repository vdr-plugin-streamdev.

commit 3b560dfdc2089a7c3b25c759ce1ab68e5a1849f5
Author: Tobias Grimm <etobi at debian.org>
Date:   Mon Sep 11 21:43:43 2017 +0200

    New upstream version 0.6.1+git20170911
---
 CONTRIBUTORS              |   9 ++
 HISTORY                   |   5 +
 client/filter.c           |   3 +-
 libdvbmpeg/ctools.c       |   2 +-
 server/componentIGMP.c    |  27 +++++
 server/componentIGMP.h    |   5 +
 server/connection.c       |  15 +++
 server/connectionHTTP.c   |  10 ++
 server/connectionIGMP.c   |   4 +
 server/connectionIGMP.h   |   8 ++
 server/connectionVTP.c    | 268 ++++++++++++++++++++++++++++++++++++++++++++++
 server/livestreamer.c     |  32 +++++-
 server/livestreamer.h     |   4 +
 server/menu.c             |   8 ++
 server/menuHTTP.c         | 123 ++++++++++++++++++++-
 server/menuHTTP.h         |  10 ++
 server/server.c           |   4 +
 server/server.h           |   4 +
 server/streamdev-server.c |  16 +++
 server/streamdev-server.h |   4 +
 20 files changed, 553 insertions(+), 8 deletions(-)

diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index f057935..2a5155f 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -245,3 +245,12 @@ Toerless Eckert
 
 Tomasz Maciej Nowak
   for providing Polish language texts
+
+Christopher Reimer
+  for providing an initial compatibility patch for VDR 2.3.1
+
+Matthias Senzel
+  for refining the compatibility patch for VDR 2.3.1
+
+David Binderman
+  for fixing an lseek error check in libdvbmpeg
diff --git a/HISTORY b/HISTORY
index 8baed7d..cfed92c 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,11 @@
 VDR Plugin 'streamdev' Revision History
 ---------------------------------------
  
+- fixed lseek error check in libdvbmpeg (thanks to David Binderman)
+- server compatibility with VDR 2.3.1 (thanks to Christopher Reimer and
+  Matthias Senzel)
+- client compatibility with VDR 2.3.1
+- use cReceiver::SetPriority(...) in VDR 2.1.4+
 - doubled size of client's filter buffer (suggested by Toerless Eckert)
 - make sure TimedWrite(...) doesn't return failure after a slow but successful
   write operation (thanks to Toerless Eckert)
diff --git a/client/filter.c b/client/filter.c
index 94640d2..ffefa47 100644
--- a/client/filter.c
+++ b/client/filter.c
@@ -219,9 +219,8 @@ int cStreamdevFilters::OpenFilter(u_short Pid, u_char Tid, u_char Mask) {
 	cStreamdevFilter *f = new cStreamdevFilter(Pid, Tid, Mask);
 	int fh = f->ReadPipe();
 
-	Lock();
+	LOCK_THREAD;
 	Add(f);
-	Unlock();
 
 	return fh;
 }
diff --git a/libdvbmpeg/ctools.c b/libdvbmpeg/ctools.c
index 185ba45..f373204 100644
--- a/libdvbmpeg/ctools.c
+++ b/libdvbmpeg/ctools.c
@@ -558,7 +558,7 @@ int read_pes(int f, pes_packet *p){
 
 	while (neof > 0 && !found) {
 	        po = lseek(f,0,SEEK_CUR);
-		if (po < 0) return -1;
+		if (po == (off_t) -1) return -1;
 		if ((neof = save_read(f,&sync4,4)) < 4) return -1;
 		if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
 			p->stream_id = sync4[3];
diff --git a/server/componentIGMP.c b/server/componentIGMP.c
index 7398c67..52d2b5d 100644
--- a/server/componentIGMP.c
+++ b/server/componentIGMP.c
@@ -105,7 +105,11 @@ cComponentIGMP::~cComponentIGMP(void)
 {
 }
 
+#if APIVERSNUM >= 20300
+cMulticastGroup* cComponentIGMP::FindGroup(in_addr_t Group)
+#else
 cMulticastGroup* cComponentIGMP::FindGroup(in_addr_t Group) const
+#endif
 {
 	cMulticastGroup *group = m_Groups.First();
 	while (group && group->group != Group)
@@ -117,7 +121,12 @@ bool cComponentIGMP::Initialize(void)
 {
 	if (cServerComponent::Initialize() && IGMPMembership(IGMP_ALL_ROUTER))
 	{
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_READ;
+		for (const cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel))
+#else
 		for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
+#endif
 		{
 			if (channel->GroupSep())
 				continue;
@@ -146,7 +155,12 @@ void cComponentIGMP::Destruct(void)
 		Cancel(-1);
 		m_CondWait.Signal();
 		Cancel(2);
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_READ;
+		for (const cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel))
+#else
 		for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
+#endif
 		{
 			if (channel->GroupSep())
 				continue;
@@ -432,9 +446,18 @@ cServerConnection* cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group)
 	in_addr_t g = ntohl(Group->group);
 	if (g > MULTICAST_PRIV_MIN && g <= MULTICAST_PRIV_MAX) {
 		cThreadLock lock;
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_READ;
+		const cChannel *channel = Channels->GetByNumber(g - MULTICAST_PRIV_MIN);
+#else
 		cChannel *channel = Channels.GetByNumber(g - MULTICAST_PRIV_MIN);
+#endif
 		const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#if APIVERSNUM >= 20300
+		const cServerConnection *s = clients.First();
+#else
 		cServerConnection *s = clients.First();
+#endif
 		while (s) {
 			if (s->RemoteIpAddr() == Group->group)
 				break;
@@ -453,7 +476,11 @@ cServerConnection* cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group)
 void cComponentIGMP::IGMPStopMulticast(cMulticastGroup* Group)
 {
 	cThreadLock lock;
+#if APIVERSNUM >= 20300
+	cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#else
 	const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#endif
 	for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) {
 		if (s->RemoteIpAddr() == Group->group)
 			s->Close();
diff --git a/server/componentIGMP.h b/server/componentIGMP.h
index 8f6c027..d870b64 100644
--- a/server/componentIGMP.h
+++ b/server/componentIGMP.h
@@ -9,6 +9,7 @@
 #include <time.h>
 #include <vdr/thread.h>
 #include "server/component.h"
+#include "../common.h"
 
 class cMulticastGroup;
 
@@ -23,7 +24,11 @@ private:
 	bool m_Querier;
 	cCondWait m_CondWait;
 
+#if APIVERSNUM >= 20300
+	cMulticastGroup* FindGroup(in_addr_t Group);
+#else
 	cMulticastGroup* FindGroup(in_addr_t Group) const;
+#endif
 
 	/* Add or remove local host to multicast group */
 	bool IGMPMembership(in_addr_t Group, bool Add = true);
diff --git a/server/connection.c b/server/connection.c
index 56be407..0db382e 100644
--- a/server/connection.c
+++ b/server/connection.c
@@ -46,14 +46,29 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
 		int temp = strtol(String, NULL, 10);
 		if (temp == 0)
 			temp = cDevice::CurrentChannel();
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_READ;
+		if (temp >= 1 && temp <= Channels->MaxNumber())
+			channel = Channels->GetByNumber(temp);
+#else
 		if (temp >= 1 && temp <= Channels.MaxNumber())
 			channel = Channels.GetByNumber(temp);
+#endif
 	} else {
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_READ;
+		channel = Channels->GetByChannelID(tChannelID::FromString(string));
+#else
 		channel = Channels.GetByChannelID(tChannelID::FromString(string));
+#endif
 
 		if (channel == NULL) {
 			int i = 1;
+#if APIVERSNUM >= 20300
+			while ((channel = Channels->GetByNumber(i, 1)) != NULL) {
+#else
 			while ((channel = Channels.GetByNumber(i, 1)) != NULL) {
+#endif
 				if (String == channel->Name())
 					break;
 
diff --git a/server/connectionHTTP.c b/server/connectionHTTP.c
index 922bd04..b139c9b 100644
--- a/server/connectionHTTP.c
+++ b/server/connectionHTTP.c
@@ -523,8 +523,13 @@ RecPlayer* cConnectionHTTP::RecPlayerFromString(const char *FileBase, const char
 			ino_t inode = (ino_t) strtoull(p + 1, &p, 0);
 			if (*p == 0 && inode > 0) {
 				struct stat st;
+#if APIVERSNUM >= 20300
+				LOCK_RECORDINGS_READ;
+				for (const cRecording *rec = Recordings->First(); rec; rec = Recordings->Next(rec)) {
+#else
 				cThreadLock RecordingsLock(&Recordings);
 				for (cRecording *rec = Recordings.First(); rec; rec = Recordings.Next(rec)) {
+#endif
 					if (stat(rec->FileName(), &st) == 0 && st.st_dev == (dev_t) l && st.st_ino == inode)
 						recPlayer = new RecPlayer(rec->FileName());
 				}
@@ -532,8 +537,13 @@ RecPlayer* cConnectionHTTP::RecPlayerFromString(const char *FileBase, const char
 		}
 		else if (*p == 0) {
 			// get recording by index
+#if APIVERSNUM >= 20300
+			LOCK_RECORDINGS_READ;
+			const cRecording *rec = Recordings->Get((int) l - 1);
+#else
 			cThreadLock RecordingsLock(&Recordings);
 			cRecording *rec = Recordings.Get((int) l - 1);
+#endif
 			if (rec)
 				recPlayer = new RecPlayer(rec->FileName());
 		}
diff --git a/server/connectionIGMP.c b/server/connectionIGMP.c
index f2a34fc..53d2af4 100644
--- a/server/connectionIGMP.c
+++ b/server/connectionIGMP.c
@@ -21,7 +21,11 @@ cConnectionIGMP::~cConnectionIGMP()
 {
 }
 
+#if APIVERSNUM >= 20300
+bool cConnectionIGMP::SetChannel(const cChannel *Channel, in_addr_t Dst)
+#else
 bool cConnectionIGMP::SetChannel(cChannel *Channel, in_addr_t Dst)
+#endif
 {
 	if (Channel) {
 		m_Channel = Channel;
diff --git a/server/connectionIGMP.h b/server/connectionIGMP.h
index 89292b2..ef9ea40 100644
--- a/server/connectionIGMP.h
+++ b/server/connectionIGMP.h
@@ -19,13 +19,21 @@ class cConnectionIGMP: public cServerConnection {
 private:
 	int                               m_ClientPort;
 	eStreamType                       m_StreamType;
+#if APIVERSNUM >= 20300
+	const cChannel                   *m_Channel;
+#else
 	cChannel                         *m_Channel;
+#endif
 
 public:
 	cConnectionIGMP(const char* Name, int ClientPort, eStreamType StreamType);
 	virtual ~cConnectionIGMP();
 
+#if APIVERSNUM >= 20300
+	bool SetChannel(const cChannel *Channel, in_addr_t Dst);
+#else
 	bool SetChannel(cChannel *Channel, in_addr_t Dst);
+#endif
 	virtual void Welcome(void);
 	virtual cString ToText(char Delimiter = ' ') const;
 
diff --git a/server/connectionVTP.c b/server/connectionVTP.c
index 05c49ee..1b8dd96 100644
--- a/server/connectionVTP.c
+++ b/server/connectionVTP.c
@@ -58,8 +58,10 @@ public:
 
 cLSTEHandler::cLSTEHandler(cConnectionVTP *Client, const char *Option):
 		m_Client(Client),
+#if APIVERSNUM < 20300
 		m_SchedulesLock(new cSchedulesLock(false, 500)),
 		m_Schedules(cSchedules::Schedules(*m_SchedulesLock)),
+#endif
 		m_Schedule(NULL),
 		m_Event(NULL),
 		m_Errno(0),
@@ -131,11 +133,20 @@ cLSTEHandler::cLSTEHandler(cConnectionVTP *Client, const char *Option):
 					break;
 				}
 			} else if (!m_Schedule) {
+#if APIVERSNUM >= 20300
+				LOCK_CHANNELS_READ;
+				const cChannel* Channel = NULL;
+				if (isnumber(p))
+					Channel = Channels->GetByNumber(strtol(Option, NULL, 10));
+				else
+					Channel = Channels->GetByChannelID(tChannelID::FromString(
+#else
 				cChannel* Channel = NULL;
 				if (isnumber(p))
 					Channel = Channels.GetByNumber(strtol(Option, NULL, 10));
 				else
 					Channel = Channels.GetByChannelID(tChannelID::FromString(
+#endif
 					                                  Option));
 				if (Channel) {
 					m_Schedule = m_Schedules->GetSchedule(Channel->GetChannelID());
@@ -215,7 +226,12 @@ bool cLSTEHandler::Next(bool &Last)
 	switch (m_State) {
 	case Channel:
 		if (m_Schedule != NULL) {
+#if APIVERSNUM >= 20300
+			LOCK_CHANNELS_READ;
+			const cChannel *channel = Channels->GetByChannelID(m_Schedule->ChannelID(),
+#else
 			cChannel *channel = Channels.GetByChannelID(m_Schedule->ChannelID(),
+#endif
 			                                            true);
 			if (channel != NULL) {
 				m_State = Event;
@@ -371,12 +387,21 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
 		m_Errno(0),
 		m_Traverse(false)
 {
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	if (!Channels) {
+#else
 	if (!Channels.Lock(false, 500)) {
+#endif
 		m_Errno = 451;
 		m_Error = "Channels are being modified - try again";
 	} else if (*Option) {
 		if (isnumber(Option)) {
+#if APIVERSNUM >= 20300
+			m_Channel = Channels->GetByNumber(strtol(Option, NULL, 10));
+#else
 			m_Channel = Channels.GetByNumber(strtol(Option, NULL, 10));
+#endif
 			if (m_Channel == NULL) {
 				m_Errno = 501;
 				m_Error = cString::sprintf("Channel \"%s\" not defined", Option);
@@ -386,21 +411,35 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
 			int i = 1;
 			m_Traverse = true;
 			m_Option = strdup(Option);
+#if APIVERSNUM >= 20300
+			while (i <= Channels->MaxNumber()) {
+				m_Channel = Channels->GetByNumber(i, 1);
+#else
 			while (i <= Channels.MaxNumber()) {
 				m_Channel = Channels.GetByNumber(i, 1);
+#endif
 				if (strcasestr(m_Channel->Name(), Option) != NULL)
 					break;
 				i = m_Channel->Number() + 1;
 			}
 
+#if APIVERSNUM >= 20300
+			if (i > Channels->MaxNumber()) {
+#else
 			if (i > Channels.MaxNumber()) {
+#endif
 				m_Errno = 501;
 				m_Error = cString::sprintf("Channel \"%s\" not defined", Option);
 				return;
 			}
 		}
+#if APIVERSNUM >= 20300
+	} else if (Channels->MaxNumber() >= 1) {
+		m_Channel = Channels->GetByNumber(1, 1);
+#else
 	} else if (Channels.MaxNumber() >= 1) {
 		m_Channel = Channels.GetByNumber(1, 1);
+#endif
 		m_Traverse = true;
 	} else {
 		m_Errno = 550;
@@ -410,7 +449,9 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
 
 cLSTCHandler::~cLSTCHandler()
 {
+#if APIVERSNUM < 20300
 	Channels.Unlock();
+#endif
 	if (m_Option != NULL)
 		free(m_Option);
 }
@@ -435,8 +476,14 @@ bool cLSTCHandler::Next(bool &Last)
 	Last = true;
 	if (m_Traverse) {
 		int i = m_Channel->Number() + 1;
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_READ;
+		while (i <= Channels->MaxNumber()) {
+			m_Channel = Channels->GetByNumber(i, 1);
+#else
 		while (i <= Channels.MaxNumber()) {
 			m_Channel = Channels.GetByNumber(i, 1);
+#endif
 			if (m_Channel != NULL) {
 				if (m_Option == NULL || strcasestr(m_Channel->Name(), 
 												   m_Option) != NULL)
@@ -448,7 +495,11 @@ bool cLSTCHandler::Next(bool &Last)
 			}
 		}
 
+#if APIVERSNUM >= 20300
+		if (i < Channels->MaxNumber() + 1)
+#else
 		if (i < Channels.MaxNumber() + 1)
+#endif
 			Last = false;
 	}
 
@@ -461,7 +512,11 @@ class cLSTTHandler
 {
 private:
 	cConnectionVTP *m_Client;
+#if APIVERSNUM >= 20300
+	const cTimer   *m_Timer;
+#else
 	cTimer         *m_Timer;
+#endif
 	int             m_Index;
 	int             m_Errno;
 	cString         m_Error;
@@ -479,9 +534,16 @@ cLSTTHandler::cLSTTHandler(cConnectionVTP *Client, const char *Option):
 		m_Errno(0),
 		m_Traverse(false)
 {
+#if APIVERSNUM >= 20300
+	LOCK_TIMERS_READ;
+#endif
 	if (*Option) {
 		if (isnumber(Option)) {
+#if APIVERSNUM >= 20300
+			m_Timer = Timers->Get(strtol(Option, NULL, 10) - 1);
+#else
 			m_Timer = Timers.Get(strtol(Option, NULL, 10) - 1);
+#endif
 			if (m_Timer == NULL) {
 				m_Errno = 501;
 				m_Error = cString::sprintf("Timer \"%s\" not defined", Option);
@@ -490,10 +552,18 @@ cLSTTHandler::cLSTTHandler(cConnectionVTP *Client, const char *Option):
 			m_Errno = 501;
 			m_Error = cString::sprintf("Error in timer number \"%s\"", Option);
 		}
+#if APIVERSNUM >= 20300
+	} else if (Timers->Count()) {
+#else
 	} else if (Timers.Count()) {
+#endif
 		m_Traverse = true;
 		m_Index = 0;
+#if APIVERSNUM >= 20300
+		m_Timer = Timers->Get(m_Index);
+#else
 		m_Timer = Timers.Get(m_Index);
+#endif
 		if (m_Timer == NULL) {
 			m_Errno = 501;
 			m_Error = cString::sprintf("Timer \"%d\" not found", m_Index + 1);
@@ -519,7 +589,12 @@ bool cLSTTHandler::Next(bool &Last)
 
 	bool result;
 	char *buffer;
+#if APIVERSNUM >= 20300
+	LOCK_TIMERS_READ;
+	Last = !m_Traverse || m_Index >= Timers->Count() - 1;
+#else
 	Last = !m_Traverse || m_Index >= Timers.Count() - 1;
+#endif
 	buffer = strdup(*m_Timer->ToText());
 	buffer[strlen(buffer) - 1] = '\0'; // strip \n
 	result = m_Client->Respond(Last ? 250 : -250, "%d %s", m_Timer->Index() + 1,
@@ -527,7 +602,11 @@ bool cLSTTHandler::Next(bool &Last)
 	free(buffer);
 
 	if (m_Traverse && !Last) {
+#if APIVERSNUM >= 20300
+		m_Timer = Timers->Get(++m_Index);
+#else
 		m_Timer = Timers.Get(++m_Index);
+#endif
 		if (m_Timer == NULL) {
 			m_Errno = 501;
 			m_Error = cString::sprintf("Timer \"%d\" not found", m_Index + 1);
@@ -544,7 +623,11 @@ private:
 	enum eStates { Recording, Event, Title, Subtitle, Description, Components, Vps, 
 	               EndRecording };
 	cConnectionVTP *m_Client;
+#if APIVERSNUM >= 20300
+	const cRecording     *m_Recording;
+#else
 	cRecording     *m_Recording;
+#endif
 	const cEvent   *m_Event;
 	int             m_Index;
 	int             m_Errno;
@@ -570,9 +653,16 @@ cLSTRHandler::cLSTRHandler(cConnectionVTP *Client, const char *Option):
 		m_State(Recording),
 		m_CurrentComponent(0)
 {
+#if APIVERSNUM >= 20300
+	LOCK_RECORDINGS_READ;
+#endif
 	if (*Option) {
 		if (isnumber(Option)) {
+#if APIVERSNUM >= 20300
+			m_Recording = Recordings->Get(strtol(Option, NULL, 10) - 1);
+#else
 			m_Recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
+#endif
 			m_Event = m_Recording->Info()->GetEvent();
 			m_Info = true;
 			if (m_Recording == NULL) {
@@ -585,10 +675,18 @@ cLSTRHandler::cLSTRHandler(cConnectionVTP *Client, const char *Option):
 			m_Error = cString::sprintf("Error in Recording number \"%s\"", Option);
 		}
 	} 
+#if APIVERSNUM >= 20300 
+	else if (Recordings->Count()) {
+#else
 	else if (Recordings.Count()) {
+#endif
 		m_Traverse = true;
 		m_Index = 0;
+#if APIVERSNUM >= 20300
+		m_Recording = Recordings->Get(m_Index);
+#else
 		m_Recording = Recordings.Get(m_Index);
+#endif
 		if (m_Recording == NULL) {
 			m_Errno = 501;
 			m_Error = cString::sprintf("Recording \"%d\" not found", m_Index + 1);
@@ -691,11 +789,20 @@ bool cLSTRHandler::Next(bool &Last)
 	}
 	else {
 		bool result;
+#if APIVERSNUM >= 20300
+		LOCK_RECORDINGS_READ;
+		Last = !m_Traverse || m_Index >= Recordings->Count() - 1;
+#else
 		Last = !m_Traverse || m_Index >= Recordings.Count() - 1;
+#endif
 		result = m_Client->Respond(Last ? 250 : -250, "%d %s", m_Recording->Index() + 1, m_Recording->Title(' ', true));
 
 		if (m_Traverse && !Last) {
+#if APIVERSNUM >= 20300
+			m_Recording = Recordings->Get(++m_Index);
+#else
 			m_Recording = Recordings.Get(++m_Index);
+#endif
 			if (m_Recording == NULL) {
 				m_Errno = 501;
 				m_Error = cString::sprintf("Recording \"%d\" not found", m_Index + 1);
@@ -1145,7 +1252,12 @@ bool cConnectionVTP::CmdPLAY(char *Opts)
 {
 	if (*Opts) {
 		if (isnumber(Opts)) {
+#if APIVERSNUM >= 20300
+			LOCK_RECORDINGS_READ;
+			const cRecording *recording = Recordings->Get(strtol(Opts, NULL, 10) - 1);
+#else
 			cRecording *recording = Recordings.Get(strtol(Opts, NULL, 10) - 1);
+#endif
 			if (recording) {
 				if (m_RecPlayer) {
 					delete m_RecPlayer;
@@ -1391,10 +1503,17 @@ bool cConnectionVTP::CmdSTAT(const char *Option)
 			Reply(250, "VDR: %s | Streamdev: %s", VDRVERSION, VERSION);
 		}
 		else if (strcasecmp(Option, "RECORDS") == 0) {
+#if APIVERSNUM >= 20300
+			LOCK_RECORDINGS_WRITE;
+			Recordings->Sort();
+			if (Recordings) {
+				cRecording *recording = Recordings->Last();
+#else
 			bool recordings = Recordings.Load();
 			Recordings.Sort();
 			if (recordings) {
 				cRecording *recording = Recordings.Last();
+#endif
 				Reply(250, "%d", recording->Index() + 1);
 			}
 			else {
@@ -1402,10 +1521,20 @@ bool cConnectionVTP::CmdSTAT(const char *Option)
 			}
 		}
 		else if (strcasecmp(Option, "CHANNELS") == 0) {
+#if APIVERSNUM >= 20300 
+			LOCK_CHANNELS_READ;
+			Reply(250, "%d", Channels->MaxNumber());
+#else
 			Reply(250, "%d", Channels.MaxNumber());
+#endif
 		}
 		else if (strcasecmp(Option, "TIMERS") == 0) {
+#if APIVERSNUM >= 20300 
+			LOCK_TIMERS_READ;
+			Reply(250, "%d", Timers->Count());
+#else
 			Reply(250, "%d", Timers.Count());
+#endif
 		}
 		else if (strcasecmp(Option, "CHARSET") == 0) {
 			Reply(250, "%s", cCharSetConv::SystemCharacterTable());
@@ -1433,7 +1562,12 @@ bool cConnectionVTP::CmdMODT(const char *Option)
 		int n = strtol(Option, &tail, 10);
 		if (tail && tail != Option) {
 			tail = skipspace(tail);
+#if APIVERSNUM >= 20300
+			LOCK_TIMERS_WRITE;
+			cTimer *timer = Timers->Get(n - 1);
+#else
 			cTimer *timer = Timers.Get(n - 1);
+#endif
 			if (timer) {
 				cTimer t = *timer;
 				if (strcasecmp(tail, "ON") == 0)
@@ -1445,7 +1579,11 @@ bool cConnectionVTP::CmdMODT(const char *Option)
 					EXIT_WRAPPER();
 				}
 				*timer = t;
+#if APIVERSNUM >= 20300
+				Timers->SetModified();
+#else
 				Timers.SetModified();
+#endif
 				isyslog("timer %s modified (%s)", *timer->ToDescr(), 
 				        timer->HasFlags(tfActive) ? "active" : "inactive");
 				Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
@@ -1464,10 +1602,18 @@ bool cConnectionVTP::CmdNEWT(const char *Option)
 	if (*Option) {
 		cTimer *timer = new cTimer;
 		if (timer->Parse(Option)) {
+#if APIVERSNUM >= 20300
+			LOCK_TIMERS_WRITE;
+			cTimer *t = Timers->GetTimer(timer);
+			if (!t) {
+				Timers->Add(timer);
+				Timers->SetModified();
+#else
 			cTimer *t = Timers.GetTimer(timer);
 			if (!t) {
 				Timers.Add(timer);
 				Timers.SetModified();
+#endif
 				isyslog("timer %s added", *timer->ToDescr());
 				Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
 				EXIT_WRAPPER();
@@ -1512,21 +1658,39 @@ bool cConnectionVTP::CmdDELT(const char *Option)
 			}
 		}
 
+#if APIVERSNUM >= 20300
+		LOCK_TIMERS_WRITE;
+		cTimer *Timer = Timers->Get(number);
+			if (Timer) {
+			if (Timer->Recording()) {
+				if (force) {
+					if (!Timer->Remote()) {
+						Timer->Skip();
+						cRecordControls::Process(Timers, time(NULL));
+					}
+#else
 		cTimer *timer = Timers.Get(number);
 			if (timer) {
 			if (timer->Recording()) {
 				if (force) {
 					timer->Skip();
 					cRecordControls::Process(time(NULL));
+#endif
 				}
 				else {
 					Reply(550, "Timer \"%i\" is recording", number);
 					EXIT_WRAPPER();
 				}
 			}
+#if APIVERSNUM >= 20300
+					isyslog("deleting timer %s", *Timer->ToDescr());
+					Timers->Del(Timer);
+					Timers->SetModified();
+#else
 					isyslog("deleting timer %s", *timer->ToDescr());
 					Timers.Del(timer);
 					Timers.SetModified();
+#endif
 			Reply(250, "Timer \"%i\" deleted", number);
 				} else
 			Reply(501, "Timer \"%i\" not defined", number);
@@ -1538,7 +1702,12 @@ bool cConnectionVTP::CmdDELT(const char *Option)
 bool cConnectionVTP::CmdNEXT(const char *Option)
 {
 	INIT_WRAPPER();
+#if APIVERSNUM >= 20300
+	LOCK_TIMERS_READ;
+	const cTimer *t = Timers->GetNextActiveTimer();
+#else
 	cTimer *t = Timers.GetNextActiveTimer();
+#endif
 	if (t) {
 		time_t Start = t->StartTime();
 		int Number = t->Index() + 1;
@@ -1562,12 +1731,23 @@ bool cConnectionVTP::CmdNEWC(const char *Option)
 	if (*Option) {
 		cChannel ch;
 		if (ch.Parse(Option)) {
+#if APIVERSNUM >= 20300
+			LOCK_CHANNELS_WRITE;
+			if (Channels->HasUniqueChannelID(&ch)) {
+#else
 			if (Channels.HasUniqueChannelID(&ch)) {
+#endif
 				cChannel *channel = new cChannel;
 				*channel = ch;
+#if APIVERSNUM >= 20300 
+				Channels->Add(channel);
+				Channels->ReNumber();
+				Channels->SetModified();
+#else
 				Channels.Add(channel);
 				Channels.ReNumber();
 				Channels.SetModified(true);
+#endif
 				isyslog("new channel %d %s", channel->Number(), *channel->ToText());
 				Reply(250, "%d %s", channel->Number(), *channel->ToText());
 			}
@@ -1593,15 +1773,28 @@ bool cConnectionVTP::CmdMODC(const char *Option)
 		int n = strtol(Option, &tail, 10);
 		if (tail && tail != Option) {
 			tail = skipspace(tail);
+#if APIVERSNUM >= 20300         
+			LOCK_CHANNELS_WRITE;
+			Channels->SetExplicitModify();
+				cChannel *channel = Channels->GetByNumber(n);
+#else
 			if (!Channels.BeingEdited()) {
 				cChannel *channel = Channels.GetByNumber(n);
+#endif
 				if (channel) {
 					cChannel ch;
 					if (ch.Parse(tail)) {
+#if APIVERSNUM >= 20300         
+						if (Channels->HasUniqueChannelID(&ch, channel)) {
+							*channel = ch;
+							Channels->ReNumber();
+							Channels->SetModified();
+#else
 						if (Channels.HasUniqueChannelID(&ch, channel)) {
 							*channel = ch;
 							Channels.ReNumber();
 							Channels.SetModified(true);
+#endif
 							isyslog("modifed channel %d %s", channel->Number(), *channel->ToText());
 							Reply(250, "%d %s", channel->Number(), *channel->ToText());
 						}
@@ -1616,10 +1809,12 @@ bool cConnectionVTP::CmdMODC(const char *Option)
 				else {
 					Reply(501, "Channel \"%d\" not defined", n);
 				}
+#if APIVERSNUM < 20300
 			}
 			else {
 				Reply(550, "Channels are being edited - try again later");
 			}
+#endif
 		}
 		else {
 			Reply(501, "Error in channel number");
@@ -1635,7 +1830,14 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
 {
 	INIT_WRAPPER();
 	if (*Option) {
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_WRITE;
+		Channels->SetExplicitModify();
+//		LOCK_TIMERS_WRITE;
+//		Timers->SetExplicitModify();
+#else
 		if (!Channels.BeingEdited() && !Timers.BeingEdited()) {
+#endif
 			char *tail;
 			int From = strtol(Option, &tail, 10);
 			if (tail && tail != Option) {
@@ -1643,20 +1845,37 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
 				if (tail && tail != Option) {
 					int To = strtol(tail, NULL, 10);
 					int CurrentChannelNr = cDevice::CurrentChannel();
+#if APIVERSNUM >= 20300
+					cChannel *CurrentChannel = Channels->GetByNumber(CurrentChannelNr);
+					cChannel *FromChannel = Channels->GetByNumber(From);
+					if (FromChannel) {
+						cChannel *ToChannel = Channels->GetByNumber(To);
+#else
 					cChannel *CurrentChannel = Channels.GetByNumber(CurrentChannelNr);
 					cChannel *FromChannel = Channels.GetByNumber(From);
 					if (FromChannel) {
 						cChannel *ToChannel = Channels.GetByNumber(To);
+#endif
 						if (ToChannel) {
 							int FromNumber = FromChannel->Number();
 							int ToNumber = ToChannel->Number();
 							if (FromNumber != ToNumber) {
+#if APIVERSNUM >= 20300
+								Channels->Move(FromChannel, ToChannel);
+								Channels->ReNumber();
+								Channels->SetModified();
+#else
 								Channels.Move(FromChannel, ToChannel);
 								Channels.ReNumber();
 								Channels.SetModified(true);
+#endif
 								if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) {
 									if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) {
+#if APIVERSNUM >= 20300
+										Channels->SwitchTo(CurrentChannel->Number());
+#else
 										Channels.SwitchTo(CurrentChannel->Number());
+#endif
 									}
 									else {
 										cDevice::SetCurrentChannel(CurrentChannel);
@@ -1684,10 +1903,12 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
 			else {
 				Reply(501, "Error in channel number");
 			}
+#if APIVERSNUM < 20300
 		}
 		else {
 			Reply(550, "Channels or timers are being edited - try again later");
 		}
+#endif
 	}
 	else {
 		Reply(501, "Missing channel number");
@@ -1700,31 +1921,63 @@ bool cConnectionVTP::CmdDELC(const char *Option)
 	INIT_WRAPPER();
 	if (*Option) {
 		if (isnumber(Option)) {
+#if APIVERSNUM >= 20300
+			LOCK_CHANNELS_WRITE;
+			Channels->SetExplicitModify();
+			cChannel *channel = Channels->GetByNumber(strtol(Option, NULL, 10));
+#else
 			if (!Channels.BeingEdited()) {
 				cChannel *channel = Channels.GetByNumber(strtol(Option, NULL, 10));
+#endif
 				if (channel) {
+#if APIVERSNUM >= 20300
+					LOCK_TIMERS_READ;
+					for (const cTimer *timer = Timers->First(); timer; timer = Timers->Next(timer)) {
+#else
 					for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) {
+#endif
 						if (timer->Channel() == channel) {
 							Reply(550, "Channel \"%s\" is in use by timer %d", Option, timer->Index() + 1);
 							return false;
 						}
 					}
 					int CurrentChannelNr = cDevice::CurrentChannel();
+#if APIVERSNUM >= 20300
+					cChannel *CurrentChannel = Channels->GetByNumber(CurrentChannelNr);
+#else
 					cChannel *CurrentChannel = Channels.GetByNumber(CurrentChannelNr);
+#endif
 					if (CurrentChannel && channel == CurrentChannel) {
+#if APIVERSNUM >= 20300
+						int n = Channels->GetNextNormal(CurrentChannel->Index());
+						if (n < 0)
+							n = Channels->GetPrevNormal(CurrentChannel->Index());
+						CurrentChannel = Channels->Get(n);
+#else
 						int n = Channels.GetNextNormal(CurrentChannel->Index());
 						if (n < 0)
 							n = Channels.GetPrevNormal(CurrentChannel->Index());
 						CurrentChannel = Channels.Get(n);
+#endif
 						CurrentChannelNr = 0; // triggers channel switch below
 					}
+#if APIVERSNUM >= 20300
+					Channels->Del(channel);
+					Channels->ReNumber();
+					Channels->SetModified();
+#else
 					Channels.Del(channel);
 					Channels.ReNumber();
 					Channels.SetModified(true);
+#endif
 					isyslog("channel %s deleted", Option);
 					if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) {
 						if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring())
+#if APIVERSNUM >= 20300
+							Channels->SwitchTo(CurrentChannel->Number());
+#else
 							Channels.SwitchTo(CurrentChannel->Number());
+#endif
 						else
 							cDevice::SetCurrentChannel(CurrentChannel);
 					}
@@ -1733,9 +1986,11 @@ bool cConnectionVTP::CmdDELC(const char *Option)
 				else
 					Reply(501, "Channel \"%s\" not defined", Option);
 			}
+#if APIVERSNUM < 20300
 			else
 				Reply(550, "Channels are being edited - try again later");
 		}
+#endif
 		else
 			Reply(501, "Error in channel number \"%s\"", Option);
 	}
@@ -1750,13 +2005,22 @@ bool cConnectionVTP::CmdDELR(const char *Option)
 	INIT_WRAPPER();
 	if (*Option) {
 		if (isnumber(Option)) {
+#if APIVERSNUM >= 20300
+			LOCK_RECORDINGS_WRITE;
+			cRecording *recording = Recordings->Get(strtol(Option, NULL, 10) - 1);
+#else
 			cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
+#endif
 			if (recording) {
 				cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
 				if (!rc) {
 					if (recording->Delete()) {
 						Reply(250, "Recording \"%s\" deleted", Option);
+#if APIVERSNUM >= 20300
+						Recordings->DelByName(recording->FileName());
+#else
 						::Recordings.DelByName(recording->FileName());
+#endif
 					}
 					else
 						Reply(554, "Error while deleting recording!");
@@ -1765,7 +2029,11 @@ bool cConnectionVTP::CmdDELR(const char *Option)
 					Reply(550, "Recording \"%s\" is in use by timer %d", Option, rc->Timer()->Index() + 1);
 			}
 			else
+#if APIVERSNUM >= 20300
+				Reply(550, "Recording \"%s\" not found%s", Option, Recordings->Count() ? "" : " (use LSTR before deleting)");
+#else
 				Reply(550, "Recording \"%s\" not found%s", Option, Recordings.Count() ? "" : " (use LSTR before deleting)");
+#endif
 		}
 		else
 			Reply(501, "Error in recording number \"%s\"", Option);
diff --git a/server/livestreamer.c b/server/livestreamer.c
index 41befe4..41f7d2d 100644
--- a/server/livestreamer.c
+++ b/server/livestreamer.c
@@ -31,7 +31,11 @@ private:
 	cStreamdevLiveStreamer *m_Streamer;
 
 protected:
+#if APIVERSNUM >= 20300
+	virtual void Receive(const uchar *Data, int Length);
+#else
 	virtual void Receive(uchar *Data, int Length);
+#endif
 
 public:
 	cStreamdevLiveReceiver(cStreamdevLiveStreamer *Streamer, const cChannel *Channel, int Priority, const int *Pids);
@@ -53,7 +57,11 @@ cStreamdevLiveReceiver::~cStreamdevLiveReceiver()
 	Detach();
 }
 
+#if APIVERSNUM >= 20300
+void cStreamdevLiveReceiver::Receive(const uchar *Data, int Length) {
+#else
 void cStreamdevLiveReceiver::Receive(uchar *Data, int Length) {
+#endif
 	m_Streamer->Receive(Data, Length);
 }
 
@@ -250,7 +258,12 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
 			SI::PAT::Association assoc;
 			for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) {
 				if (!assoc.isNITPid()) {
+#if APIVERSNUM >= 20300
+					LOCK_CHANNELS_READ;
+					const cChannel *Channel =  Channels->GetByServiceID(Source(), Transponder(), assoc.getServiceId());
+#else
 					const cChannel *Channel =  Channels.GetByServiceID(Source(), Transponder(), assoc.getServiceId());
+#endif
 					if (Channel && (Channel == m_Channel)) {
 						int prevPmtPid = pmtPid;
 						if (0 != (pmtPid = assoc.getPid())) {
@@ -443,7 +456,13 @@ bool cStreamdevLiveStreamer::SetPids(int Pid, const int *Pids1, const int *Pids2
 void cStreamdevLiveStreamer::SetPriority(int Priority)
 {
 	m_Priority = Priority;
-	StartReceiver();
+#if VDRVERSNUM >= 20104
+	cThreadLock ThreadLock(m_Device);
+	if (m_Receiver)
+		m_Receiver->SetPriority(Priority);
+	else
+#endif
+		StartReceiver();
 }
 
 void cStreamdevLiveStreamer::GetSignal(int *DevNum, int *Strength, int *Quality) const
@@ -541,7 +560,11 @@ bool cStreamdevLiveStreamer::SetChannel(eStreamType StreamType, const int* Apid,
 	}
 }
 
+#if APIVERSNUM >= 20300                 
+void cStreamdevLiveStreamer::Receive(const uchar *Data, int Length)
+#else
 void cStreamdevLiveStreamer::Receive(uchar *Data, int Length)
+#endif
 {
 	int p = m_ReceiveBuffer->PutTS(Data, Length);
 	if (p != Length)
@@ -682,9 +705,16 @@ void cStreamdevLiveStreamer::MainThreadHook()
 	}
 	if (m_SwitchLive) {
 		// switched away live TV. Try previous channel on other device first
+#if APIVERSNUM >= 20300                 
+		LOCK_CHANNELS_READ;
+		if (!Channels->SwitchTo(cDevice::CurrentChannel())) {
+			// switch to streamdev channel otherwise
+			Channels->SwitchTo(m_Channel->Number());
+#else
 		if (!Channels.SwitchTo(cDevice::CurrentChannel())) {
 			// switch to streamdev channel otherwise
 			Channels.SwitchTo(m_Channel->Number());
+#endif
 			Skins.Message(mtInfo, tr("Streaming active"));
 		}
 		if (m_Device)
diff --git a/server/livestreamer.h b/server/livestreamer.h
index b525c7b..a671bd1 100644
--- a/server/livestreamer.h
+++ b/server/livestreamer.h
@@ -64,7 +64,11 @@ public:
 	void GetSignal(int *DevNum, int *Strength, int *Quality) const;
 	virtual cString ToText() const;
 	
+#if APIVERSNUM >= 20300
+	void Receive(const uchar *Data, int Length);
+#else
 	void Receive(uchar *Data, int Length);
+#endif
 	virtual bool IsReceiving(void) const;
 
 	virtual void Attach(void);
diff --git a/server/menu.c b/server/menu.c
index d5f0c7e..18c6764 100644
--- a/server/menu.c
+++ b/server/menu.c
@@ -13,7 +13,11 @@
 
 cStreamdevServerMenu::cStreamdevServerMenu(): cOsdMenu(tr("Streamdev Connections"), 4, 20) {
 	cThreadLock lock;
+#if APIVERSNUM >= 20300
+	cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#else
 	const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#endif
 	for (cServerConnection *s = clients.First(); s; s = clients.Next(s))
 		Add(new cOsdItem(s->ToText('\t')));
 	SetHelpKeys();
@@ -31,7 +35,11 @@ eOSState cStreamdevServerMenu::Disconnect() {
 	cOsdItem *item = Get(Current());
 	if (item) {
 		cThreadLock lock;
+#if APIVERSNUM >= 20300
+		cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#else
 		const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#endif
 		const char *text = item->Text();
 		for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) {
 			if (!strcmp(text, s->ToText('\t'))) {
diff --git a/server/menuHTTP.c b/server/menuHTTP.c
index 05315ea..e075d4d 100644
--- a/server/menuHTTP.c
+++ b/server/menuHTTP.c
@@ -6,10 +6,19 @@
 #include "server/menuHTTP.h"
 
 //**************************** cRecordingIterator **************
+#if APIVERSNUM >= 20300
+cRecordingsIterator::cRecordingsIterator(eStreamType StreamType)
+#else
 cRecordingsIterator::cRecordingsIterator(eStreamType StreamType): RecordingsLock(&Recordings)
+#endif
 {	
 	streamType = StreamType;
+#if APIVERSNUM >= 20300
+	LOCK_RECORDINGS_READ;
+	first = NextSuitable(Recordings->First());
+#else
 	first = NextSuitable(Recordings.First());
+#endif
 	current = NULL;
 }
 
@@ -20,20 +29,32 @@ const cRecording* cRecordingsIterator::NextSuitable(const cRecording *Recording)
 		bool isPes = Recording->IsPesRecording();
 		if (!isPes || (isPes && streamType == stPES))
 			break;
+#if APIVERSNUM >= 20300
+		LOCK_RECORDINGS_READ;
+		Recording = Recordings->Next(Recording);
+#else
 		Recording = Recordings.Next(Recording);
+#endif
 	}
 	return Recording;
 }
 
 bool cRecordingsIterator::Next()
 {
+#if APIVERSNUM >= 20300
+	LOCK_RECORDINGS_READ;
+#endif
 	if (first)
 	{
 		current = first;
 		first = NULL;
 	}
 	else
+#if APIVERSNUM >= 20300
+		current = NextSuitable(Recordings->Next(current));
+#else
 		current = NextSuitable(Recordings.Next(current));
+#endif
 	return current;
 }
 
@@ -71,9 +92,16 @@ const cString cChannelIterator::ItemId() const
 		if (current->GroupSep())
 		{
 			int index = 0;
+#if APIVERSNUM >= 20300
+			LOCK_CHANNELS_READ;
+			for (int curr = Channels->GetNextGroup(-1); curr >= 0; curr = Channels->GetNextGroup(curr))
+			{
+				if (Channels->Get(curr) == current)
+#else
 			for (int curr = Channels.GetNextGroup(-1); curr >= 0; curr = Channels.GetNextGroup(curr))
 			{
 				if (Channels.Get(curr) == current)
+#endif
 					return itoa(index);
 				index++;
 			}
@@ -89,47 +117,111 @@ const cString cChannelIterator::ItemId() const
 const cChannel* cChannelIterator::GetGroup(const char* GroupId)
 {
 	int group = -1;
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+#endif
 	if (GroupId)
 	{
 		int Index = atoi(GroupId);
+#if APIVERSNUM >= 20300
+		group = Channels->GetNextGroup(-1);
+		while (Index-- && group >= 0)
+			group = Channels->GetNextGroup(group);
+	}
+	return group >= 0 ? Channels->Get(group) : NULL;
+#else
 		group = Channels.GetNextGroup(-1);
 		while (Index-- && group >= 0)
 			group = Channels.GetNextGroup(group);
 	}
 	return group >= 0 ? Channels.Get(group) : NULL;
+#endif
+}
+
+const cChannel* cChannelIterator::FirstChannel()
+{
+const cChannel *Channel;
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	Channel = Channels->First();
+#else
+	Channel = Channels.First();
+#endif
+	return Channel;
+}
+
+const cChannel* cChannelIterator::NextNormal()
+{
+const cChannel *Channel;
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	Channel = Channels->Get(Channels->GetNextNormal(-1));
+#else
+	Channel = Channels.Get(Channels.GetNextNormal(-1));
+#endif
+	return Channel;
 }
 
+const cChannel* cChannelIterator::NextGroup()
+{
+const cChannel *Channel;
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	Channel = Channels->Get(Channels->GetNextGroup(-1));
+#else
+	Channel = Channels.Get(Channels.GetNextGroup(-1));
+#endif
+	return Channel;
+}
 
 //**************************** cListAll **************
-cListAll::cListAll(): cChannelIterator(Channels.First())
+cListAll::cListAll(): cChannelIterator(FirstChannel())
 {}
 
 const cChannel* cListAll::NextChannel(const cChannel *Channel)
 {
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	if (Channel)
+		Channel = SkipFakeGroups(Channels->Next(Channel));
+#else
 	if (Channel)
 		Channel = SkipFakeGroups(Channels.Next(Channel));
+#endif
 	return Channel;
 }
 
 //**************************** cListChannels **************
-cListChannels::cListChannels(): cChannelIterator(Channels.Get(Channels.GetNextNormal(-1)))
+cListChannels::cListChannels(): cChannelIterator(NextNormal())
 {}
 
 const cChannel* cListChannels::NextChannel(const cChannel *Channel)
 {
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	if (Channel)
+		Channel = Channels->Get(Channels->GetNextNormal(Channel->Index()));
+#else
 	if (Channel)
 		Channel = Channels.Get(Channels.GetNextNormal(Channel->Index()));
+#endif
 	return Channel;
 }
 
 // ********************* cListGroups ****************
-cListGroups::cListGroups(): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1)))
+cListGroups::cListGroups(): cChannelIterator(NextGroup())
 {}
 
 const cChannel* cListGroups::NextChannel(const cChannel *Channel)
 {
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	if (Channel)
+		Channel = Channels->Get(Channels->GetNextGroup(Channel->Index()));
+#else
 	if (Channel)
 		Channel = Channels.Get(Channels.GetNextGroup(Channel->Index()));
+#endif
 	return Channel;
 }
 //
@@ -139,8 +231,14 @@ cListGroup::cListGroup(const char *GroupId): cChannelIterator(GetNextChannelInGr
 
 const cChannel* cListGroup::GetNextChannelInGroup(const cChannel *Channel)
 {
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	if (Channel)
+		Channel = SkipFakeGroups(Channels->Next(Channel));
+#else
 	if (Channel)
 		Channel = SkipFakeGroups(Channels.Next(Channel));
+#endif
 	return Channel && !Channel->GroupSep() ? Channel : NULL;
 }
 
@@ -150,25 +248,42 @@ const cChannel* cListGroup::NextChannel(const cChannel *Channel)
 }
 //
 // ********************* cListTree ****************
-cListTree::cListTree(const char *SelectedGroupId): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1)))
+cListTree::cListTree(const char *SelectedGroupId): cChannelIterator(NextGroup())
 {
 	selectedGroup = GetGroup(SelectedGroupId);
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+	currentGroup = Channels->Get(Channels->GetNextGroup(-1));
+#else
 	currentGroup = Channels.Get(Channels.GetNextGroup(-1));
+#endif
 }
 
 const cChannel* cListTree::NextChannel(const cChannel *Channel)
 {
 	if (currentGroup == selectedGroup)
 	{
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_READ;
+		if (Channel)
+			Channel = SkipFakeGroups(Channels->Next(Channel));
+#else
 		if (Channel)
 			Channel = SkipFakeGroups(Channels.Next(Channel));
+#endif
 		if (Channel && Channel->GroupSep())
 			currentGroup = Channel;
 	}
 	else
 	{
+#if APIVERSNUM >= 20300
+		LOCK_CHANNELS_READ;
+		if (Channel)
+			Channel = Channels->Get(Channels->GetNextGroup(Channel->Index()));
+#else
 		if (Channel)
 			Channel = Channels.Get(Channels.GetNextGroup(Channel->Index()));
+#endif
 		currentGroup = Channel;
 	}
 	return Channel;
diff --git a/server/menuHTTP.h b/server/menuHTTP.h
index 91a00b1..5d4ca44 100644
--- a/server/menuHTTP.h
+++ b/server/menuHTTP.h
@@ -48,6 +48,9 @@ class cChannelIterator: public cItemIterator
 		const cChannel *first;
 		const cChannel *current;
 	protected:
+		virtual const cChannel* FirstChannel();
+		virtual const cChannel* NextNormal();
+		virtual const cChannel* NextGroup();
 		virtual const cChannel* NextChannel(const cChannel *Channel) = 0;
 		static inline const cChannel* SkipFakeGroups(const cChannel *Channel);
 		// Helper which returns the group by its index
@@ -208,8 +211,15 @@ class cRssMenuList: public cMenuList
 
 inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group)
 {
+#if APIVERSNUM >= 20300
+	LOCK_CHANNELS_READ;
+#endif
 	while (Group && Group->GroupSep() && !*Group->Name())
+#if APIVERSNUM >= 20300
+		Group = Channels->Next(Group);
+#else
 		Group = Channels.Next(Group);
+#endif
 	return Group;
 }
 
diff --git a/server/server.c b/server/server.c
index 8dd122e..328f728 100644
--- a/server/server.c
+++ b/server/server.c
@@ -177,7 +177,11 @@ void cStreamdevServer::Action(void)
 	}
 }
 
+#if APIVERSNUM >= 20300
+cList<cServerConnection>& cStreamdevServer::Clients(cThreadLock& Lock)
+#else
 const cList<cServerConnection>& cStreamdevServer::Clients(cThreadLock& Lock)
+#endif
 {
 	Lock.Lock(m_Instance);
 	return m_Clients;
diff --git a/server/server.h b/server/server.h
index 91a9cae..c70e099 100644
--- a/server/server.h
+++ b/server/server.h
@@ -37,7 +37,11 @@ public:
 	static void Destruct(void);
 	static bool Active(void);
 
+#if APIVERSNUM >= 20300
+	static cList<cServerConnection>& Clients(cThreadLock& Lock);
+#else
 	static const cList<cServerConnection>& Clients(cThreadLock& Lock);
+#endif
 };
 
 inline bool cStreamdevServer::Active(void) 
diff --git a/server/streamdev-server.c b/server/streamdev-server.c
index 33d08a5..04b2380 100644
--- a/server/streamdev-server.c
+++ b/server/streamdev-server.c
@@ -21,7 +21,11 @@
 cList<cMainThreadHookSubscriber> cMainThreadHookSubscriber::m_Subscribers;
 cMutex cMainThreadHookSubscriber::m_Mutex;
 
+#if APIVERSNUM >= 20300
+cList<cMainThreadHookSubscriber>& cMainThreadHookSubscriber::Subscribers(cMutexLock& Lock)
+#else
 const cList<cMainThreadHookSubscriber>& cMainThreadHookSubscriber::Subscribers(cMutexLock& Lock)
+#endif
 {
 	Lock.Lock(&m_Mutex);
 	return m_Subscribers;
@@ -163,7 +167,11 @@ void cPluginStreamdevServer::MainThreadHook(void)
 	}
 
 	cMutexLock lock;
+#if APIVERSNUM >= 20300
+	cList<cMainThreadHookSubscriber>& subs = cMainThreadHookSubscriber::Subscribers(lock);
+#else
 	const cList<cMainThreadHookSubscriber>& subs = cMainThreadHookSubscriber::Subscribers(lock);
+#endif
 	for (cMainThreadHookSubscriber *s = subs.First(); s; s = subs.Next(s))
 		s->MainThreadHook();
 }
@@ -199,7 +207,11 @@ cString cPluginStreamdevServer::SVDRPCommand(const char *Command, const char *Op
 	{
 		reply = "";
 		cThreadLock lock;
+#if APIVERSNUM >= 20300
+		cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#else
 		const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#endif
 		cServerConnection *s = clients.First();
 		if (!s)
 		{
@@ -223,7 +235,11 @@ cString cPluginStreamdevServer::SVDRPCommand(const char *Command, const char *Op
 		} else
 		{
 			cThreadLock lock;
+#if APIVERSNUM >= 20300
+			cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#else
 			const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
+#endif
 			cServerConnection *s = clients.First();
 			for (; s && s != client; s = clients.Next(s));
 
diff --git a/server/streamdev-server.h b/server/streamdev-server.h
index 4654e26..18e61c2 100644
--- a/server/streamdev-server.h
+++ b/server/streamdev-server.h
@@ -15,7 +15,11 @@ private:
 	static cList<cMainThreadHookSubscriber> m_Subscribers;
 	static cMutex m_Mutex;
 public:
+#if APIVERSNUM >= 20300
+	static cList<cMainThreadHookSubscriber>& Subscribers(cMutexLock& Lock);
+#else
 	static const cList<cMainThreadHookSubscriber>& Subscribers(cMutexLock& Lock);
+#endif
 
 	virtual void MainThreadHook() = 0;
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr-plugin-streamdev.git



More information about the pkg-vdr-dvb-changes mailing list