diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-03-03 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-03-03 18:00:00 +0100 |
commit | a001a4bf97715d62b387d1da9fd1e48382508428 (patch) | |
tree | 122e77986a23e2eea92487322e4c943595fdecd7 /dvbapi.c | |
parent | 0bad88704ba7e0346c49bb28be28e709473d9244 (diff) | |
download | vdr-patch-lnbsharing-a001a4bf97715d62b387d1da9fd1e48382508428.tar.gz vdr-patch-lnbsharing-a001a4bf97715d62b387d1da9fd1e48382508428.tar.bz2 |
Version 1.0.0pre3vdr-1.0.0pre3
- Fixed parsing 'E' records in epg2html.pl.
- Fixed a deadlock when switching channels via Schedule/Now|Next/Switch (reported
by Martin Hammerschmid).
- Changed the meaning of the 'Ca' parameter in 'channels.conf'. Each channel can
now define which decryption method it needs in order to be accessed. The new
configuration file 'ca.conf' contains the defined values, and the default
'channels.conf' has been modifed to contain the new values for 'Premiere World'
and 'ORF'. If you use the default 'channels.conf' and have the conditional
access hardware to receive encrypted channels, please make sure you copy the
file 'ca.conf' into your /video directory (or wherever your configuration files
are located) and go into the "Setup" menu and set the CICAM values according
to your hardware setup. Currently there are two possible CICAM entries per
DVB card, so any card can implement up to two different conditional access
modes (besides the default "Free To Air" mode, which is always assumed to be
available on any DVB card).
- Updated French language texts (thanks to Jean-Claude Repetto).
Diffstat (limited to 'dvbapi.c')
-rw-r--r-- | dvbapi.c | 127 |
1 files changed, 93 insertions, 34 deletions
@@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.c 1.152 2002/02/24 12:53:51 kls Exp $ + * $Id: dvbapi.c 1.154 2002/03/03 15:43:24 kls Exp $ */ #include "dvbapi.h" @@ -1684,9 +1684,10 @@ cDvbApi::cDvbApi(int n) replayBuffer = NULL; transferBuffer = NULL; transferringFromDvbApi = NULL; - ca = 0; + ca = -1; priority = -1; cardIndex = n; + SetCaCaps(); // Devices that are only present on DVB-C or DVB-S cards: @@ -1783,37 +1784,93 @@ bool cDvbApi::SetPrimaryDvbApi(int n) return false; } +int cDvbApi::CanShift(int Ca, int Priority) +{ + // Test whether a recording on this DVB device can be shifted to another one + // in order to perform a new recording with the given Ca and Priority on this device: + int ShiftLevel = -1; // default means this device can't be shifted + if (Recording()) { + if (ProvidesCa(Ca) // this device provides the requested Ca + && (Ca != this->Ca() // the requested Ca is different from the one currently used... + || Priority > this->Priority())) { // ...or the request comes from a higher priority + cDvbApi *d = NULL; + int Provides[MAXDVBAPI]; + for (int i = 0; i < NumDvbApis; i++) { + if ((Provides[i] = dvbApi[i]->ProvidesCa(this->Ca())) != 0) { // this device is basicly able to do the job + if (dvbApi[i] != this) { // it is not _this_ device + int sl = dvbApi[i]->CanShift(this->Ca(), Priority); // this is the original Priority! + if (sl >= 0 && (ShiftLevel < 0 || sl < ShiftLevel)) { + d = dvbApi[i]; + ShiftLevel = sl; + } + } + } + } + if (ShiftLevel >= 0) + ShiftLevel++; // adds the device's own shift + } + } + else if (Priority > this->Priority()) + ShiftLevel = 0; // no shifting necessary, this device can do the job + return ShiftLevel; +} + cDvbApi *cDvbApi::GetDvbApi(int Ca, int Priority) { - cDvbApi *d = NULL, *dMinPriority = NULL; - int index = Ca - 1; - for (int i = 0; i < MAXDVBAPI; i++) { - if (dvbApi[i]) { - if (dvbApi[i]->CardIndex() == index) { // means we need exactly _this_ device + cDvbApi *d = NULL; + int Provides[MAXDVBAPI]; + // Check which devices provide Ca: + for (int i = 0; i < NumDvbApis; i++) { + if ((Provides[i] = dvbApi[i]->ProvidesCa(Ca)) != 0) { // this device is basicly able to do the job + if (Priority > dvbApi[i]->Priority() // Priority is high enough to use this device + && (!d // we don't have a device yet, or... + || dvbApi[i]->Priority() < d->Priority() // ...this one has an even lower Priority + || (dvbApi[i]->Priority() == d->Priority() // ...same Priority... + && Provides[i] < Provides[d->CardIndex()]))) // ...but this one provides fewer Ca values d = dvbApi[i]; - break; - } - else if (Ca == 0) { // means any device would be acceptable - if (!d || !dvbApi[i]->Recording() || (d->Recording() && d->Priority() > dvbApi[i]->Priority())) - d = dvbApi[i]; // this is one that is either not currently recording or has the lowest priority - if (d && d != PrimaryDvbApi && !d->Recording()) // avoids the PrimaryDvbApi if possible - break; - if (d && d->Recording() && d->Priority() < Setup.PrimaryLimit && (!dMinPriority || d->Priority() < dMinPriority->Priority())) - dMinPriority = d; // this is the one with the lowest priority below Setup.PrimaryLimit - } } } - if (d == PrimaryDvbApi) { // the PrimaryDvbApi was the only one that was free - if (Priority < Setup.PrimaryLimit) - return NULL; // not enough priority to use the PrimaryDvbApi - if (dMinPriority) // there's one that must not use the PrimaryDvbApi... - d = dMinPriority; // ...so let's kick out that one + if (!d && Ca > MAXDVBAPI) { + // We didn't find one the easy way, so now we have to try harder: + int ShiftLevel = -1; + for (int i = 0; i < NumDvbApis; i++) { + if (Provides[i]) { // this device is basicly able to do the job, but for some reason we didn't get it above + int sl = dvbApi[i]->CanShift(Ca, Priority); // asks this device to shift its job to another device + if (sl >= 0 && (ShiftLevel < 0 || sl < ShiftLevel)) { + d = dvbApi[i]; // found one that can be shifted with the fewest number of subsequent shifts + ShiftLevel = sl; + } + } + } } - return (d // we found one... - && (!d->Recording() // ...that's either not currently recording... - || d->Priority() < Priority // ...or has a lower priority... - || (!d->Ca() && Ca))) // ...or doesn't need this card - ? d : NULL; + return d; +} + +void cDvbApi::SetCaCaps(void) +{ + for (int i = 0; i < MAXCACAPS; i++) + caCaps[i] = Setup.CaCaps[CardIndex()][i]; +} + +int cDvbApi::ProvidesCa(int Ca) +{ + if (Ca == CardIndex() + 1) + return 1; // exactly _this_ card was requested + if (Ca && Ca <= MAXDVBAPI) + return 0; // a specific card was requested, but not _this_ one + int result = Ca ? 0 : 1; // by default every card can provide FTA + int others = Ca ? 1 : 0; + for (int i = 0; i < MAXCACAPS; i++) { + if (caCaps[i]) { + if (caCaps[i] == Ca) + result = 1; + else + others++; + } + else + break; + } + return result ? result + others : 0; } bool cDvbApi::Probe(const char *FileName) @@ -1854,7 +1911,7 @@ bool cDvbApi::Init(void) void cDvbApi::Cleanup(void) { - for (int i = 0; i < MAXDVBAPI; i++) { + for (int i = 0; i < NumDvbApis; i++) { delete dvbApi[i]; dvbApi[i] = NULL; } @@ -2148,6 +2205,11 @@ void cDvbApi::Flush(void) #endif } +int cDvbApi::Priority(void) +{ + return (this == PrimaryDvbApi && !Recording()) ? Setup.PrimaryLimit - 1 : priority; +} + int cDvbApi::SetModeRecord(void) { // Sets up the DVB device for recording @@ -2238,9 +2300,6 @@ bool cDvbApi::SetPids(bool ForRecording) eSetChannelResult cDvbApi::SetChannel(int ChannelNumber, int Frequency, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Dpid1, int Dpid2, int Tpid, int Ca, int Pnr) { - // Make sure the siProcessor won't access the device while switching - cThreadLock ThreadLock(siProcessor); - StopTransfer(); StopReplay(); @@ -2265,7 +2324,7 @@ eSetChannelResult cDvbApi::SetChannel(int ChannelNumber, int Frequency, char Pol // If this card can't receive this channel, we must not actually switch // the channel here, because that would irritate the driver when we // start replaying in Transfer Mode immediately after switching the channel: - bool NeedsTransferMode = (this == PrimaryDvbApi && Ca && Ca != CardIndex() + 1); + bool NeedsTransferMode = (this == PrimaryDvbApi && !ProvidesCa(Ca)); if (!NeedsTransferMode) { @@ -2507,7 +2566,7 @@ void cDvbApi::StopRecord(void) if (recordBuffer) { delete recordBuffer; recordBuffer = NULL; - ca = 0; + ca = -1; priority = -1; } } @@ -2706,7 +2765,7 @@ void cEITScanner::Process(void) time_t now = time(NULL); if (now - lastScan > ScanTimeout && now - lastActivity > ActivityTimeout) { for (int i = 0; i < MAXDVBAPI; i++) { - cDvbApi *DvbApi = cDvbApi::GetDvbApi(i + 1, MAXPRIORITY); + cDvbApi *DvbApi = cDvbApi::GetDvbApi(i + 1, MAXPRIORITY + 1); if (DvbApi) { if (DvbApi != cDvbApi::PrimaryDvbApi || (cDvbApi::NumDvbApis == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) { if (!(DvbApi->Recording() || DvbApi->Replaying() || DvbApi->Transferring())) { |