Streamdev-server compatibility with VDR 2.3.1 (fixes #2249)

This commit is contained in:
Frank Schmirler 2016-03-21 00:28:02 +01:00
parent d66c635a80
commit 674bb5b331
18 changed files with 538 additions and 4 deletions

View File

@ -245,3 +245,9 @@ Toerless Eckert
Tomasz Maciej Nowak Tomasz Maciej Nowak
for providing Polish language texts 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

View File

@ -1,6 +1,8 @@
VDR Plugin 'streamdev' Revision History VDR Plugin 'streamdev' Revision History
--------------------------------------- ---------------------------------------
- server compatibility with VDR 2.3.1 (thanks to Christopher Reimer and
Matthias Senzel)
- client compatibility with VDR 2.3.1 - client compatibility with VDR 2.3.1
- use cReceiver::SetPriority(...) in VDR 2.1.4+ - use cReceiver::SetPriority(...) in VDR 2.1.4+
- doubled size of client's filter buffer (suggested by Toerless Eckert) - doubled size of client's filter buffer (suggested by Toerless Eckert)

View File

@ -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 cMulticastGroup* cComponentIGMP::FindGroup(in_addr_t Group) const
#endif
{ {
cMulticastGroup *group = m_Groups.First(); cMulticastGroup *group = m_Groups.First();
while (group && group->group != Group) while (group && group->group != Group)
@ -117,7 +121,12 @@ bool cComponentIGMP::Initialize(void)
{ {
if (cServerComponent::Initialize() && IGMPMembership(IGMP_ALL_ROUTER)) 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)) for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
#endif
{ {
if (channel->GroupSep()) if (channel->GroupSep())
continue; continue;
@ -146,7 +155,12 @@ void cComponentIGMP::Destruct(void)
Cancel(-1); Cancel(-1);
m_CondWait.Signal(); m_CondWait.Signal();
Cancel(2); 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)) for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
#endif
{ {
if (channel->GroupSep()) if (channel->GroupSep())
continue; continue;
@ -432,9 +446,18 @@ cServerConnection* cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group)
in_addr_t g = ntohl(Group->group); in_addr_t g = ntohl(Group->group);
if (g > MULTICAST_PRIV_MIN && g <= MULTICAST_PRIV_MAX) { if (g > MULTICAST_PRIV_MIN && g <= MULTICAST_PRIV_MAX) {
cThreadLock lock; 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); cChannel *channel = Channels.GetByNumber(g - MULTICAST_PRIV_MIN);
#endif
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock); const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#if APIVERSNUM >= 20300
const cServerConnection *s = clients.First();
#else
cServerConnection *s = clients.First(); cServerConnection *s = clients.First();
#endif
while (s) { while (s) {
if (s->RemoteIpAddr() == Group->group) if (s->RemoteIpAddr() == Group->group)
break; break;
@ -453,7 +476,11 @@ cServerConnection* cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group)
void cComponentIGMP::IGMPStopMulticast(cMulticastGroup* Group) void cComponentIGMP::IGMPStopMulticast(cMulticastGroup* Group)
{ {
cThreadLock lock; cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock); const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) { for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) {
if (s->RemoteIpAddr() == Group->group) if (s->RemoteIpAddr() == Group->group)
s->Close(); s->Close();

View File

@ -9,6 +9,7 @@
#include <time.h> #include <time.h>
#include <vdr/thread.h> #include <vdr/thread.h>
#include "server/component.h" #include "server/component.h"
#include "../common.h"
class cMulticastGroup; class cMulticastGroup;
@ -23,7 +24,11 @@ private:
bool m_Querier; bool m_Querier;
cCondWait m_CondWait; cCondWait m_CondWait;
#if APIVERSNUM >= 20300
cMulticastGroup* FindGroup(in_addr_t Group);
#else
cMulticastGroup* FindGroup(in_addr_t Group) const; cMulticastGroup* FindGroup(in_addr_t Group) const;
#endif
/* Add or remove local host to multicast group */ /* Add or remove local host to multicast group */
bool IGMPMembership(in_addr_t Group, bool Add = true); bool IGMPMembership(in_addr_t Group, bool Add = true);

View File

@ -46,14 +46,29 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
int temp = strtol(String, NULL, 10); int temp = strtol(String, NULL, 10);
if (temp == 0) if (temp == 0)
temp = cDevice::CurrentChannel(); 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()) if (temp >= 1 && temp <= Channels.MaxNumber())
channel = Channels.GetByNumber(temp); channel = Channels.GetByNumber(temp);
#endif
} else { } else {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
channel = Channels->GetByChannelID(tChannelID::FromString(string));
#else
channel = Channels.GetByChannelID(tChannelID::FromString(string)); channel = Channels.GetByChannelID(tChannelID::FromString(string));
#endif
if (channel == NULL) { if (channel == NULL) {
int i = 1; int i = 1;
#if APIVERSNUM >= 20300
while ((channel = Channels->GetByNumber(i, 1)) != NULL) {
#else
while ((channel = Channels.GetByNumber(i, 1)) != NULL) { while ((channel = Channels.GetByNumber(i, 1)) != NULL) {
#endif
if (String == channel->Name()) if (String == channel->Name())
break; break;

View File

@ -523,8 +523,13 @@ RecPlayer* cConnectionHTTP::RecPlayerFromString(const char *FileBase, const char
ino_t inode = (ino_t) strtoull(p + 1, &p, 0); ino_t inode = (ino_t) strtoull(p + 1, &p, 0);
if (*p == 0 && inode > 0) { if (*p == 0 && inode > 0) {
struct stat st; struct stat st;
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
for (const cRecording *rec = Recordings->First(); rec; rec = Recordings->Next(rec)) {
#else
cThreadLock RecordingsLock(&Recordings); cThreadLock RecordingsLock(&Recordings);
for (cRecording *rec = Recordings.First(); rec; rec = Recordings.Next(rec)) { 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) if (stat(rec->FileName(), &st) == 0 && st.st_dev == (dev_t) l && st.st_ino == inode)
recPlayer = new RecPlayer(rec->FileName()); recPlayer = new RecPlayer(rec->FileName());
} }
@ -532,8 +537,13 @@ RecPlayer* cConnectionHTTP::RecPlayerFromString(const char *FileBase, const char
} }
else if (*p == 0) { else if (*p == 0) {
// get recording by index // get recording by index
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
const cRecording *rec = Recordings->Get((int) l - 1);
#else
cThreadLock RecordingsLock(&Recordings); cThreadLock RecordingsLock(&Recordings);
cRecording *rec = Recordings.Get((int) l - 1); cRecording *rec = Recordings.Get((int) l - 1);
#endif
if (rec) if (rec)
recPlayer = new RecPlayer(rec->FileName()); recPlayer = new RecPlayer(rec->FileName());
} }

View File

@ -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) bool cConnectionIGMP::SetChannel(cChannel *Channel, in_addr_t Dst)
#endif
{ {
if (Channel) { if (Channel) {
m_Channel = Channel; m_Channel = Channel;

View File

@ -19,13 +19,21 @@ class cConnectionIGMP: public cServerConnection {
private: private:
int m_ClientPort; int m_ClientPort;
eStreamType m_StreamType; eStreamType m_StreamType;
#if APIVERSNUM >= 20300
const cChannel *m_Channel;
#else
cChannel *m_Channel; cChannel *m_Channel;
#endif
public: public:
cConnectionIGMP(const char* Name, int ClientPort, eStreamType StreamType); cConnectionIGMP(const char* Name, int ClientPort, eStreamType StreamType);
virtual ~cConnectionIGMP(); virtual ~cConnectionIGMP();
#if APIVERSNUM >= 20300
bool SetChannel(const cChannel *Channel, in_addr_t Dst);
#else
bool SetChannel(cChannel *Channel, in_addr_t Dst); bool SetChannel(cChannel *Channel, in_addr_t Dst);
#endif
virtual void Welcome(void); virtual void Welcome(void);
virtual cString ToText(char Delimiter = ' ') const; virtual cString ToText(char Delimiter = ' ') const;

View File

@ -58,8 +58,10 @@ public:
cLSTEHandler::cLSTEHandler(cConnectionVTP *Client, const char *Option): cLSTEHandler::cLSTEHandler(cConnectionVTP *Client, const char *Option):
m_Client(Client), m_Client(Client),
#if APIVERSNUM < 20300
m_SchedulesLock(new cSchedulesLock(false, 500)), m_SchedulesLock(new cSchedulesLock(false, 500)),
m_Schedules(cSchedules::Schedules(*m_SchedulesLock)), m_Schedules(cSchedules::Schedules(*m_SchedulesLock)),
#endif
m_Schedule(NULL), m_Schedule(NULL),
m_Event(NULL), m_Event(NULL),
m_Errno(0), m_Errno(0),
@ -131,11 +133,20 @@ cLSTEHandler::cLSTEHandler(cConnectionVTP *Client, const char *Option):
break; break;
} }
} else if (!m_Schedule) { } 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; cChannel* Channel = NULL;
if (isnumber(p)) if (isnumber(p))
Channel = Channels.GetByNumber(strtol(Option, NULL, 10)); Channel = Channels.GetByNumber(strtol(Option, NULL, 10));
else else
Channel = Channels.GetByChannelID(tChannelID::FromString( Channel = Channels.GetByChannelID(tChannelID::FromString(
#endif
Option)); Option));
if (Channel) { if (Channel) {
m_Schedule = m_Schedules->GetSchedule(Channel->GetChannelID()); m_Schedule = m_Schedules->GetSchedule(Channel->GetChannelID());
@ -215,7 +226,12 @@ bool cLSTEHandler::Next(bool &Last)
switch (m_State) { switch (m_State) {
case Channel: case Channel:
if (m_Schedule != NULL) { 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(), cChannel *channel = Channels.GetByChannelID(m_Schedule->ChannelID(),
#endif
true); true);
if (channel != NULL) { if (channel != NULL) {
m_State = Event; m_State = Event;
@ -371,12 +387,21 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
m_Errno(0), m_Errno(0),
m_Traverse(false) m_Traverse(false)
{ {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (!Channels) {
#else
if (!Channels.Lock(false, 500)) { if (!Channels.Lock(false, 500)) {
#endif
m_Errno = 451; m_Errno = 451;
m_Error = "Channels are being modified - try again"; m_Error = "Channels are being modified - try again";
} else if (*Option) { } else if (*Option) {
if (isnumber(Option)) { if (isnumber(Option)) {
#if APIVERSNUM >= 20300
m_Channel = Channels->GetByNumber(strtol(Option, NULL, 10));
#else
m_Channel = Channels.GetByNumber(strtol(Option, NULL, 10)); m_Channel = Channels.GetByNumber(strtol(Option, NULL, 10));
#endif
if (m_Channel == NULL) { if (m_Channel == NULL) {
m_Errno = 501; m_Errno = 501;
m_Error = cString::sprintf("Channel \"%s\" not defined", Option); m_Error = cString::sprintf("Channel \"%s\" not defined", Option);
@ -386,21 +411,35 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
int i = 1; int i = 1;
m_Traverse = true; m_Traverse = true;
m_Option = strdup(Option); m_Option = strdup(Option);
#if APIVERSNUM >= 20300
while (i <= Channels->MaxNumber()) {
m_Channel = Channels->GetByNumber(i, 1);
#else
while (i <= Channels.MaxNumber()) { while (i <= Channels.MaxNumber()) {
m_Channel = Channels.GetByNumber(i, 1); m_Channel = Channels.GetByNumber(i, 1);
#endif
if (strcasestr(m_Channel->Name(), Option) != NULL) if (strcasestr(m_Channel->Name(), Option) != NULL)
break; break;
i = m_Channel->Number() + 1; i = m_Channel->Number() + 1;
} }
#if APIVERSNUM >= 20300
if (i > Channels->MaxNumber()) {
#else
if (i > Channels.MaxNumber()) { if (i > Channels.MaxNumber()) {
#endif
m_Errno = 501; m_Errno = 501;
m_Error = cString::sprintf("Channel \"%s\" not defined", Option); m_Error = cString::sprintf("Channel \"%s\" not defined", Option);
return; return;
} }
} }
#if APIVERSNUM >= 20300
} else if (Channels->MaxNumber() >= 1) {
m_Channel = Channels->GetByNumber(1, 1);
#else
} else if (Channels.MaxNumber() >= 1) { } else if (Channels.MaxNumber() >= 1) {
m_Channel = Channels.GetByNumber(1, 1); m_Channel = Channels.GetByNumber(1, 1);
#endif
m_Traverse = true; m_Traverse = true;
} else { } else {
m_Errno = 550; m_Errno = 550;
@ -410,7 +449,9 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
cLSTCHandler::~cLSTCHandler() cLSTCHandler::~cLSTCHandler()
{ {
#if APIVERSNUM < 20300
Channels.Unlock(); Channels.Unlock();
#endif
if (m_Option != NULL) if (m_Option != NULL)
free(m_Option); free(m_Option);
} }
@ -435,8 +476,14 @@ bool cLSTCHandler::Next(bool &Last)
Last = true; Last = true;
if (m_Traverse) { if (m_Traverse) {
int i = m_Channel->Number() + 1; 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()) { while (i <= Channels.MaxNumber()) {
m_Channel = Channels.GetByNumber(i, 1); m_Channel = Channels.GetByNumber(i, 1);
#endif
if (m_Channel != NULL) { if (m_Channel != NULL) {
if (m_Option == NULL || strcasestr(m_Channel->Name(), if (m_Option == NULL || strcasestr(m_Channel->Name(),
m_Option) != NULL) 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) if (i < Channels.MaxNumber() + 1)
#endif
Last = false; Last = false;
} }
@ -461,7 +512,11 @@ class cLSTTHandler
{ {
private: private:
cConnectionVTP *m_Client; cConnectionVTP *m_Client;
#if APIVERSNUM >= 20300
const cTimer *m_Timer;
#else
cTimer *m_Timer; cTimer *m_Timer;
#endif
int m_Index; int m_Index;
int m_Errno; int m_Errno;
cString m_Error; cString m_Error;
@ -479,9 +534,16 @@ cLSTTHandler::cLSTTHandler(cConnectionVTP *Client, const char *Option):
m_Errno(0), m_Errno(0),
m_Traverse(false) m_Traverse(false)
{ {
#if APIVERSNUM >= 20300
LOCK_TIMERS_READ;
#endif
if (*Option) { if (*Option) {
if (isnumber(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); m_Timer = Timers.Get(strtol(Option, NULL, 10) - 1);
#endif
if (m_Timer == NULL) { if (m_Timer == NULL) {
m_Errno = 501; m_Errno = 501;
m_Error = cString::sprintf("Timer \"%s\" not defined", Option); m_Error = cString::sprintf("Timer \"%s\" not defined", Option);
@ -490,10 +552,18 @@ cLSTTHandler::cLSTTHandler(cConnectionVTP *Client, const char *Option):
m_Errno = 501; m_Errno = 501;
m_Error = cString::sprintf("Error in timer number \"%s\"", Option); m_Error = cString::sprintf("Error in timer number \"%s\"", Option);
} }
#if APIVERSNUM >= 20300
} else if (Timers->Count()) {
#else
} else if (Timers.Count()) { } else if (Timers.Count()) {
#endif
m_Traverse = true; m_Traverse = true;
m_Index = 0; m_Index = 0;
#if APIVERSNUM >= 20300
m_Timer = Timers->Get(m_Index);
#else
m_Timer = Timers.Get(m_Index); m_Timer = Timers.Get(m_Index);
#endif
if (m_Timer == NULL) { if (m_Timer == NULL) {
m_Errno = 501; m_Errno = 501;
m_Error = cString::sprintf("Timer \"%d\" not found", m_Index + 1); m_Error = cString::sprintf("Timer \"%d\" not found", m_Index + 1);
@ -519,7 +589,12 @@ bool cLSTTHandler::Next(bool &Last)
bool result; bool result;
char *buffer; 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; Last = !m_Traverse || m_Index >= Timers.Count() - 1;
#endif
buffer = strdup(*m_Timer->ToText()); buffer = strdup(*m_Timer->ToText());
buffer[strlen(buffer) - 1] = '\0'; // strip \n buffer[strlen(buffer) - 1] = '\0'; // strip \n
result = m_Client->Respond(Last ? 250 : -250, "%d %s", m_Timer->Index() + 1, result = m_Client->Respond(Last ? 250 : -250, "%d %s", m_Timer->Index() + 1,
@ -527,7 +602,11 @@ bool cLSTTHandler::Next(bool &Last)
free(buffer); free(buffer);
if (m_Traverse && !Last) { if (m_Traverse && !Last) {
#if APIVERSNUM >= 20300
m_Timer = Timers->Get(++m_Index);
#else
m_Timer = Timers.Get(++m_Index); m_Timer = Timers.Get(++m_Index);
#endif
if (m_Timer == NULL) { if (m_Timer == NULL) {
m_Errno = 501; m_Errno = 501;
m_Error = cString::sprintf("Timer \"%d\" not found", m_Index + 1); 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, enum eStates { Recording, Event, Title, Subtitle, Description, Components, Vps,
EndRecording }; EndRecording };
cConnectionVTP *m_Client; cConnectionVTP *m_Client;
#if APIVERSNUM >= 20300
const cRecording *m_Recording;
#else
cRecording *m_Recording; cRecording *m_Recording;
#endif
const cEvent *m_Event; const cEvent *m_Event;
int m_Index; int m_Index;
int m_Errno; int m_Errno;
@ -570,9 +653,16 @@ cLSTRHandler::cLSTRHandler(cConnectionVTP *Client, const char *Option):
m_State(Recording), m_State(Recording),
m_CurrentComponent(0) m_CurrentComponent(0)
{ {
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
#endif
if (*Option) { if (*Option) {
if (isnumber(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); m_Recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
#endif
m_Event = m_Recording->Info()->GetEvent(); m_Event = m_Recording->Info()->GetEvent();
m_Info = true; m_Info = true;
if (m_Recording == NULL) { 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); m_Error = cString::sprintf("Error in Recording number \"%s\"", Option);
} }
} }
#if APIVERSNUM >= 20300
else if (Recordings->Count()) {
#else
else if (Recordings.Count()) { else if (Recordings.Count()) {
#endif
m_Traverse = true; m_Traverse = true;
m_Index = 0; m_Index = 0;
#if APIVERSNUM >= 20300
m_Recording = Recordings->Get(m_Index);
#else
m_Recording = Recordings.Get(m_Index); m_Recording = Recordings.Get(m_Index);
#endif
if (m_Recording == NULL) { if (m_Recording == NULL) {
m_Errno = 501; m_Errno = 501;
m_Error = cString::sprintf("Recording \"%d\" not found", m_Index + 1); m_Error = cString::sprintf("Recording \"%d\" not found", m_Index + 1);
@ -691,11 +789,20 @@ bool cLSTRHandler::Next(bool &Last)
} }
else { else {
bool result; 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; 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)); result = m_Client->Respond(Last ? 250 : -250, "%d %s", m_Recording->Index() + 1, m_Recording->Title(' ', true));
if (m_Traverse && !Last) { if (m_Traverse && !Last) {
#if APIVERSNUM >= 20300
m_Recording = Recordings->Get(++m_Index);
#else
m_Recording = Recordings.Get(++m_Index); m_Recording = Recordings.Get(++m_Index);
#endif
if (m_Recording == NULL) { if (m_Recording == NULL) {
m_Errno = 501; m_Errno = 501;
m_Error = cString::sprintf("Recording \"%d\" not found", m_Index + 1); m_Error = cString::sprintf("Recording \"%d\" not found", m_Index + 1);
@ -1145,7 +1252,12 @@ bool cConnectionVTP::CmdPLAY(char *Opts)
{ {
if (*Opts) { if (*Opts) {
if (isnumber(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); cRecording *recording = Recordings.Get(strtol(Opts, NULL, 10) - 1);
#endif
if (recording) { if (recording) {
if (m_RecPlayer) { if (m_RecPlayer) {
delete m_RecPlayer; delete m_RecPlayer;
@ -1391,10 +1503,17 @@ bool cConnectionVTP::CmdSTAT(const char *Option)
Reply(250, "VDR: %s | Streamdev: %s", VDRVERSION, VERSION); Reply(250, "VDR: %s | Streamdev: %s", VDRVERSION, VERSION);
} }
else if (strcasecmp(Option, "RECORDS") == 0) { 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(); bool recordings = Recordings.Load();
Recordings.Sort(); Recordings.Sort();
if (recordings) { if (recordings) {
cRecording *recording = Recordings.Last(); cRecording *recording = Recordings.Last();
#endif
Reply(250, "%d", recording->Index() + 1); Reply(250, "%d", recording->Index() + 1);
} }
else { else {
@ -1402,10 +1521,20 @@ bool cConnectionVTP::CmdSTAT(const char *Option)
} }
} }
else if (strcasecmp(Option, "CHANNELS") == 0) { else if (strcasecmp(Option, "CHANNELS") == 0) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
Reply(250, "%d", Channels->MaxNumber());
#else
Reply(250, "%d", Channels.MaxNumber()); Reply(250, "%d", Channels.MaxNumber());
#endif
} }
else if (strcasecmp(Option, "TIMERS") == 0) { else if (strcasecmp(Option, "TIMERS") == 0) {
#if APIVERSNUM >= 20300
LOCK_TIMERS_READ;
Reply(250, "%d", Timers->Count());
#else
Reply(250, "%d", Timers.Count()); Reply(250, "%d", Timers.Count());
#endif
} }
else if (strcasecmp(Option, "CHARSET") == 0) { else if (strcasecmp(Option, "CHARSET") == 0) {
Reply(250, "%s", cCharSetConv::SystemCharacterTable()); Reply(250, "%s", cCharSetConv::SystemCharacterTable());
@ -1433,7 +1562,12 @@ bool cConnectionVTP::CmdMODT(const char *Option)
int n = strtol(Option, &tail, 10); int n = strtol(Option, &tail, 10);
if (tail && tail != Option) { if (tail && tail != Option) {
tail = skipspace(tail); tail = skipspace(tail);
#if APIVERSNUM >= 20300
LOCK_TIMERS_WRITE;
cTimer *timer = Timers->Get(n - 1);
#else
cTimer *timer = Timers.Get(n - 1); cTimer *timer = Timers.Get(n - 1);
#endif
if (timer) { if (timer) {
cTimer t = *timer; cTimer t = *timer;
if (strcasecmp(tail, "ON") == 0) if (strcasecmp(tail, "ON") == 0)
@ -1445,7 +1579,11 @@ bool cConnectionVTP::CmdMODT(const char *Option)
EXIT_WRAPPER(); EXIT_WRAPPER();
} }
*timer = t; *timer = t;
#if APIVERSNUM >= 20300
Timers->SetModified();
#else
Timers.SetModified(); Timers.SetModified();
#endif
isyslog("timer %s modified (%s)", *timer->ToDescr(), isyslog("timer %s modified (%s)", *timer->ToDescr(),
timer->HasFlags(tfActive) ? "active" : "inactive"); timer->HasFlags(tfActive) ? "active" : "inactive");
Reply(250, "%d %s", timer->Index() + 1, *timer->ToText()); Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
@ -1464,10 +1602,18 @@ bool cConnectionVTP::CmdNEWT(const char *Option)
if (*Option) { if (*Option) {
cTimer *timer = new cTimer; cTimer *timer = new cTimer;
if (timer->Parse(Option)) { 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); cTimer *t = Timers.GetTimer(timer);
if (!t) { if (!t) {
Timers.Add(timer); Timers.Add(timer);
Timers.SetModified(); Timers.SetModified();
#endif
isyslog("timer %s added", *timer->ToDescr()); isyslog("timer %s added", *timer->ToDescr());
Reply(250, "%d %s", timer->Index() + 1, *timer->ToText()); Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
EXIT_WRAPPER(); 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); cTimer *timer = Timers.Get(number);
if (timer) { if (timer) {
if (timer->Recording()) { if (timer->Recording()) {
if (force) { if (force) {
timer->Skip(); timer->Skip();
cRecordControls::Process(time(NULL)); cRecordControls::Process(time(NULL));
#endif
} }
else { else {
Reply(550, "Timer \"%i\" is recording", number); Reply(550, "Timer \"%i\" is recording", number);
EXIT_WRAPPER(); EXIT_WRAPPER();
} }
} }
#if APIVERSNUM >= 20300
isyslog("deleting timer %s", *Timer->ToDescr());
Timers->Del(Timer);
Timers->SetModified();
#else
isyslog("deleting timer %s", *timer->ToDescr()); isyslog("deleting timer %s", *timer->ToDescr());
Timers.Del(timer); Timers.Del(timer);
Timers.SetModified(); Timers.SetModified();
#endif
Reply(250, "Timer \"%i\" deleted", number); Reply(250, "Timer \"%i\" deleted", number);
} else } else
Reply(501, "Timer \"%i\" not defined", number); Reply(501, "Timer \"%i\" not defined", number);
@ -1538,7 +1702,12 @@ bool cConnectionVTP::CmdDELT(const char *Option)
bool cConnectionVTP::CmdNEXT(const char *Option) bool cConnectionVTP::CmdNEXT(const char *Option)
{ {
INIT_WRAPPER(); INIT_WRAPPER();
#if APIVERSNUM >= 20300
LOCK_TIMERS_READ;
const cTimer *t = Timers->GetNextActiveTimer();
#else
cTimer *t = Timers.GetNextActiveTimer(); cTimer *t = Timers.GetNextActiveTimer();
#endif
if (t) { if (t) {
time_t Start = t->StartTime(); time_t Start = t->StartTime();
int Number = t->Index() + 1; int Number = t->Index() + 1;
@ -1562,12 +1731,23 @@ bool cConnectionVTP::CmdNEWC(const char *Option)
if (*Option) { if (*Option) {
cChannel ch; cChannel ch;
if (ch.Parse(Option)) { if (ch.Parse(Option)) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_WRITE;
if (Channels->HasUniqueChannelID(&ch)) {
#else
if (Channels.HasUniqueChannelID(&ch)) { if (Channels.HasUniqueChannelID(&ch)) {
#endif
cChannel *channel = new cChannel; cChannel *channel = new cChannel;
*channel = ch; *channel = ch;
#if APIVERSNUM >= 20300
Channels->Add(channel);
Channels->ReNumber();
Channels->SetModified();
#else
Channels.Add(channel); Channels.Add(channel);
Channels.ReNumber(); Channels.ReNumber();
Channels.SetModified(true); Channels.SetModified(true);
#endif
isyslog("new channel %d %s", channel->Number(), *channel->ToText()); isyslog("new channel %d %s", channel->Number(), *channel->ToText());
Reply(250, "%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); int n = strtol(Option, &tail, 10);
if (tail && tail != Option) { if (tail && tail != Option) {
tail = skipspace(tail); tail = skipspace(tail);
#if APIVERSNUM >= 20300
LOCK_CHANNELS_WRITE;
Channels->SetExplicitModify();
cChannel *channel = Channels->GetByNumber(n);
#else
if (!Channels.BeingEdited()) { if (!Channels.BeingEdited()) {
cChannel *channel = Channels.GetByNumber(n); cChannel *channel = Channels.GetByNumber(n);
#endif
if (channel) { if (channel) {
cChannel ch; cChannel ch;
if (ch.Parse(tail)) { if (ch.Parse(tail)) {
#if APIVERSNUM >= 20300
if (Channels->HasUniqueChannelID(&ch, channel)) {
*channel = ch;
Channels->ReNumber();
Channels->SetModified();
#else
if (Channels.HasUniqueChannelID(&ch, channel)) { if (Channels.HasUniqueChannelID(&ch, channel)) {
*channel = ch; *channel = ch;
Channels.ReNumber(); Channels.ReNumber();
Channels.SetModified(true); Channels.SetModified(true);
#endif
isyslog("modifed channel %d %s", channel->Number(), *channel->ToText()); isyslog("modifed channel %d %s", channel->Number(), *channel->ToText());
Reply(250, "%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 { else {
Reply(501, "Channel \"%d\" not defined", n); Reply(501, "Channel \"%d\" not defined", n);
} }
#if APIVERSNUM < 20300
} }
else { else {
Reply(550, "Channels are being edited - try again later"); Reply(550, "Channels are being edited - try again later");
} }
#endif
} }
else { else {
Reply(501, "Error in channel number"); Reply(501, "Error in channel number");
@ -1635,7 +1830,14 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
{ {
INIT_WRAPPER(); INIT_WRAPPER();
if (*Option) { if (*Option) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_WRITE;
Channels->SetExplicitModify();
// LOCK_TIMERS_WRITE;
// Timers->SetExplicitModify();
#else
if (!Channels.BeingEdited() && !Timers.BeingEdited()) { if (!Channels.BeingEdited() && !Timers.BeingEdited()) {
#endif
char *tail; char *tail;
int From = strtol(Option, &tail, 10); int From = strtol(Option, &tail, 10);
if (tail && tail != Option) { if (tail && tail != Option) {
@ -1643,20 +1845,37 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
if (tail && tail != Option) { if (tail && tail != Option) {
int To = strtol(tail, NULL, 10); int To = strtol(tail, NULL, 10);
int CurrentChannelNr = cDevice::CurrentChannel(); 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 *CurrentChannel = Channels.GetByNumber(CurrentChannelNr);
cChannel *FromChannel = Channels.GetByNumber(From); cChannel *FromChannel = Channels.GetByNumber(From);
if (FromChannel) { if (FromChannel) {
cChannel *ToChannel = Channels.GetByNumber(To); cChannel *ToChannel = Channels.GetByNumber(To);
#endif
if (ToChannel) { if (ToChannel) {
int FromNumber = FromChannel->Number(); int FromNumber = FromChannel->Number();
int ToNumber = ToChannel->Number(); int ToNumber = ToChannel->Number();
if (FromNumber != ToNumber) { if (FromNumber != ToNumber) {
#if APIVERSNUM >= 20300
Channels->Move(FromChannel, ToChannel);
Channels->ReNumber();
Channels->SetModified();
#else
Channels.Move(FromChannel, ToChannel); Channels.Move(FromChannel, ToChannel);
Channels.ReNumber(); Channels.ReNumber();
Channels.SetModified(true); Channels.SetModified(true);
#endif
if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) {
if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) { if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) {
#if APIVERSNUM >= 20300
Channels->SwitchTo(CurrentChannel->Number());
#else
Channels.SwitchTo(CurrentChannel->Number()); Channels.SwitchTo(CurrentChannel->Number());
#endif
} }
else { else {
cDevice::SetCurrentChannel(CurrentChannel); cDevice::SetCurrentChannel(CurrentChannel);
@ -1684,10 +1903,12 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
else { else {
Reply(501, "Error in channel number"); Reply(501, "Error in channel number");
} }
#if APIVERSNUM < 20300
} }
else { else {
Reply(550, "Channels or timers are being edited - try again later"); Reply(550, "Channels or timers are being edited - try again later");
} }
#endif
} }
else { else {
Reply(501, "Missing channel number"); Reply(501, "Missing channel number");
@ -1700,31 +1921,63 @@ bool cConnectionVTP::CmdDELC(const char *Option)
INIT_WRAPPER(); INIT_WRAPPER();
if (*Option) { if (*Option) {
if (isnumber(Option)) { if (isnumber(Option)) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_WRITE;
Channels->SetExplicitModify();
cChannel *channel = Channels->GetByNumber(strtol(Option, NULL, 10));
#else
if (!Channels.BeingEdited()) { if (!Channels.BeingEdited()) {
cChannel *channel = Channels.GetByNumber(strtol(Option, NULL, 10)); cChannel *channel = Channels.GetByNumber(strtol(Option, NULL, 10));
#endif
if (channel) { 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)) { for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) {
#endif
if (timer->Channel() == channel) { if (timer->Channel() == channel) {
Reply(550, "Channel \"%s\" is in use by timer %d", Option, timer->Index() + 1); Reply(550, "Channel \"%s\" is in use by timer %d", Option, timer->Index() + 1);
return false; return false;
} }
} }
int CurrentChannelNr = cDevice::CurrentChannel(); int CurrentChannelNr = cDevice::CurrentChannel();
#if APIVERSNUM >= 20300
cChannel *CurrentChannel = Channels->GetByNumber(CurrentChannelNr);
#else
cChannel *CurrentChannel = Channels.GetByNumber(CurrentChannelNr); cChannel *CurrentChannel = Channels.GetByNumber(CurrentChannelNr);
#endif
if (CurrentChannel && channel == CurrentChannel) { 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()); int n = Channels.GetNextNormal(CurrentChannel->Index());
if (n < 0) if (n < 0)
n = Channels.GetPrevNormal(CurrentChannel->Index()); n = Channels.GetPrevNormal(CurrentChannel->Index());
CurrentChannel = Channels.Get(n); CurrentChannel = Channels.Get(n);
#endif
CurrentChannelNr = 0; // triggers channel switch below CurrentChannelNr = 0; // triggers channel switch below
} }
#if APIVERSNUM >= 20300
Channels->Del(channel);
Channels->ReNumber();
Channels->SetModified();
#else
Channels.Del(channel); Channels.Del(channel);
Channels.ReNumber(); Channels.ReNumber();
Channels.SetModified(true); Channels.SetModified(true);
#endif
isyslog("channel %s deleted", Option); isyslog("channel %s deleted", Option);
if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) {
if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring())
#if APIVERSNUM >= 20300
Channels->SwitchTo(CurrentChannel->Number());
#else
Channels.SwitchTo(CurrentChannel->Number()); Channels.SwitchTo(CurrentChannel->Number());
#endif
else else
cDevice::SetCurrentChannel(CurrentChannel); cDevice::SetCurrentChannel(CurrentChannel);
} }
@ -1733,9 +1986,11 @@ bool cConnectionVTP::CmdDELC(const char *Option)
else else
Reply(501, "Channel \"%s\" not defined", Option); Reply(501, "Channel \"%s\" not defined", Option);
} }
#if APIVERSNUM < 20300
else else
Reply(550, "Channels are being edited - try again later"); Reply(550, "Channels are being edited - try again later");
} }
#endif
else else
Reply(501, "Error in channel number \"%s\"", Option); Reply(501, "Error in channel number \"%s\"", Option);
} }
@ -1750,13 +2005,22 @@ bool cConnectionVTP::CmdDELR(const char *Option)
INIT_WRAPPER(); INIT_WRAPPER();
if (*Option) { if (*Option) {
if (isnumber(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); cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
#endif
if (recording) { if (recording) {
cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName()); cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
if (!rc) { if (!rc) {
if (recording->Delete()) { if (recording->Delete()) {
Reply(250, "Recording \"%s\" deleted", Option); Reply(250, "Recording \"%s\" deleted", Option);
#if APIVERSNUM >= 20300
Recordings->DelByName(recording->FileName());
#else
::Recordings.DelByName(recording->FileName()); ::Recordings.DelByName(recording->FileName());
#endif
} }
else else
Reply(554, "Error while deleting recording!"); 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); Reply(550, "Recording \"%s\" is in use by timer %d", Option, rc->Timer()->Index() + 1);
} }
else 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)"); Reply(550, "Recording \"%s\" not found%s", Option, Recordings.Count() ? "" : " (use LSTR before deleting)");
#endif
} }
else else
Reply(501, "Error in recording number \"%s\"", Option); Reply(501, "Error in recording number \"%s\"", Option);

View File

@ -31,7 +31,11 @@ private:
cStreamdevLiveStreamer *m_Streamer; cStreamdevLiveStreamer *m_Streamer;
protected: protected:
#if APIVERSNUM >= 20300
virtual void Receive(const uchar *Data, int Length);
#else
virtual void Receive(uchar *Data, int Length); virtual void Receive(uchar *Data, int Length);
#endif
public: public:
cStreamdevLiveReceiver(cStreamdevLiveStreamer *Streamer, const cChannel *Channel, int Priority, const int *Pids); cStreamdevLiveReceiver(cStreamdevLiveStreamer *Streamer, const cChannel *Channel, int Priority, const int *Pids);
@ -53,7 +57,11 @@ cStreamdevLiveReceiver::~cStreamdevLiveReceiver()
Detach(); Detach();
} }
#if APIVERSNUM >= 20300
void cStreamdevLiveReceiver::Receive(const uchar *Data, int Length) {
#else
void cStreamdevLiveReceiver::Receive(uchar *Data, int Length) { void cStreamdevLiveReceiver::Receive(uchar *Data, int Length) {
#endif
m_Streamer->Receive(Data, Length); 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; SI::PAT::Association assoc;
for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) { for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) {
if (!assoc.isNITPid()) { 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()); const cChannel *Channel = Channels.GetByServiceID(Source(), Transponder(), assoc.getServiceId());
#endif
if (Channel && (Channel == m_Channel)) { if (Channel && (Channel == m_Channel)) {
int prevPmtPid = pmtPid; int prevPmtPid = pmtPid;
if (0 != (pmtPid = assoc.getPid())) { if (0 != (pmtPid = assoc.getPid())) {
@ -547,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) void cStreamdevLiveStreamer::Receive(uchar *Data, int Length)
#endif
{ {
int p = m_ReceiveBuffer->PutTS(Data, Length); int p = m_ReceiveBuffer->PutTS(Data, Length);
if (p != Length) if (p != Length)
@ -688,9 +705,16 @@ void cStreamdevLiveStreamer::MainThreadHook()
} }
if (m_SwitchLive) { if (m_SwitchLive) {
// switched away live TV. Try previous channel on other device first // 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())) { if (!Channels.SwitchTo(cDevice::CurrentChannel())) {
// switch to streamdev channel otherwise // switch to streamdev channel otherwise
Channels.SwitchTo(m_Channel->Number()); Channels.SwitchTo(m_Channel->Number());
#endif
Skins.Message(mtInfo, tr("Streaming active")); Skins.Message(mtInfo, tr("Streaming active"));
} }
if (m_Device) if (m_Device)

View File

@ -64,7 +64,11 @@ public:
void GetSignal(int *DevNum, int *Strength, int *Quality) const; void GetSignal(int *DevNum, int *Strength, int *Quality) const;
virtual cString ToText() const; virtual cString ToText() const;
#if APIVERSNUM >= 20300
void Receive(const uchar *Data, int Length);
#else
void Receive(uchar *Data, int Length); void Receive(uchar *Data, int Length);
#endif
virtual bool IsReceiving(void) const; virtual bool IsReceiving(void) const;
virtual void Attach(void); virtual void Attach(void);

View File

@ -13,7 +13,11 @@
cStreamdevServerMenu::cStreamdevServerMenu(): cOsdMenu(tr("Streamdev Connections"), 4, 20) { cStreamdevServerMenu::cStreamdevServerMenu(): cOsdMenu(tr("Streamdev Connections"), 4, 20) {
cThreadLock lock; cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock); const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) for (cServerConnection *s = clients.First(); s; s = clients.Next(s))
Add(new cOsdItem(s->ToText('\t'))); Add(new cOsdItem(s->ToText('\t')));
SetHelpKeys(); SetHelpKeys();
@ -31,7 +35,11 @@ eOSState cStreamdevServerMenu::Disconnect() {
cOsdItem *item = Get(Current()); cOsdItem *item = Get(Current());
if (item) { if (item) {
cThreadLock lock; cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock); const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
const char *text = item->Text(); const char *text = item->Text();
for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) { for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) {
if (!strcmp(text, s->ToText('\t'))) { if (!strcmp(text, s->ToText('\t'))) {

View File

@ -6,10 +6,19 @@
#include "server/menuHTTP.h" #include "server/menuHTTP.h"
//**************************** cRecordingIterator ************** //**************************** cRecordingIterator **************
#if APIVERSNUM >= 20300
cRecordingsIterator::cRecordingsIterator(eStreamType StreamType)
#else
cRecordingsIterator::cRecordingsIterator(eStreamType StreamType): RecordingsLock(&Recordings) cRecordingsIterator::cRecordingsIterator(eStreamType StreamType): RecordingsLock(&Recordings)
#endif
{ {
streamType = StreamType; streamType = StreamType;
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
first = NextSuitable(Recordings->First());
#else
first = NextSuitable(Recordings.First()); first = NextSuitable(Recordings.First());
#endif
current = NULL; current = NULL;
} }
@ -20,20 +29,32 @@ const cRecording* cRecordingsIterator::NextSuitable(const cRecording *Recording)
bool isPes = Recording->IsPesRecording(); bool isPes = Recording->IsPesRecording();
if (!isPes || (isPes && streamType == stPES)) if (!isPes || (isPes && streamType == stPES))
break; break;
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
Recording = Recordings->Next(Recording);
#else
Recording = Recordings.Next(Recording); Recording = Recordings.Next(Recording);
#endif
} }
return Recording; return Recording;
} }
bool cRecordingsIterator::Next() bool cRecordingsIterator::Next()
{ {
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
#endif
if (first) if (first)
{ {
current = first; current = first;
first = NULL; first = NULL;
} }
else else
#if APIVERSNUM >= 20300
current = NextSuitable(Recordings->Next(current));
#else
current = NextSuitable(Recordings.Next(current)); current = NextSuitable(Recordings.Next(current));
#endif
return current; return current;
} }
@ -71,9 +92,16 @@ const cString cChannelIterator::ItemId() const
if (current->GroupSep()) if (current->GroupSep())
{ {
int index = 0; 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)) for (int curr = Channels.GetNextGroup(-1); curr >= 0; curr = Channels.GetNextGroup(curr))
{ {
if (Channels.Get(curr) == current) if (Channels.Get(curr) == current)
#endif
return itoa(index); return itoa(index);
index++; index++;
} }
@ -89,47 +117,111 @@ const cString cChannelIterator::ItemId() const
const cChannel* cChannelIterator::GetGroup(const char* GroupId) const cChannel* cChannelIterator::GetGroup(const char* GroupId)
{ {
int group = -1; int group = -1;
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
#endif
if (GroupId) if (GroupId)
{ {
int Index = atoi(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); group = Channels.GetNextGroup(-1);
while (Index-- && group >= 0) while (Index-- && group >= 0)
group = Channels.GetNextGroup(group); group = Channels.GetNextGroup(group);
} }
return group >= 0 ? Channels.Get(group) : NULL; 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::cListAll(): cChannelIterator(Channels.First()) cListAll::cListAll(): cChannelIterator(FirstChannel())
{} {}
const cChannel* cListAll::NextChannel(const cChannel *Channel) const cChannel* cListAll::NextChannel(const cChannel *Channel)
{ {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = SkipFakeGroups(Channels->Next(Channel));
#else
if (Channel) if (Channel)
Channel = SkipFakeGroups(Channels.Next(Channel)); Channel = SkipFakeGroups(Channels.Next(Channel));
#endif
return Channel; return Channel;
} }
//**************************** cListChannels ************** //**************************** cListChannels **************
cListChannels::cListChannels(): cChannelIterator(Channels.Get(Channels.GetNextNormal(-1))) cListChannels::cListChannels(): cChannelIterator(NextNormal())
{} {}
const cChannel* cListChannels::NextChannel(const cChannel *Channel) 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) if (Channel)
Channel = Channels.Get(Channels.GetNextNormal(Channel->Index())); Channel = Channels.Get(Channels.GetNextNormal(Channel->Index()));
#endif
return Channel; return Channel;
} }
// ********************* cListGroups **************** // ********************* cListGroups ****************
cListGroups::cListGroups(): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1))) cListGroups::cListGroups(): cChannelIterator(NextGroup())
{} {}
const cChannel* cListGroups::NextChannel(const cChannel *Channel) 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) if (Channel)
Channel = Channels.Get(Channels.GetNextGroup(Channel->Index())); Channel = Channels.Get(Channels.GetNextGroup(Channel->Index()));
#endif
return Channel; return Channel;
} }
// //
@ -139,8 +231,14 @@ cListGroup::cListGroup(const char *GroupId): cChannelIterator(GetNextChannelInGr
const cChannel* cListGroup::GetNextChannelInGroup(const cChannel *Channel) const cChannel* cListGroup::GetNextChannelInGroup(const cChannel *Channel)
{ {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = SkipFakeGroups(Channels->Next(Channel));
#else
if (Channel) if (Channel)
Channel = SkipFakeGroups(Channels.Next(Channel)); Channel = SkipFakeGroups(Channels.Next(Channel));
#endif
return Channel && !Channel->GroupSep() ? Channel : NULL; return Channel && !Channel->GroupSep() ? Channel : NULL;
} }
@ -150,25 +248,42 @@ const cChannel* cListGroup::NextChannel(const cChannel *Channel)
} }
// //
// ********************* cListTree **************** // ********************* cListTree ****************
cListTree::cListTree(const char *SelectedGroupId): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1))) cListTree::cListTree(const char *SelectedGroupId): cChannelIterator(NextGroup())
{ {
selectedGroup = GetGroup(SelectedGroupId); selectedGroup = GetGroup(SelectedGroupId);
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
currentGroup = Channels->Get(Channels->GetNextGroup(-1));
#else
currentGroup = Channels.Get(Channels.GetNextGroup(-1)); currentGroup = Channels.Get(Channels.GetNextGroup(-1));
#endif
} }
const cChannel* cListTree::NextChannel(const cChannel *Channel) const cChannel* cListTree::NextChannel(const cChannel *Channel)
{ {
if (currentGroup == selectedGroup) if (currentGroup == selectedGroup)
{ {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = SkipFakeGroups(Channels->Next(Channel));
#else
if (Channel) if (Channel)
Channel = SkipFakeGroups(Channels.Next(Channel)); Channel = SkipFakeGroups(Channels.Next(Channel));
#endif
if (Channel && Channel->GroupSep()) if (Channel && Channel->GroupSep())
currentGroup = Channel; currentGroup = Channel;
} }
else else
{ {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = Channels->Get(Channels->GetNextGroup(Channel->Index()));
#else
if (Channel) if (Channel)
Channel = Channels.Get(Channels.GetNextGroup(Channel->Index())); Channel = Channels.Get(Channels.GetNextGroup(Channel->Index()));
#endif
currentGroup = Channel; currentGroup = Channel;
} }
return Channel; return Channel;

View File

@ -48,6 +48,9 @@ class cChannelIterator: public cItemIterator
const cChannel *first; const cChannel *first;
const cChannel *current; const cChannel *current;
protected: protected:
virtual const cChannel* FirstChannel();
virtual const cChannel* NextNormal();
virtual const cChannel* NextGroup();
virtual const cChannel* NextChannel(const cChannel *Channel) = 0; virtual const cChannel* NextChannel(const cChannel *Channel) = 0;
static inline const cChannel* SkipFakeGroups(const cChannel *Channel); static inline const cChannel* SkipFakeGroups(const cChannel *Channel);
// Helper which returns the group by its index // Helper which returns the group by its index
@ -208,8 +211,15 @@ class cRssMenuList: public cMenuList
inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group) inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group)
{ {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
#endif
while (Group && Group->GroupSep() && !*Group->Name()) while (Group && Group->GroupSep() && !*Group->Name())
#if APIVERSNUM >= 20300
Group = Channels->Next(Group);
#else
Group = Channels.Next(Group); Group = Channels.Next(Group);
#endif
return Group; return Group;
} }

View File

@ -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) const cList<cServerConnection>& cStreamdevServer::Clients(cThreadLock& Lock)
#endif
{ {
Lock.Lock(m_Instance); Lock.Lock(m_Instance);
return m_Clients; return m_Clients;

View File

@ -37,7 +37,11 @@ public:
static void Destruct(void); static void Destruct(void);
static bool Active(void); static bool Active(void);
#if APIVERSNUM >= 20300
static cList<cServerConnection>& Clients(cThreadLock& Lock);
#else
static const cList<cServerConnection>& Clients(cThreadLock& Lock); static const cList<cServerConnection>& Clients(cThreadLock& Lock);
#endif
}; };
inline bool cStreamdevServer::Active(void) inline bool cStreamdevServer::Active(void)

View File

@ -21,7 +21,11 @@
cList<cMainThreadHookSubscriber> cMainThreadHookSubscriber::m_Subscribers; cList<cMainThreadHookSubscriber> cMainThreadHookSubscriber::m_Subscribers;
cMutex cMainThreadHookSubscriber::m_Mutex; cMutex cMainThreadHookSubscriber::m_Mutex;
#if APIVERSNUM >= 20300
cList<cMainThreadHookSubscriber>& cMainThreadHookSubscriber::Subscribers(cMutexLock& Lock)
#else
const cList<cMainThreadHookSubscriber>& cMainThreadHookSubscriber::Subscribers(cMutexLock& Lock) const cList<cMainThreadHookSubscriber>& cMainThreadHookSubscriber::Subscribers(cMutexLock& Lock)
#endif
{ {
Lock.Lock(&m_Mutex); Lock.Lock(&m_Mutex);
return m_Subscribers; return m_Subscribers;
@ -163,7 +167,11 @@ void cPluginStreamdevServer::MainThreadHook(void)
} }
cMutexLock lock; cMutexLock lock;
#if APIVERSNUM >= 20300
cList<cMainThreadHookSubscriber>& subs = cMainThreadHookSubscriber::Subscribers(lock);
#else
const cList<cMainThreadHookSubscriber>& subs = cMainThreadHookSubscriber::Subscribers(lock); const cList<cMainThreadHookSubscriber>& subs = cMainThreadHookSubscriber::Subscribers(lock);
#endif
for (cMainThreadHookSubscriber *s = subs.First(); s; s = subs.Next(s)) for (cMainThreadHookSubscriber *s = subs.First(); s; s = subs.Next(s))
s->MainThreadHook(); s->MainThreadHook();
} }
@ -199,7 +207,11 @@ cString cPluginStreamdevServer::SVDRPCommand(const char *Command, const char *Op
{ {
reply = ""; reply = "";
cThreadLock lock; cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock); const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
cServerConnection *s = clients.First(); cServerConnection *s = clients.First();
if (!s) if (!s)
{ {
@ -223,7 +235,11 @@ cString cPluginStreamdevServer::SVDRPCommand(const char *Command, const char *Op
} else } else
{ {
cThreadLock lock; cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock); const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
cServerConnection *s = clients.First(); cServerConnection *s = clients.First();
for (; s && s != client; s = clients.Next(s)); for (; s && s != client; s = clients.Next(s));

View File

@ -15,7 +15,11 @@ private:
static cList<cMainThreadHookSubscriber> m_Subscribers; static cList<cMainThreadHookSubscriber> m_Subscribers;
static cMutex m_Mutex; static cMutex m_Mutex;
public: public:
#if APIVERSNUM >= 20300
static cList<cMainThreadHookSubscriber>& Subscribers(cMutexLock& Lock);
#else
static const cList<cMainThreadHookSubscriber>& Subscribers(cMutexLock& Lock); static const cList<cMainThreadHookSubscriber>& Subscribers(cMutexLock& Lock);
#endif
virtual void MainThreadHook() = 0; virtual void MainThreadHook() = 0;