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.
|
- 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.
|
- Updated for vdr-1.7.16.
|
||||||
- Renamed Sid scanner to section id scanner and added
|
- 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.
|
receivers due to VDR's channel selection mechanism.
|
||||||
- Enabled partial content responses for HTTP protocol.
|
- Enabled partial content responses for HTTP protocol.
|
||||||
- Fixed EXT protocol execution (Thanks to Peter Holik).
|
- 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),
|
isPacketDelivered(false),
|
||||||
isOpenDvr(false),
|
isOpenDvr(false),
|
||||||
sidScanEnabled(false),
|
sidScanEnabled(false),
|
||||||
pidScanEnabled(false)
|
pidScanEnabled(false),
|
||||||
|
channelId(tChannelID::InvalidID)
|
||||||
{
|
{
|
||||||
unsigned int bufsize = (unsigned int)MEGABYTE(IptvConfig.GetTsBufferSize());
|
unsigned int bufsize = (unsigned int)MEGABYTE(IptvConfig.GetTsBufferSize());
|
||||||
bufsize -= (bufsize % TS_SIZE);
|
bufsize -= (bufsize % TS_SIZE);
|
||||||
@ -35,13 +36,13 @@ cIptvDevice::cIptvDevice(unsigned int Index)
|
|||||||
pFileProtocol = new cIptvProtocolFile();
|
pFileProtocol = new cIptvProtocolFile();
|
||||||
pExtProtocol = new cIptvProtocolExt();
|
pExtProtocol = new cIptvProtocolExt();
|
||||||
pIptvStreamer = new cIptvStreamer(tsBuffer, (100 * TS_SIZE));
|
pIptvStreamer = new cIptvStreamer(tsBuffer, (100 * TS_SIZE));
|
||||||
pPidScanner = new cPidScanner;
|
pPidScanner = new cPidScanner();
|
||||||
// Initialize filter pointers
|
// Initialize filter pointers
|
||||||
memset(secfilters, '\0', sizeof(secfilters));
|
memset(secfilters, '\0', sizeof(secfilters));
|
||||||
// Start section handler for iptv device
|
// Start section handler for iptv device
|
||||||
StartSectionHandler();
|
StartSectionHandler();
|
||||||
// Sid scanner must be created after the section handler
|
// Sid scanner must be created after the section handler
|
||||||
pSidScanner = new cSidScanner;
|
pSidScanner = new cSidScanner();
|
||||||
if (pSidScanner)
|
if (pSidScanner)
|
||||||
AttachFilter(pSidScanner);
|
AttachFilter(pSidScanner);
|
||||||
// Check if dvr fifo exists
|
// 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 cIptvDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
bool needsDetachReceivers = Receiving(true);
|
bool needsDetachReceivers = Receiving(true) && Channel && !(Channel->GetChannelID() == channelId);
|
||||||
|
|
||||||
debug("cIptvDevice::ProvidesChannel(%d)\n", deviceIndex);
|
debug("cIptvDevice::ProvidesChannel(%d)\n", deviceIndex);
|
||||||
if (ProvidesTransponder(Channel))
|
if (ProvidesTransponder(Channel))
|
||||||
@ -240,10 +241,11 @@ bool cIptvDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
|||||||
sidScanEnabled = itp.SidScan() ? true : false;
|
sidScanEnabled = itp.SidScan() ? true : false;
|
||||||
pidScanEnabled = itp.PidScan() ? true : false;
|
pidScanEnabled = itp.PidScan() ? true : false;
|
||||||
if (pIptvStreamer->Set(itp.Address(), itp.Parameter(), deviceIndex, protocol)) {
|
if (pIptvStreamer->Set(itp.Address(), itp.Parameter(), deviceIndex, protocol)) {
|
||||||
|
channelId = Channel->GetChannelID();
|
||||||
if (sidScanEnabled && pSidScanner && IptvConfig.GetSectionFiltering())
|
if (sidScanEnabled && pSidScanner && IptvConfig.GetSectionFiltering())
|
||||||
pSidScanner->SetChannel(Channel);
|
pSidScanner->SetChannel(channelId);
|
||||||
if (pidScanEnabled && pPidScanner)
|
if (pidScanEnabled && pPidScanner)
|
||||||
pPidScanner->SetChannel(Channel);
|
pPidScanner->SetChannel(channelId);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
3
device.h
3
device.h
@ -41,6 +41,7 @@ private:
|
|||||||
bool pidScanEnabled;
|
bool pidScanEnabled;
|
||||||
cRingBufferLinear *tsBuffer;
|
cRingBufferLinear *tsBuffer;
|
||||||
int tsBufferPrefill;
|
int tsBufferPrefill;
|
||||||
|
tChannelID channelId;
|
||||||
cIptvProtocolUdp *pUdpProtocol;
|
cIptvProtocolUdp *pUdpProtocol;
|
||||||
cIptvProtocolHttp *pHttpProtocol;
|
cIptvProtocolHttp *pHttpProtocol;
|
||||||
cIptvProtocolFile *pFileProtocol;
|
cIptvProtocolFile *pFileProtocol;
|
||||||
@ -49,7 +50,7 @@ private:
|
|||||||
cPidScanner *pPidScanner;
|
cPidScanner *pPidScanner;
|
||||||
cSidScanner *pSidScanner;
|
cSidScanner *pSidScanner;
|
||||||
cMutex mutex;
|
cMutex mutex;
|
||||||
cIptvSectionFilter* secfilters[eMaxSecFilterCount];
|
cIptvSectionFilter *secfilters[eMaxSecFilterCount];
|
||||||
|
|
||||||
// constructor & destructor
|
// constructor & destructor
|
||||||
public:
|
public:
|
||||||
|
20
pidscanner.c
20
pidscanner.c
@ -13,8 +13,9 @@
|
|||||||
#define PIDSCANNER_VPID_COUNT 5 /* minimum count of video pid samples for pid detection */
|
#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 */
|
#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),
|
: timeout(0),
|
||||||
|
channelId(tChannelID::InvalidID),
|
||||||
process(true),
|
process(true),
|
||||||
Vpid(0xFFFF),
|
Vpid(0xFFFF),
|
||||||
Apid(0xFFFF),
|
Apid(0xFFFF),
|
||||||
@ -22,24 +23,17 @@ cPidScanner::cPidScanner(void)
|
|||||||
numApids(0)
|
numApids(0)
|
||||||
{
|
{
|
||||||
debug("cPidScanner::cPidScanner()\n");
|
debug("cPidScanner::cPidScanner()\n");
|
||||||
channel = cChannel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cPidScanner::~cPidScanner()
|
cPidScanner::~cPidScanner()
|
||||||
{
|
{
|
||||||
debug("cPidScanner::~cPidScanner()\n");
|
debug("cPidScanner::~cPidScanner()\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cPidScanner::SetChannel(const cChannel *Channel)
|
void cPidScanner::SetChannel(const tChannelID &ChannelId)
|
||||||
{
|
{
|
||||||
if (Channel) {
|
debug("cPidScanner::SetChannel(): %s\n", *ChannelId->ToString());
|
||||||
debug("cPidScanner::SetChannel(): %s\n", Channel->Parameters());
|
channelId = ChannelId;
|
||||||
channel = *Channel;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
debug("cPidScanner::SetChannel()\n");
|
|
||||||
channel = cChannel();
|
|
||||||
}
|
|
||||||
Vpid = 0xFFFF;
|
Vpid = 0xFFFF;
|
||||||
numVpids = 0;
|
numVpids = 0;
|
||||||
Apid = 0xFFFF;
|
Apid = 0xFFFF;
|
||||||
@ -119,7 +113,7 @@ void cPidScanner::Process(const uint8_t* buf)
|
|||||||
timeout.Set(PIDSCANNER_TIMEOUT_IN_MS);
|
timeout.Set(PIDSCANNER_TIMEOUT_IN_MS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cChannel *IptvChannel = Channels.GetByChannelID(channel.GetChannelID());
|
cChannel *IptvChannel = Channels.GetByChannelID(channelId);
|
||||||
if (IptvChannel) {
|
if (IptvChannel) {
|
||||||
int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
|
int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
|
||||||
int Atypes[MAXAPIDS + 1] = { 0 };
|
int Atypes[MAXAPIDS + 1] = { 0 };
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
class cPidScanner {
|
class cPidScanner {
|
||||||
private:
|
private:
|
||||||
cTimeMs timeout;
|
cTimeMs timeout;
|
||||||
cChannel channel;
|
tChannelID channelId;
|
||||||
bool process;
|
bool process;
|
||||||
int Vpid;
|
int Vpid;
|
||||||
int Apid;
|
int Apid;
|
||||||
@ -24,7 +24,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
cPidScanner(void);
|
cPidScanner(void);
|
||||||
~cPidScanner();
|
~cPidScanner();
|
||||||
void SetChannel(const cChannel *Channel);
|
void SetChannel(const tChannelID &ChannelId);
|
||||||
void Process(const uint8_t* buf);
|
void Process(const uint8_t* buf);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
37
sidscanner.c
37
sidscanner.c
@ -11,35 +11,34 @@
|
|||||||
#include "sidscanner.h"
|
#include "sidscanner.h"
|
||||||
|
|
||||||
cSidScanner::cSidScanner(void)
|
cSidScanner::cSidScanner(void)
|
||||||
|
: channelId(tChannelID::InvalidID),
|
||||||
|
sidFound(false),
|
||||||
|
nidFound(false),
|
||||||
|
tidFound(false)
|
||||||
{
|
{
|
||||||
debug("cSidScanner::cSidScanner()\n");
|
debug("cSidScanner::cSidScanner()\n");
|
||||||
channel = cChannel();
|
|
||||||
sidFound = false;
|
|
||||||
nidFound = false;
|
|
||||||
tidFound = false;
|
|
||||||
Set(0x00, 0x00); // PAT
|
Set(0x00, 0x00); // PAT
|
||||||
Set(0x10, 0x40); // NIT
|
Set(0x10, 0x40); // NIT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cSidScanner::~cSidScanner()
|
||||||
|
{
|
||||||
|
debug("cSidScanner::~cSidScanner()\n");
|
||||||
|
}
|
||||||
|
|
||||||
void cSidScanner::SetStatus(bool On)
|
void cSidScanner::SetStatus(bool On)
|
||||||
{
|
{
|
||||||
debug("cSidScanner::SetStatus(): %d\n", On);
|
debug("cSidScanner::SetStatus(): %d\n", On);
|
||||||
cFilter::SetStatus(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;
|
sidFound = false;
|
||||||
nidFound = false;
|
nidFound = false;
|
||||||
tidFound = 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)
|
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;
|
int newSid = -1, newNid = -1, newTid = -1;
|
||||||
|
|
||||||
//debug("cSidScanner::Process()\n");
|
//debug("cSidScanner::Process()\n");
|
||||||
if (channel.GetChannelID().Valid()) {
|
if (channelId.Valid()) {
|
||||||
if ((Pid == 0x00) && (Tid == 0x00)) {
|
if ((Pid == 0x00) && (Tid == 0x00)) {
|
||||||
debug("cSidScanner::Process(): Pid=%d Tid=%02X\n", Pid, Tid);
|
debug("cSidScanner::Process(): Pid=%d Tid=%02X\n", Pid, Tid);
|
||||||
SI::PAT pat(Data, false);
|
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;
|
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 (assoc.getServiceId() != channel.Sid()) {
|
if (assoc.getServiceId() != channelId.Sid()) {
|
||||||
debug("cSidScanner::Process(): Sid=%d\n", assoc.getServiceId());
|
debug("cSidScanner::Process(): Sid=%d\n", assoc.getServiceId());
|
||||||
newSid = 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;
|
return;
|
||||||
SI::NIT::TransportStream ts;
|
SI::NIT::TransportStream ts;
|
||||||
for (SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it); ) {
|
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());
|
debug("cSidScanner::Process(): TSid=%d\n", ts.getTransportStreamId());
|
||||||
newTid = ts.getTransportStreamId();
|
newTid = ts.getTransportStreamId();
|
||||||
}
|
}
|
||||||
tidFound = true;
|
tidFound = true;
|
||||||
break; // default to the first one
|
break; // default to the first one
|
||||||
}
|
}
|
||||||
if (nit.getNetworkId() != channel.Nid()) {
|
if (nit.getNetworkId() != channelId.Nid()) {
|
||||||
debug("cSidScanner::Process(): Nid=%d\n", ts.getTransportStreamId());
|
debug("cSidScanner::Process(): Nid=%d\n", ts.getTransportStreamId());
|
||||||
newNid = nit.getNetworkId();
|
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 ((newSid >= 0) || (newNid >= 0) || (newTid >= 0)) {
|
||||||
if (!Channels.Lock(true, 10))
|
if (!Channels.Lock(true, 10))
|
||||||
return;
|
return;
|
||||||
cChannel *IptvChannel = Channels.GetByChannelID(channel.GetChannelID());
|
cChannel *IptvChannel = Channels.GetByChannelID(channelId);
|
||||||
if (IptvChannel)
|
if (IptvChannel)
|
||||||
IptvChannel->SetId((newNid < 0) ? IptvChannel->Nid() : newNid, (newTid < 0) ? IptvChannel->Tid() : newTid,
|
IptvChannel->SetId((newNid < 0) ? IptvChannel->Nid() : newNid, (newTid < 0) ? IptvChannel->Tid() : newTid,
|
||||||
(newSid < 0) ? IptvChannel->Sid() : newSid, IptvChannel->Rid());
|
(newSid < 0) ? IptvChannel->Sid() : newSid, IptvChannel->Rid());
|
||||||
Channels.Unlock();
|
Channels.Unlock();
|
||||||
}
|
}
|
||||||
if (sidFound && nidFound && tidFound) {
|
if (sidFound && nidFound && tidFound) {
|
||||||
SetChannel(NULL);
|
SetChannel(tChannelID::InvalidID);
|
||||||
SetStatus(false);
|
SetStatus(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
class cSidScanner : public cFilter {
|
class cSidScanner : public cFilter {
|
||||||
private:
|
private:
|
||||||
cChannel channel;
|
tChannelID channelId;
|
||||||
bool sidFound;
|
bool sidFound;
|
||||||
bool nidFound;
|
bool nidFound;
|
||||||
bool tidFound;
|
bool tidFound;
|
||||||
@ -24,7 +24,8 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
cSidScanner(void);
|
cSidScanner(void);
|
||||||
void SetChannel(const cChannel *Channel);
|
~cSidScanner();
|
||||||
|
void SetChannel(const tChannelID &ChannelId);
|
||||||
void Open() { SetStatus(true); }
|
void Open() { SetStatus(true); }
|
||||||
void Close() { SetStatus(false); }
|
void Close() { SetStatus(false); }
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user