mirror of
https://github.com/rofafor/vdr-plugin-iptv.git
synced 2023-10-10 13:37:03 +02:00
Disable detaching of receivers if retuned to an existing channel (Thanks to Zdeněk Kopřivík).
This commit is contained in:
parent
ea4f8fde31
commit
55bb0e65df
4
HISTORY
4
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).
|
||||
|
14
device.c
14
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;
|
||||
}
|
||||
|
3
device.h
3
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:
|
||||
|
16
pidscanner.c
16
pidscanner.c
@ -15,6 +15,7 @@
|
||||
|
||||
cPidScanner::cPidScanner(void)
|
||||
: timeout(0),
|
||||
channelId(tChannelID::InvalidID),
|
||||
process(true),
|
||||
Vpid(0xFFFF),
|
||||
Apid(0xFFFF),
|
||||
@ -22,7 +23,6 @@ cPidScanner::cPidScanner(void)
|
||||
numApids(0)
|
||||
{
|
||||
debug("cPidScanner::cPidScanner()\n");
|
||||
channel = cChannel();
|
||||
}
|
||||
|
||||
cPidScanner::~cPidScanner()
|
||||
@ -30,16 +30,10 @@ 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 };
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
37
sidscanner.c
37
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);
|
||||
}
|
||||
}
|
||||
|
@ -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); }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user