Disable detaching of receivers if retuned to an existing channel (Thanks to Zdeněk Kopřivík).

This commit is contained in:
Rolf Ahrenberg 2010-11-29 21:09:17 +02:00
parent ea4f8fde31
commit 55bb0e65df
7 changed files with 43 additions and 44 deletions

View File

@ -142,7 +142,7 @@ VDR Plugin 'iptv' Revision History
- Updated for vdr-1.7.15.
2010-xx-xx: Version 0.4.3
2010-12-06: Version 0.4.3
- Updated for vdr-1.7.16.
- Renamed Sid scanner to section id scanner and added
@ -153,3 +153,5 @@ VDR Plugin 'iptv' Revision History
receivers due to VDR's channel selection mechanism.
- Enabled partial content responses for HTTP protocol.
- Fixed EXT protocol execution (Thanks to Peter Holik).
- Disable detaching of receivers if retuned to an existing
channel (Thanks to Zdeněk Kopřivík).

View File

@ -21,7 +21,8 @@ cIptvDevice::cIptvDevice(unsigned int Index)
isPacketDelivered(false),
isOpenDvr(false),
sidScanEnabled(false),
pidScanEnabled(false)
pidScanEnabled(false),
channelId(tChannelID::InvalidID)
{
unsigned int bufsize = (unsigned int)MEGABYTE(IptvConfig.GetTsBufferSize());
bufsize -= (bufsize % TS_SIZE);
@ -35,13 +36,13 @@ cIptvDevice::cIptvDevice(unsigned int Index)
pFileProtocol = new cIptvProtocolFile();
pExtProtocol = new cIptvProtocolExt();
pIptvStreamer = new cIptvStreamer(tsBuffer, (100 * TS_SIZE));
pPidScanner = new cPidScanner;
pPidScanner = new cPidScanner();
// Initialize filter pointers
memset(secfilters, '\0', sizeof(secfilters));
// Start section handler for iptv device
StartSectionHandler();
// Sid scanner must be created after the section handler
pSidScanner = new cSidScanner;
pSidScanner = new cSidScanner();
if (pSidScanner)
AttachFilter(pSidScanner);
// Check if dvr fifo exists
@ -193,7 +194,7 @@ bool cIptvDevice::ProvidesTransponder(const cChannel *Channel) const
bool cIptvDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
{
bool result = false;
bool needsDetachReceivers = Receiving(true);
bool needsDetachReceivers = Receiving(true) && Channel && !(Channel->GetChannelID() == channelId);
debug("cIptvDevice::ProvidesChannel(%d)\n", deviceIndex);
if (ProvidesTransponder(Channel))
@ -240,10 +241,11 @@ bool cIptvDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
sidScanEnabled = itp.SidScan() ? true : false;
pidScanEnabled = itp.PidScan() ? true : false;
if (pIptvStreamer->Set(itp.Address(), itp.Parameter(), deviceIndex, protocol)) {
channelId = Channel->GetChannelID();
if (sidScanEnabled && pSidScanner && IptvConfig.GetSectionFiltering())
pSidScanner->SetChannel(Channel);
pSidScanner->SetChannel(channelId);
if (pidScanEnabled && pPidScanner)
pPidScanner->SetChannel(Channel);
pPidScanner->SetChannel(channelId);
}
return true;
}

View File

@ -41,6 +41,7 @@ private:
bool pidScanEnabled;
cRingBufferLinear *tsBuffer;
int tsBufferPrefill;
tChannelID channelId;
cIptvProtocolUdp *pUdpProtocol;
cIptvProtocolHttp *pHttpProtocol;
cIptvProtocolFile *pFileProtocol;
@ -49,7 +50,7 @@ private:
cPidScanner *pPidScanner;
cSidScanner *pSidScanner;
cMutex mutex;
cIptvSectionFilter* secfilters[eMaxSecFilterCount];
cIptvSectionFilter *secfilters[eMaxSecFilterCount];
// constructor & destructor
public:

View File

@ -13,8 +13,9 @@
#define PIDSCANNER_VPID_COUNT 5 /* minimum count of video pid samples for pid detection */
#define PIDSCANNER_PID_DELTA_COUNT 100 /* minimum count of pid samples for audio/video only pid detection */
cPidScanner::cPidScanner(void)
cPidScanner::cPidScanner(void)
: timeout(0),
channelId(tChannelID::InvalidID),
process(true),
Vpid(0xFFFF),
Apid(0xFFFF),
@ -22,24 +23,17 @@ cPidScanner::cPidScanner(void)
numApids(0)
{
debug("cPidScanner::cPidScanner()\n");
channel = cChannel();
}
cPidScanner::~cPidScanner()
cPidScanner::~cPidScanner()
{
debug("cPidScanner::~cPidScanner()\n");
}
void cPidScanner::SetChannel(const cChannel *Channel)
void cPidScanner::SetChannel(const tChannelID &ChannelId)
{
if (Channel) {
debug("cPidScanner::SetChannel(): %s\n", Channel->Parameters());
channel = *Channel;
}
else {
debug("cPidScanner::SetChannel()\n");
channel = cChannel();
}
debug("cPidScanner::SetChannel(): %s\n", *ChannelId->ToString());
channelId = ChannelId;
Vpid = 0xFFFF;
numVpids = 0;
Apid = 0xFFFF;
@ -119,7 +113,7 @@ void cPidScanner::Process(const uint8_t* buf)
timeout.Set(PIDSCANNER_TIMEOUT_IN_MS);
return;
}
cChannel *IptvChannel = Channels.GetByChannelID(channel.GetChannelID());
cChannel *IptvChannel = Channels.GetByChannelID(channelId);
if (IptvChannel) {
int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
int Atypes[MAXAPIDS + 1] = { 0 };

View File

@ -14,7 +14,7 @@
class cPidScanner {
private:
cTimeMs timeout;
cChannel channel;
tChannelID channelId;
bool process;
int Vpid;
int Apid;
@ -24,7 +24,7 @@ private:
public:
cPidScanner(void);
~cPidScanner();
void SetChannel(const cChannel *Channel);
void SetChannel(const tChannelID &ChannelId);
void Process(const uint8_t* buf);
};

View File

@ -11,35 +11,34 @@
#include "sidscanner.h"
cSidScanner::cSidScanner(void)
: channelId(tChannelID::InvalidID),
sidFound(false),
nidFound(false),
tidFound(false)
{
debug("cSidScanner::cSidScanner()\n");
channel = cChannel();
sidFound = false;
nidFound = false;
tidFound = false;
Set(0x00, 0x00); // PAT
Set(0x10, 0x40); // NIT
}
cSidScanner::~cSidScanner()
{
debug("cSidScanner::~cSidScanner()\n");
}
void cSidScanner::SetStatus(bool On)
{
debug("cSidScanner::SetStatus(): %d\n", On);
cFilter::SetStatus(On);
}
void cSidScanner::SetChannel(const cChannel *Channel)
void cSidScanner::SetChannel(const tChannelID &ChannelId)
{
debug("cSidScanner::SetChannel(): %s\n", *ChannelId->ToString());
channelId = ChannelId;
sidFound = false;
nidFound = false;
tidFound = false;
if (Channel) {
debug("cSidScanner::SetChannel(): %s\n", Channel->Parameters());
channel = *Channel;
}
else {
debug("cSidScanner::SetChannel()\n");
channel = cChannel();
}
}
void cSidScanner::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
@ -47,7 +46,7 @@ void cSidScanner::Process(u_short Pid, u_char Tid, const u_char *Data, int Lengt
int newSid = -1, newNid = -1, newTid = -1;
//debug("cSidScanner::Process()\n");
if (channel.GetChannelID().Valid()) {
if (channelId.Valid()) {
if ((Pid == 0x00) && (Tid == 0x00)) {
debug("cSidScanner::Process(): Pid=%d Tid=%02X\n", Pid, Tid);
SI::PAT pat(Data, false);
@ -56,7 +55,7 @@ void cSidScanner::Process(u_short Pid, u_char Tid, const u_char *Data, int Lengt
SI::PAT::Association assoc;
for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) {
if (!assoc.isNITPid()) {
if (assoc.getServiceId() != channel.Sid()) {
if (assoc.getServiceId() != channelId.Sid()) {
debug("cSidScanner::Process(): Sid=%d\n", assoc.getServiceId());
newSid = assoc.getServiceId();
}
@ -72,14 +71,14 @@ void cSidScanner::Process(u_short Pid, u_char Tid, const u_char *Data, int Lengt
return;
SI::NIT::TransportStream ts;
for (SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it); ) {
if (ts.getTransportStreamId() != channel.Tid()) {
if (ts.getTransportStreamId() != channelId.Tid()) {
debug("cSidScanner::Process(): TSid=%d\n", ts.getTransportStreamId());
newTid = ts.getTransportStreamId();
}
tidFound = true;
break; // default to the first one
}
if (nit.getNetworkId() != channel.Nid()) {
if (nit.getNetworkId() != channelId.Nid()) {
debug("cSidScanner::Process(): Nid=%d\n", ts.getTransportStreamId());
newNid = nit.getNetworkId();
}
@ -89,14 +88,14 @@ void cSidScanner::Process(u_short Pid, u_char Tid, const u_char *Data, int Lengt
if ((newSid >= 0) || (newNid >= 0) || (newTid >= 0)) {
if (!Channels.Lock(true, 10))
return;
cChannel *IptvChannel = Channels.GetByChannelID(channel.GetChannelID());
cChannel *IptvChannel = Channels.GetByChannelID(channelId);
if (IptvChannel)
IptvChannel->SetId((newNid < 0) ? IptvChannel->Nid() : newNid, (newTid < 0) ? IptvChannel->Tid() : newTid,
(newSid < 0) ? IptvChannel->Sid() : newSid, IptvChannel->Rid());
Channels.Unlock();
}
if (sidFound && nidFound && tidFound) {
SetChannel(NULL);
SetChannel(tChannelID::InvalidID);
SetStatus(false);
}
}

View File

@ -13,7 +13,7 @@
class cSidScanner : public cFilter {
private:
cChannel channel;
tChannelID channelId;
bool sidFound;
bool nidFound;
bool tidFound;
@ -24,7 +24,8 @@ protected:
public:
cSidScanner(void);
void SetChannel(const cChannel *Channel);
~cSidScanner();
void SetChannel(const tChannelID &ChannelId);
void Open() { SetStatus(true); }
void Close() { SetStatus(false); }
};