From 55bb0e65df7cc73a1641cc8ca81a84afbc03406b Mon Sep 17 00:00:00 2001 From: Rolf Ahrenberg Date: Mon, 29 Nov 2010 21:09:17 +0200 Subject: [PATCH] =?UTF-8?q?Disable=20detaching=20of=20receivers=20if=20ret?= =?UTF-8?q?uned=20to=20an=20existing=20channel=20(Thanks=20to=20Zden=C4=9B?= =?UTF-8?q?k=20Kop=C5=99iv=C3=ADk).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY | 4 +++- device.c | 14 ++++++++------ device.h | 3 ++- pidscanner.c | 20 +++++++------------- pidscanner.h | 4 ++-- sidscanner.c | 37 ++++++++++++++++++------------------- sidscanner.h | 5 +++-- 7 files changed, 43 insertions(+), 44 deletions(-) diff --git a/HISTORY b/HISTORY index d4dd81f..0511348 100644 --- a/HISTORY +++ b/HISTORY @@ -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). diff --git a/device.c b/device.c index 1401b5e..ecf12f1 100644 --- a/device.c +++ b/device.c @@ -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; } diff --git a/device.h b/device.h index f0be16d..8a8ec9f 100644 --- a/device.h +++ b/device.h @@ -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: diff --git a/pidscanner.c b/pidscanner.c index e26e8ea..c9dbe1c 100644 --- a/pidscanner.c +++ b/pidscanner.c @@ -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 }; diff --git a/pidscanner.h b/pidscanner.h index a5718e9..92845fd 100644 --- a/pidscanner.h +++ b/pidscanner.h @@ -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); }; diff --git a/sidscanner.c b/sidscanner.c index 8f4a110..8ae7e78 100644 --- a/sidscanner.c +++ b/sidscanner.c @@ -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); } } diff --git a/sidscanner.h b/sidscanner.h index b4bb53e..4d6c74b 100644 --- a/sidscanner.h +++ b/sidscanner.h @@ -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); } };