Added support for DVB cards with multiple fontends

This commit is contained in:
Klaus Schmidinger 2010-01-04 14:16:11 +01:00
parent 4743fc349c
commit af494287cf
6 changed files with 104 additions and 77 deletions

View File

@ -6197,7 +6197,7 @@ Video Disk Recorder Revision History
- Fixed the default value for "Pause key handling" in the MANUAL (reported by - Fixed the default value for "Pause key handling" in the MANUAL (reported by
Diego Pierotto). Diego Pierotto).
2010-01-03: Version 1.7.11 2010-01-04: Version 1.7.11
- Fixed resetting the file size when regenerating the index file. - Fixed resetting the file size when regenerating the index file.
- The new function cDevice::PatPmtParser() can be used in derived devices to access - The new function cDevice::PatPmtParser() can be used in derived devices to access
@ -6270,3 +6270,6 @@ Video Disk Recorder Revision History
- After a CLRE command, no further EPG processing is now done for 10 seconds, - After a CLRE command, no further EPG processing is now done for 10 seconds,
so that data sent with subsequent PUTE commands doesn't interfere with data so that data sent with subsequent PUTE commands doesn't interfere with data
from the broadcasters (suggested by Helmut Auer). from the broadcasters (suggested by Helmut Auer).
- Added support for DVB cards with multiple fontends. Note that this only
works for DVB cards where each frontend can be used independently of all
the others on the same adapter.

View File

@ -5,7 +5,8 @@ VDR Plugin 'dvbsddevice' Revision History
- Initial revision. - Initial revision.
2010-01-01: Version 0.0.2 2010-01-04: Version 0.0.2
- Calling the MakePrimaryDevice() function of the base class to allow - Calling the MakePrimaryDevice() function of the base class to allow
the cDevice to stop displaying subtitles. the cDevice to stop displaying subtitles.
- Added support for DVB cards with multiple fontends.

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: dvbsdffdevice.c 2.24 2010/01/01 15:03:02 kls Exp $ * $Id: dvbsdffdevice.c 2.25 2010/01/04 12:56:56 kls Exp $
*/ */
#include "dvbsdffdevice.h" #include "dvbsdffdevice.h"
@ -23,8 +23,8 @@
int cDvbSdFfDevice::devVideoOffset = -1; int cDvbSdFfDevice::devVideoOffset = -1;
cDvbSdFfDevice::cDvbSdFfDevice(int n) cDvbSdFfDevice::cDvbSdFfDevice(int Adapter, int Frontend)
:cDvbDevice(n) :cDvbDevice(Adapter, Frontend)
{ {
spuDecoder = NULL; spuDecoder = NULL;
digitalAudio = false; digitalAudio = false;
@ -32,10 +32,10 @@ cDvbSdFfDevice::cDvbSdFfDevice(int n)
// Devices that are only present on cards with decoders: // Devices that are only present on cards with decoders:
fd_osd = DvbOpen(DEV_DVB_OSD, n, O_RDWR); fd_osd = DvbOpen(DEV_DVB_OSD, adapter, frontend, O_RDWR);
fd_video = DvbOpen(DEV_DVB_VIDEO, n, O_RDWR | O_NONBLOCK); fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
fd_audio = DvbOpen(DEV_DVB_AUDIO, n, O_RDWR | O_NONBLOCK); fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
fd_stc = DvbOpen(DEV_DVB_DEMUX, n, O_RDWR); fd_stc = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR);
// The offset of the /dev/video devices: // The offset of the /dev/video devices:
@ -317,7 +317,7 @@ bool cDvbSdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On)
memset(&pesFilterParams, 0, sizeof(pesFilterParams)); memset(&pesFilterParams, 0, sizeof(pesFilterParams));
if (On) { if (On) {
if (Handle->handle < 0) { if (Handle->handle < 0) {
Handle->handle = DvbOpen(DEV_DVB_DEMUX, CardIndex(), O_RDWR | O_NONBLOCK, true); Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true);
if (Handle->handle < 0) { if (Handle->handle < 0) {
LOG_ERROR; LOG_ERROR;
return false; return false;
@ -507,8 +507,8 @@ bool cDvbSdFfDevice::SetPlayMode(ePlayMode PlayMode)
{ {
if (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) { if (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) {
// reopen the devices // reopen the devices
fd_video = DvbOpen(DEV_DVB_VIDEO, CardIndex(), O_RDWR | O_NONBLOCK); fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
fd_audio = DvbOpen(DEV_DVB_AUDIO, CardIndex(), O_RDWR | O_NONBLOCK); fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
SetVideoFormat(Setup.VideoFormat); SetVideoFormat(Setup.VideoFormat);
} }
@ -756,7 +756,7 @@ int cDvbSdFfDevice::PlayTsAudio(const uchar *Data, int Length)
// --- cDvbSdFfDeviceProbe --------------------------------------------------- // --- cDvbSdFfDeviceProbe ---------------------------------------------------
bool cDvbSdFfDeviceProbe::Probe(int Adapter) bool cDvbSdFfDeviceProbe::Probe(int Adapter, int Frontend)
{ {
static uint32_t SubsystemIds[] = { static uint32_t SubsystemIds[] = {
0x110A0000, // Fujitsu Siemens DVB-C 0x110A0000, // Fujitsu Siemens DVB-C
@ -776,13 +776,13 @@ bool cDvbSdFfDeviceProbe::Probe(int Adapter)
cReadLine ReadLine; cReadLine ReadLine;
FILE *f = NULL; FILE *f = NULL;
uint32_t SubsystemId = 0; uint32_t SubsystemId = 0;
FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend0/device/subsystem_vendor", Adapter); FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
if ((f = fopen(FileName, "r")) != NULL) { if ((f = fopen(FileName, "r")) != NULL) {
if (char *s = ReadLine.Read(f)) if (char *s = ReadLine.Read(f))
SubsystemId = strtoul(s, NULL, 0) << 16; SubsystemId = strtoul(s, NULL, 0) << 16;
fclose(f); fclose(f);
} }
FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend0/device/subsystem_device", Adapter); FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
if ((f = fopen(FileName, "r")) != NULL) { if ((f = fopen(FileName, "r")) != NULL) {
if (char *s = ReadLine.Read(f)) if (char *s = ReadLine.Read(f))
SubsystemId |= strtoul(s, NULL, 0); SubsystemId |= strtoul(s, NULL, 0);
@ -791,7 +791,7 @@ bool cDvbSdFfDeviceProbe::Probe(int Adapter)
for (uint32_t *sid = SubsystemIds; *sid; sid++) { for (uint32_t *sid = SubsystemIds; *sid; sid++) {
if (*sid == SubsystemId) { if (*sid == SubsystemId) {
dsyslog("creating cDvbSdFfDevice"); dsyslog("creating cDvbSdFfDevice");
new cDvbSdFfDevice(Adapter); new cDvbSdFfDevice(Adapter, Frontend);
return true; return true;
} }
} }

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: dvbsdffdevice.h 2.10 2009/12/31 15:36:56 kls Exp $ * $Id: dvbsdffdevice.h 2.11 2010/01/04 11:01:14 kls Exp $
*/ */
#ifndef __DVBSDFFDEVICE_H #ifndef __DVBSDFFDEVICE_H
@ -20,7 +20,7 @@ private:
protected: protected:
virtual void MakePrimaryDevice(bool On); virtual void MakePrimaryDevice(bool On);
public: public:
cDvbSdFfDevice(int n); cDvbSdFfDevice(int Adapter, int Frontend);
virtual ~cDvbSdFfDevice(); virtual ~cDvbSdFfDevice();
virtual bool HasDecoder(void) const; virtual bool HasDecoder(void) const;
@ -101,7 +101,7 @@ public:
class cDvbSdFfDeviceProbe : public cDvbDeviceProbe { class cDvbSdFfDeviceProbe : public cDvbDeviceProbe {
public: public:
virtual bool Probe(int Adapter); virtual bool Probe(int Adapter, int Frontend);
}; };
#endif //__DVBSDFFDEVICE_H #endif //__DVBSDFFDEVICE_H

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbdevice.c 2.23 2009/12/31 15:38:18 kls Exp $ * $Id: dvbdevice.c 2.24 2010/01/04 14:06:24 kls Exp $
*/ */
#include "dvbdevice.h" #include "dvbdevice.h"
@ -31,7 +31,7 @@ class cDvbTuner : public cThread {
private: private:
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked }; enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
int fd_frontend; int fd_frontend;
int cardIndex; int adapter, frontend;
int tuneTimeout; int tuneTimeout;
int lockTimeout; int lockTimeout;
time_t lastTimeoutReport; time_t lastTimeoutReport;
@ -46,17 +46,18 @@ private:
bool SetFrontend(void); bool SetFrontend(void);
virtual void Action(void); virtual void Action(void);
public: public:
cDvbTuner(int Fd_Frontend, int CardIndex, fe_delivery_system FrontendType); cDvbTuner(int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType);
virtual ~cDvbTuner(); virtual ~cDvbTuner();
bool IsTunedTo(const cChannel *Channel) const; bool IsTunedTo(const cChannel *Channel) const;
void Set(const cChannel *Channel); void Set(const cChannel *Channel);
bool Locked(int TimeoutMs = 0); bool Locked(int TimeoutMs = 0);
}; };
cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_delivery_system FrontendType) cDvbTuner::cDvbTuner(int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType)
{ {
fd_frontend = Fd_Frontend; fd_frontend = Fd_Frontend;
cardIndex = CardIndex; adapter = Adapter;
frontend = Frontend;
frontendType = FrontendType; frontendType = FrontendType;
tuneTimeout = 0; tuneTimeout = 0;
lockTimeout = 0; lockTimeout = 0;
@ -65,7 +66,7 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_delivery_system Frontend
tunerStatus = tsIdle; tunerStatus = tsIdle;
if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2)
CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power
SetDescription("tuner on device %d", cardIndex + 1); SetDescription("tuner on frontend %d/%d", adapter, frontend);
Start(); Start();
} }
@ -154,7 +155,7 @@ bool cDvbTuner::SetFrontend(void)
#define SETCMD(c, d) { Frontend[CmdSeq.num].cmd = (c);\ #define SETCMD(c, d) { Frontend[CmdSeq.num].cmd = (c);\
Frontend[CmdSeq.num].u.data = (d);\ Frontend[CmdSeq.num].u.data = (d);\
if (CmdSeq.num++ > MAXFRONTENDCMDS) {\ if (CmdSeq.num++ > MAXFRONTENDCMDS) {\
esyslog("ERROR: too many tuning commands on frontend %d", cardIndex);\ esyslog("ERROR: too many tuning commands on frontend %d/%d", adapter, frontend);\
return false;\ return false;\
}\ }\
} }
@ -165,7 +166,7 @@ bool cDvbTuner::SetFrontend(void)
CmdSeq.props = Frontend; CmdSeq.props = Frontend;
SETCMD(DTV_CLEAR, 0); SETCMD(DTV_CLEAR, 0);
if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) { if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
esyslog("ERROR: frontend %d: %m", cardIndex); esyslog("ERROR: frontend %d/%d: %m", adapter, frontend);
return false; return false;
} }
CmdSeq.num = 0; CmdSeq.num = 0;
@ -239,7 +240,7 @@ bool cDvbTuner::SetFrontend(void)
SETCMD(DTV_ROLLOFF, channel.RollOff()); SETCMD(DTV_ROLLOFF, channel.RollOff());
} }
else { else {
esyslog("ERROR: frontend %d doesn't provide DVB-S2", cardIndex); esyslog("ERROR: frontend %d/%d doesn't provide DVB-S2", adapter, frontend);
return false; return false;
} }
} }
@ -285,7 +286,7 @@ bool cDvbTuner::SetFrontend(void)
} }
SETCMD(DTV_TUNE, 0); SETCMD(DTV_TUNE, 0);
if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) { if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
esyslog("ERROR: frontend %d: %m", cardIndex); esyslog("ERROR: frontend %d/%d: %m", adapter, frontend);
return false; return false;
} }
return true; return true;
@ -313,7 +314,7 @@ void cDvbTuner::Action(void)
tunerStatus = tsSet; tunerStatus = tsSet;
diseqcCommands = NULL; diseqcCommands = NULL;
if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these
isyslog("frontend %d timed out while tuning to channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); isyslog("frontend %d/%d timed out while tuning to channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder());
lastTimeoutReport = time(NULL); lastTimeoutReport = time(NULL);
} }
continue; continue;
@ -322,13 +323,13 @@ void cDvbTuner::Action(void)
if (Status & FE_REINIT) { if (Status & FE_REINIT) {
tunerStatus = tsSet; tunerStatus = tsSet;
diseqcCommands = NULL; diseqcCommands = NULL;
isyslog("frontend %d was reinitialized", cardIndex); isyslog("frontend %d/%d was reinitialized", adapter, frontend);
lastTimeoutReport = 0; lastTimeoutReport = 0;
continue; continue;
} }
else if (Status & FE_HAS_LOCK) { else if (Status & FE_HAS_LOCK) {
if (LostLock) { if (LostLock) {
isyslog("frontend %d regained lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); isyslog("frontend %d/%d regained lock on channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder());
LostLock = false; LostLock = false;
} }
tunerStatus = tsLocked; tunerStatus = tsLocked;
@ -337,7 +338,7 @@ void cDvbTuner::Action(void)
} }
else if (tunerStatus == tsLocked) { else if (tunerStatus == tsLocked) {
LostLock = true; LostLock = true;
isyslog("frontend %d lost lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); isyslog("frontend %d/%d lost lock on channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder());
tunerStatus = tsTuned; tunerStatus = tsTuned;
Timer.Set(lockTimeout); Timer.Set(lockTimeout);
lastTimeoutReport = 0; lastTimeoutReport = 0;
@ -376,8 +377,10 @@ const char *DeliverySystems[] = {
NULL NULL
}; };
cDvbDevice::cDvbDevice(int n) cDvbDevice::cDvbDevice(int Adapter, int Frontend)
{ {
adapter = Adapter;
frontend = Frontend;
ciAdapter = NULL; ciAdapter = NULL;
dvbTuner = NULL; dvbTuner = NULL;
frontendType = SYS_UNDEFINED; frontendType = SYS_UNDEFINED;
@ -385,11 +388,11 @@ cDvbDevice::cDvbDevice(int n)
// Devices that are present on all card types: // Devices that are present on all card types:
int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK); int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, adapter, frontend, O_RDWR | O_NONBLOCK);
// Common Interface: // Common Interface:
fd_ca = DvbOpen(DEV_DVB_CA, n, O_RDWR); fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR);
if (fd_ca >= 0) if (fd_ca >= 0)
ciAdapter = cDvbCiAdapter::CreateCiAdapter(this, fd_ca); ciAdapter = cDvbCiAdapter::CreateCiAdapter(this, fd_ca);
@ -406,7 +409,7 @@ cDvbDevice::cDvbDevice(int n)
case FE_OFDM: frontendType = SYS_DVBT; break; case FE_OFDM: frontendType = SYS_DVBT; break;
case FE_QAM: frontendType = SYS_DVBC_ANNEX_AC; break; case FE_QAM: frontendType = SYS_DVBC_ANNEX_AC; break;
case FE_ATSC: frontendType = SYS_ATSC; break; case FE_ATSC: frontendType = SYS_ATSC; break;
default: esyslog("ERROR: unknown frontend type %d on device %d", frontendInfo.type, CardIndex() + 1); default: esyslog("ERROR: unknown frontend type %d on frontend %d/%d", frontendInfo.type, adapter, frontend);
} }
} }
else else
@ -415,12 +418,12 @@ cDvbDevice::cDvbDevice(int n)
numProvidedSystems++; numProvidedSystems++;
if (frontendType == SYS_DVBS2) if (frontendType == SYS_DVBS2)
numProvidedSystems++; numProvidedSystems++;
isyslog("device %d provides %s (\"%s\")", CardIndex() + 1, DeliverySystems[frontendType], frontendInfo.name); isyslog("frontend %d/%d provides %s (\"%s\")", adapter, frontend, DeliverySystems[frontendType], frontendInfo.name);
dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType); dvbTuner = new cDvbTuner(fd_frontend, adapter, frontend, frontendType);
} }
} }
else else
esyslog("ERROR: can't open DVB device %d", n); esyslog("ERROR: can't open DVB device %d/%d", adapter, frontend);
StartSectionHandler(); StartSectionHandler();
} }
@ -434,34 +437,27 @@ cDvbDevice::~cDvbDevice()
// caused segfaults. Besides, the program is about to terminate anyway... // caused segfaults. Besides, the program is about to terminate anyway...
} }
cString cDvbDevice::DvbName(const char *Name, int n) cString cDvbDevice::DvbName(const char *Name, int Adapter, int Frontend)
{ {
return cString::sprintf("%s%d/%s%d", DEV_DVB_ADAPTER, n, Name, 0); return cString::sprintf("%s%d/%s%d", DEV_DVB_ADAPTER, Adapter, Name, Frontend);
} }
int cDvbDevice::DvbOpen(const char *Name, int n, int Mode, bool ReportError) int cDvbDevice::DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError)
{ {
cString FileName = DvbName(Name, n); cString FileName = DvbName(Name, Adapter, Frontend);
int fd = open(FileName, Mode); int fd = open(FileName, Mode);
if (fd < 0 && ReportError) if (fd < 0 && ReportError)
LOG_ERROR_STR(*FileName); LOG_ERROR_STR(*FileName);
return fd; return fd;
} }
bool cDvbDevice::Probe(int Adapter) bool cDvbDevice::Exists(int Adapter, int Frontend)
{ {
cString FileName = DvbName(DEV_DVB_FRONTEND, Adapter); cString FileName = DvbName(DEV_DVB_FRONTEND, Adapter, Frontend);
if (access(FileName, F_OK) == 0) { if (access(FileName, F_OK) == 0) {
dsyslog("probing %s", *FileName);
int f = open(FileName, O_RDONLY); int f = open(FileName, O_RDONLY);
if (f >= 0) { if (f >= 0) {
close(f); close(f);
for (cDvbDeviceProbe *dp = DvbDeviceProbes.First(); dp; dp = DvbDeviceProbes.Next(dp)) {
if (dp->Probe(Adapter))
return true; // a plugin has created the actual device
}
dsyslog("creating cDvbDevice");
new cDvbDevice(Adapter); // it's a "budget" device
return true; return true;
} }
else if (errno != ENODEV && errno != EINVAL) else if (errno != ENODEV && errno != EINVAL)
@ -472,26 +468,49 @@ bool cDvbDevice::Probe(int Adapter)
return false; return false;
} }
bool cDvbDevice::Probe(int Adapter, int Frontend)
{
cString FileName = DvbName(DEV_DVB_FRONTEND, Adapter, Frontend);
dsyslog("probing %s", *FileName);
for (cDvbDeviceProbe *dp = DvbDeviceProbes.First(); dp; dp = DvbDeviceProbes.Next(dp)) {
if (dp->Probe(Adapter, Frontend))
return true; // a plugin has created the actual device
}
dsyslog("creating cDvbDevice");
new cDvbDevice(Adapter, Frontend); // it's a "budget" device
return true;
}
bool cDvbDevice::Initialize(void) bool cDvbDevice::Initialize(void)
{ {
int found = 0; int Checked = 0;
int i; int Found = 0;
for (i = 0; i < MAXDVBDEVICES; i++) { for (int Adapter = 0; ; Adapter++) {
if (UseDevice(NextCardIndex())) { for (int Frontend = 0; ; Frontend++) {
if (Probe(i)) if (Exists(Adapter, Frontend)) {
found++; if (Checked++ < MAXDVBDEVICES) {
else if (UseDevice(NextCardIndex())) {
break; if (Probe(Adapter, Frontend))
} Found++;
else }
NextCardIndex(1); // skips this one else
NextCardIndex(1); // skips this one
}
}
else if (Frontend == 0)
goto LastAdapter;
else
goto NextAdapter;
}
NextAdapter: ;
} }
NextCardIndex(MAXDVBDEVICES - i); // skips the rest LastAdapter:
if (found > 0) NextCardIndex(MAXDVBDEVICES - Checked); // skips the rest
isyslog("found %d video device%s", found, found > 1 ? "s" : ""); if (Found > 0)
isyslog("found %d DVB device%s", Found, Found > 1 ? "s" : "");
else else
isyslog("no DVB device found"); isyslog("no DVB device found");
return found > 0; return Found > 0;
} }
bool cDvbDevice::Ready(void) bool cDvbDevice::Ready(void)
@ -513,7 +532,7 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On)
memset(&pesFilterParams, 0, sizeof(pesFilterParams)); memset(&pesFilterParams, 0, sizeof(pesFilterParams));
if (On) { if (On) {
if (Handle->handle < 0) { if (Handle->handle < 0) {
Handle->handle = DvbOpen(DEV_DVB_DEMUX, CardIndex(), O_RDWR | O_NONBLOCK, true); Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true);
if (Handle->handle < 0) { if (Handle->handle < 0) {
LOG_ERROR; LOG_ERROR;
return false; return false;
@ -548,7 +567,7 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On)
int cDvbDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask) int cDvbDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
{ {
cString FileName = DvbName(DEV_DVB_DEMUX, CardIndex()); cString FileName = DvbName(DEV_DVB_DEMUX, adapter, frontend);
int f = open(FileName, O_RDWR | O_NONBLOCK); int f = open(FileName, O_RDWR | O_NONBLOCK);
if (f >= 0) { if (f >= 0) {
dmx_sct_filter_params sctFilterParams; dmx_sct_filter_params sctFilterParams;
@ -658,7 +677,7 @@ void cDvbDevice::SetTransferModeForDolbyDigital(int Mode)
bool cDvbDevice::OpenDvr(void) bool cDvbDevice::OpenDvr(void)
{ {
CloseDvr(); CloseDvr();
fd_dvr = DvbOpen(DEV_DVB_DVR, CardIndex(), O_RDONLY | O_NONBLOCK, true); fd_dvr = DvbOpen(DEV_DVB_DVR, adapter, frontend, O_RDONLY | O_NONBLOCK, true);
if (fd_dvr >= 0) if (fd_dvr >= 0)
tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(2), CardIndex() + 1); tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(2), CardIndex() + 1);
return fd_dvr >= 0; return fd_dvr >= 0;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbdevice.h 2.10 2009/12/31 15:38:05 kls Exp $ * $Id: dvbdevice.h 2.11 2010/01/04 14:07:12 kls Exp $
*/ */
#ifndef __DVBDEVICE_H #ifndef __DVBDEVICE_H
@ -37,23 +37,27 @@ class cDvbTuner;
class cDvbDevice : public cDevice { class cDvbDevice : public cDevice {
protected: protected:
static cString DvbName(const char *Name, int n); static cString DvbName(const char *Name, int Adapter, int Frontend);
static int DvbOpen(const char *Name, int n, int Mode, bool ReportError = false); static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError = false);
private: private:
static bool Probe(int Adapter); static bool Exists(int Adapter, int Frontend);
///< Checks whether the given adapter/frontend exists.
static bool Probe(int Adapter, int Frontend);
///< Probes for existing DVB devices. ///< Probes for existing DVB devices.
public: public:
static bool Initialize(void); static bool Initialize(void);
///< Initializes the DVB devices. ///< Initializes the DVB devices.
///< Must be called before accessing any DVB functions. ///< Must be called before accessing any DVB functions.
///< \return True if any devices are available. ///< \return True if any devices are available.
protected:
int adapter, frontend;
private: private:
dvb_frontend_info frontendInfo; dvb_frontend_info frontendInfo;
int numProvidedSystems; int numProvidedSystems;
fe_delivery_system frontendType; fe_delivery_system frontendType;
int fd_dvr, fd_ca; int fd_dvr, fd_ca;
public: public:
cDvbDevice(int n); cDvbDevice(int Adapter, int Frontend);
virtual ~cDvbDevice(); virtual ~cDvbDevice();
virtual bool Ready(void); virtual bool Ready(void);
@ -125,7 +129,7 @@ class cDvbDeviceProbe : public cListObject {
public: public:
cDvbDeviceProbe(void); cDvbDeviceProbe(void);
virtual ~cDvbDeviceProbe(); virtual ~cDvbDeviceProbe();
virtual bool Probe(int Adapter) = 0; virtual bool Probe(int Adapter, int Frontend) = 0;
///< Probes for a DVB device at the given Adapter and creates the appropriate ///< Probes for a DVB device at the given Adapter and creates the appropriate
///< object derived from cDvbDevice if applicable. ///< object derived from cDvbDevice if applicable.
///< Returns true if a device has been created. ///< Returns true if a device has been created.