diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2004-01-04 12:30:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2004-01-04 12:30:00 +0100 |
commit | 8976ebcec5ca1ac03c54209b7cc12e9d14915c6b (patch) | |
tree | 8562202f489ee585c1252b2cb4a9e61b3e200efe /eitscan.c | |
parent | 3a1058fe1fca6d10cea42786aa54abf3d0bd0b94 (diff) | |
download | vdr-8976ebcec5ca1ac03c54209b7cc12e9d14915c6b.tar.gz vdr-8976ebcec5ca1ac03c54209b7cc12e9d14915c6b.tar.bz2 |
Implemented automatic PID switching and channel detection
Diffstat (limited to 'eitscan.c')
-rw-r--r-- | eitscan.c | 144 |
1 files changed, 104 insertions, 40 deletions
@@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: eitscan.c 1.14 2003/09/06 13:06:13 kls Exp $ + * $Id: eitscan.c 1.15 2004/01/04 12:28:00 kls Exp $ */ #include "eitscan.h" @@ -12,6 +12,68 @@ #include "channels.h" #include "dvbdevice.h" +// --- cScanData ------------------------------------------------------------- + +class cScanData : public cListObject { +private: + int source; + int transponder; +public: + cScanData(int Source, int Transponder); + virtual bool operator< (const cListObject &ListObject); + int Source(void) { return source; } + int Transponder(void) { return transponder; } + cChannel *GetChannel(void); + }; + +cScanData::cScanData(int Source, int Transponder) +{ + source = Source; + transponder = Transponder; +} + +bool cScanData::operator< (const cListObject &ListObject) +{ + cScanData *sd = (cScanData *)&ListObject; + return source < sd->source || source == sd->source && transponder < sd->transponder; +} + +//XXX this might be done differently later... +cChannel *cScanData::GetChannel(void) +{ + for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { + if (!Channel->GroupSep() && Channel->Source() == source && ISTRANSPONDER(Channel->Transponder(), transponder)) + return Channel; + } + return NULL; +} + +// --- cScanList ------------------------------------------------------------- + +class cScanList : public cList<cScanData> { +public: + cScanList(void); + void AddTransponder(const cChannel *Channel); + }; + +cScanList::cScanList(void) +{ + for (cChannel *ch = Channels.First(); ch; ch = Channels.Next(ch)) + AddTransponder(ch); + Sort(); +} + +void cScanList::AddTransponder(const cChannel *Channel) +{ + for (cScanData *sd = First(); sd; sd = Next(sd)) { + if (sd->Source() == Channel->Source() && sd->Transponder() == Channel->Transponder()) + return; + } + Add(new cScanData(Channel->Source(), Channel->Transponder())); +} + +// --- cEITScanner ----------------------------------------------------------- + cEITScanner EITScanner; cEITScanner::cEITScanner(void) @@ -20,24 +82,12 @@ cEITScanner::cEITScanner(void) currentDevice = NULL; currentChannel = 0; memset(lastChannel, 0, sizeof(lastChannel)); - numTransponders = 0; - transponders = NULL; + scanList = NULL; } cEITScanner::~cEITScanner() { - free(transponders); -} - -bool cEITScanner::TransponderScanned(cChannel *Channel) -{ - for (int i = 0; i < numTransponders; i++) { - if (transponders[i] == Channel->Frequency()) - return true; - } - transponders = (int *)realloc(transponders, ++numTransponders * sizeof(int)); - transponders[numTransponders - 1] = Channel->Frequency(); - return false; + delete scanList; } void cEITScanner::Activity(void) @@ -54,37 +104,51 @@ void cEITScanner::Process(void) if (Setup.EPGScanTimeout && Channels.MaxNumber() > 1) { time_t now = time(NULL); if (now - lastScan > ScanTimeout && now - lastActivity > ActivityTimeout) { - for (int i = 0; i < cDevice::NumDevices(); i++) { - cDevice *Device = cDevice::GetDevice(i); - if (Device && Device->CardIndex() < MAXDVBDEVICES) { - if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) { - if (!(Device->Receiving(true) || Device->Replaying())) { - for (;;) { - cChannel *Channel = Channels.GetByNumber(lastChannel[Device->DeviceNumber()] + 1, 1); - if (Channel) { - lastChannel[Device->DeviceNumber()] = Channel->Number(); - if (Channel->Sid() && Device->ProvidesChannel(Channel) && !TransponderScanned(Channel)) { - if (Device == cDevice::PrimaryDevice() && !currentChannel) { - currentChannel = Device->CurrentChannel(); + if (Channels.Lock(false, 10)) { + if (!scanList) + scanList = new cScanList(); + for (bool AnyDeviceSwitched = false; !AnyDeviceSwitched; ) { + cScanData *ScanData = NULL; + for (int i = 0; i < cDevice::NumDevices(); i++) { + cDevice *Device = cDevice::GetDevice(i); + if (Device) { + if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) { + if (!(Device->Receiving(true) || Device->Replaying())) { + if (!ScanData) + ScanData = scanList->First(); + if (ScanData) { + cChannel *Channel = ScanData->GetChannel(); + //XXX if (Device->ProvidesTransponder(Channel)) { + if ((!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= 0x0100) && Device->ProvidesTransponder(Channel)) { //XXX temporary for the 'sky' plugin + if (Device == cDevice::PrimaryDevice() && !currentChannel) + currentChannel = Device->CurrentChannel(); + currentDevice = Device;//XXX see also dvbdevice.c!!! + Device->SwitchChannel(Channel, false); + currentDevice = NULL; + scanList->Del(ScanData); + ScanData = NULL; + AnyDeviceSwitched = true; } - currentDevice = Device; - Device->SwitchChannel(Channel, false); - currentDevice = NULL; - break; } - } - else { - if (lastChannel[Device->DeviceNumber()]) - numTransponders = 0; - lastChannel[Device->DeviceNumber()] = 0; - break; + else + break; } } - } + } + } + if (ScanData && !AnyDeviceSwitched) { + scanList->Del(ScanData); + ScanData = NULL; + } + if (!scanList->Count()) { + delete scanList; + scanList = NULL; + break; } } - } - lastScan = time(NULL); + Channels.Unlock(); + lastScan = time(NULL); + } } } } |