mirror of
https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
synced 2023-10-10 17:16:51 +00:00
Snapshot 2010-09-15
This commit is contained in:
committed by
Mikko Matilainen
parent
db3274c046
commit
635ccc479f
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: connection.c,v 1.10.2.3 2010/07/19 13:50:14 schmirl Exp $
|
||||
* $Id: connection.c,v 1.10.2.4 2010/08/03 10:56:58 schmirl Exp $
|
||||
*/
|
||||
|
||||
#include "server/connection.h"
|
||||
@@ -254,12 +254,16 @@ cDevice *cServerConnection::GetDevice(const cChannel *Channel, int Priority)
|
||||
}
|
||||
Dprintf(" * Found device for live tv: %p (%d)\n", newdev,
|
||||
newdev ? newdev->CardIndex() + 1 : 0);
|
||||
if (newdev == NULL || newdev == device)
|
||||
if (newdev == NULL || newdev == device) {
|
||||
// no suitable device to continue live TV, giving up...
|
||||
device = NULL;
|
||||
dsyslog("streamdev: Not providing channel %s at priority %d - live TV not suspended", Channel->Name(), Priority);
|
||||
}
|
||||
else
|
||||
newdev->SwitchChannel(current, true);
|
||||
}
|
||||
else if (!device)
|
||||
dsyslog("streamdev: No device provides channel %s at priority %d", Channel->Name(), Priority);
|
||||
}
|
||||
|
||||
return device;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: connectionVTP.c,v 1.18.2.7 2010/07/19 13:50:14 schmirl Exp $
|
||||
* $Id: connectionVTP.c,v 1.18.2.9 2010/08/18 10:26:19 schmirl Exp $
|
||||
*/
|
||||
|
||||
#include "server/connectionVTP.h"
|
||||
@@ -726,6 +726,8 @@ cConnectionVTP::cConnectionVTP(void):
|
||||
m_StreamType(stTSPIDS),
|
||||
m_FiltersSupport(false),
|
||||
m_RecPlayer(NULL),
|
||||
m_TuneChannel(NULL),
|
||||
m_TunePriority(0),
|
||||
m_LSTEHandler(NULL),
|
||||
m_LSTCHandler(NULL),
|
||||
m_LSTTHandler(NULL),
|
||||
@@ -816,6 +818,7 @@ bool cConnectionVTP::Command(char *Cmd)
|
||||
else if (strcasecmp(Cmd, "READ") == 0) return CmdREAD(param);
|
||||
else if (strcasecmp(Cmd, "TUNE") == 0) return CmdTUNE(param);
|
||||
else if (strcasecmp(Cmd, "PLAY") == 0) return CmdPLAY(param);
|
||||
else if (strcasecmp(Cmd, "PRIO") == 0) return CmdPRIO(param);
|
||||
else if (strcasecmp(Cmd, "ADDP") == 0) return CmdADDP(param);
|
||||
else if (strcasecmp(Cmd, "DELP") == 0) return CmdDELP(param);
|
||||
else if (strcasecmp(Cmd, "ADDF") == 0) return CmdADDF(param);
|
||||
@@ -874,6 +877,11 @@ bool cConnectionVTP::CmdCAPS(char *Opts)
|
||||
return Respond(220, "Capability \"%s\" accepted", Opts);
|
||||
}
|
||||
|
||||
// Command PRIO is known
|
||||
if (strcasecmp(Opts, "PRIO") == 0) {
|
||||
return Respond(220, "Capability \"%s\" accepted", Opts);
|
||||
}
|
||||
|
||||
return Respond(561, "Capability \"%s\" not known", Opts);
|
||||
}
|
||||
|
||||
@@ -891,9 +899,15 @@ bool cConnectionVTP::CmdPROV(char *Opts)
|
||||
if ((chan = ChannelFromString(Opts)) == NULL)
|
||||
return Respond(550, "Undefined channel \"%s\"", Opts);
|
||||
|
||||
return GetDevice(chan, prio) != NULL
|
||||
? Respond(220, "Channel available")
|
||||
: Respond(560, "Channel not available");
|
||||
if (GetDevice(chan, prio)) {
|
||||
m_TuneChannel = chan;
|
||||
m_TunePriority = prio;
|
||||
return Respond(220, "Channel available");
|
||||
}
|
||||
else {
|
||||
m_TuneChannel = NULL;
|
||||
return Respond(560, "Channel not available");
|
||||
}
|
||||
}
|
||||
|
||||
bool cConnectionVTP::CmdPORT(char *Opts)
|
||||
@@ -1047,18 +1061,23 @@ bool cConnectionVTP::CmdTUNE(char *Opts)
|
||||
{
|
||||
const cChannel *chan;
|
||||
cDevice *dev;
|
||||
int prio = m_TunePriority;
|
||||
|
||||
if ((chan = ChannelFromString(Opts)) == NULL)
|
||||
return Respond(550, "Undefined channel \"%s\"", Opts);
|
||||
|
||||
if ((dev = GetDevice(chan, 0)) == NULL)
|
||||
if (chan != m_TuneChannel) {
|
||||
esyslog("streamdev-server TUNE %s: Priority unknown - using 0", Opts);
|
||||
prio = 0;
|
||||
}
|
||||
if ((dev = GetDevice(chan, prio)) == NULL)
|
||||
return Respond(560, "Channel not available");
|
||||
|
||||
if (!dev->SwitchChannel(chan, false))
|
||||
return Respond(560, "Channel not available");
|
||||
|
||||
delete m_LiveStreamer;
|
||||
m_LiveStreamer = new cStreamdevLiveStreamer(1, this);
|
||||
m_LiveStreamer = new cStreamdevLiveStreamer(prio, this);
|
||||
m_LiveStreamer->SetChannel(chan, m_StreamType);
|
||||
m_LiveStreamer->SetDevice(dev);
|
||||
if(m_LiveSocket)
|
||||
@@ -1099,6 +1118,22 @@ bool cConnectionVTP::CmdPLAY(char *Opts)
|
||||
}
|
||||
}
|
||||
|
||||
bool cConnectionVTP::CmdPRIO(char *Opts)
|
||||
{
|
||||
int prio;
|
||||
char *end;
|
||||
|
||||
prio = strtoul(Opts, &end, 10);
|
||||
if (end == Opts || (*end != '\0' && *end != ' '))
|
||||
return Respond(500, "Use: PRIO Priority");
|
||||
|
||||
if (m_LiveStreamer) {
|
||||
m_LiveStreamer->SetPriority(prio);
|
||||
return Respond(220, "Priority changed to %d", prio);
|
||||
}
|
||||
return Respond(550, "Priority not applicable");
|
||||
}
|
||||
|
||||
bool cConnectionVTP::CmdADDP(char *Opts)
|
||||
{
|
||||
int pid;
|
||||
@@ -1223,6 +1258,7 @@ bool cConnectionVTP::CmdSUSP(void)
|
||||
else if (StreamdevServerSetup.SuspendMode == smOffer
|
||||
&& StreamdevServerSetup.AllowSuspend) {
|
||||
cControl::Launch(new cSuspendCtl);
|
||||
cControl::Attach();
|
||||
return Respond(220, "Server is suspended");
|
||||
} else
|
||||
return Respond(550, "Client may not suspend server");
|
||||
|
||||
@@ -31,6 +31,11 @@ private:
|
||||
bool m_FiltersSupport;
|
||||
RecPlayer *m_RecPlayer;
|
||||
|
||||
// Priority is only known in PROV command
|
||||
// Store in here for later use in TUNE call
|
||||
const cChannel *m_TuneChannel;
|
||||
int m_TunePriority;
|
||||
|
||||
// Members adopted for SVDRP
|
||||
cLSTEHandler *m_LSTEHandler;
|
||||
cLSTCHandler *m_LSTCHandler;
|
||||
@@ -59,6 +64,7 @@ public:
|
||||
bool CmdREAD(char *Opts);
|
||||
bool CmdTUNE(char *Opts);
|
||||
bool CmdPLAY(char *Opts);
|
||||
bool CmdPRIO(char *Opts);
|
||||
bool CmdADDP(char *Opts);
|
||||
bool CmdDELP(char *Opts);
|
||||
bool CmdADDF(char *Opts);
|
||||
|
||||
@@ -297,7 +297,7 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
|
||||
if (written != TS_SIZE)
|
||||
siBuffer.ReportOverflow(TS_SIZE - written);
|
||||
if (pmtPid != prevPmtPid) {
|
||||
m_Streamer->SetPids(pmtPid);
|
||||
m_Streamer->SetPid(pmtPid, true);
|
||||
Add(pmtPid, 0x02);
|
||||
pmtVersion = -1;
|
||||
}
|
||||
@@ -442,21 +442,28 @@ bool cStreamdevLiveStreamer::SetPids(int Pid, const int *Pids1, const int *Pids2
|
||||
return true;
|
||||
}
|
||||
|
||||
void cStreamdevLiveStreamer::SetPriority(int Priority)
|
||||
{
|
||||
m_Priority = Priority;
|
||||
StartReceiver();
|
||||
}
|
||||
|
||||
void cStreamdevLiveStreamer::StartReceiver(void)
|
||||
{
|
||||
DELETENULL(m_Receiver);
|
||||
if (m_NumPids > 0) {
|
||||
if (m_Device != NULL && m_NumPids > 0 && IsRunning()) {
|
||||
Dprintf("Creating Receiver to respect changed pids\n");
|
||||
cReceiver *current = m_Receiver;
|
||||
#if VDRVERSNUM < 10500
|
||||
m_Receiver = new cStreamdevLiveReceiver(this, m_Channel->Ca(), m_Priority, m_Pids);
|
||||
#else
|
||||
m_Receiver = new cStreamdevLiveReceiver(this, m_Channel->GetChannelID(), m_Priority, m_Pids);
|
||||
#endif
|
||||
if (IsRunning() && m_Device != NULL) {
|
||||
Dprintf("Attaching new receiver\n");
|
||||
Attach();
|
||||
}
|
||||
cThreadLock ThreadLock(m_Device);
|
||||
Attach();
|
||||
delete current;
|
||||
}
|
||||
else
|
||||
DELETENULL(m_Receiver);
|
||||
}
|
||||
|
||||
bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, const int* Apid, const int *Dpid)
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
bool SetPid(int Pid, bool On);
|
||||
bool SetPids(int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL);
|
||||
bool SetChannel(const cChannel *Channel, eStreamType StreamType, const int* Apid = NULL, const int* Dpid = NULL);
|
||||
void SetPriority(int Priority);
|
||||
|
||||
virtual int Put(const uchar *Data, int Count);
|
||||
virtual uchar *Get(int &Count);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "server/menuHTTP.h"
|
||||
|
||||
//**************************** cChannelIterator **************
|
||||
cChannelIterator::cChannelIterator(cChannel *First): channel(First)
|
||||
cChannelIterator::cChannelIterator(const cChannel *First): channel(First)
|
||||
{}
|
||||
|
||||
const cChannel* cChannelIterator::Next()
|
||||
@@ -19,7 +19,7 @@ cListAll::cListAll(): cChannelIterator(Channels.First())
|
||||
const cChannel* cListAll::NextChannel(const cChannel *Channel)
|
||||
{
|
||||
if (Channel)
|
||||
Channel = Channels.Next(Channel);
|
||||
Channel = SkipFakeGroups(Channels.Next(Channel));
|
||||
return Channel;
|
||||
}
|
||||
|
||||
@@ -46,14 +46,19 @@ const cChannel* cListGroups::NextChannel(const cChannel *Channel)
|
||||
}
|
||||
//
|
||||
// ********************* cListGroup ****************
|
||||
cListGroup::cListGroup(const cChannel *Group): cChannelIterator((Group && Group->GroupSep() && Channels.Next(Group) && !Channels.Next(Group)->GroupSep()) ? Channels.Next(Group) : NULL)
|
||||
cListGroup::cListGroup(const cChannel *Group): cChannelIterator(GetNextChannelInGroup(Group))
|
||||
{}
|
||||
|
||||
const cChannel* cListGroup::GetNextChannelInGroup(const cChannel *Channel)
|
||||
{
|
||||
if (Channel)
|
||||
Channel = SkipFakeGroups(Channels.Next(Channel));
|
||||
return Channel && !Channel->GroupSep() ? Channel : NULL;
|
||||
}
|
||||
|
||||
const cChannel* cListGroup::NextChannel(const cChannel *Channel)
|
||||
{
|
||||
if (Channel)
|
||||
Channel = Channels.Next(Channel);
|
||||
return (Channel && !Channel->GroupSep()) ? Channel : NULL;
|
||||
return GetNextChannelInGroup(Channel);
|
||||
}
|
||||
//
|
||||
// ********************* cListTree ****************
|
||||
@@ -68,7 +73,7 @@ const cChannel* cListTree::NextChannel(const cChannel *Channel)
|
||||
if (currentGroup == selectedGroup)
|
||||
{
|
||||
if (Channel)
|
||||
Channel = Channels.Next(Channel);
|
||||
Channel = SkipFakeGroups(Channels.Next(Channel));
|
||||
if (Channel && Channel->GroupSep())
|
||||
currentGroup = Channel;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@ class cChannelIterator
|
||||
const cChannel *channel;
|
||||
protected:
|
||||
virtual const cChannel* NextChannel(const cChannel *Channel) = 0;
|
||||
static inline const cChannel* SkipFakeGroups(const cChannel *Channel);
|
||||
public:
|
||||
const cChannel* Next();
|
||||
cChannelIterator(cChannel *First);
|
||||
cChannelIterator(const cChannel *First);
|
||||
virtual ~cChannelIterator() {};
|
||||
};
|
||||
|
||||
@@ -48,6 +49,8 @@ class cListGroups: public cChannelIterator
|
||||
|
||||
class cListGroup: public cChannelIterator
|
||||
{
|
||||
private:
|
||||
static const cChannel* GetNextChannelInGroup(const cChannel *Channel);
|
||||
protected:
|
||||
virtual const cChannel* NextChannel(const cChannel *Channel);
|
||||
public:
|
||||
@@ -155,4 +158,11 @@ class cM3uChannelList: public cChannelList
|
||||
virtual ~cM3uChannelList();
|
||||
};
|
||||
|
||||
inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group)
|
||||
{
|
||||
while (Group && Group->GroupSep() && !*Group->Name())
|
||||
Group = Channels.Next(Group);
|
||||
return Group;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user