diff options
author | Lars Hanisch <dvb@flensrocker.de> | 2011-02-02 14:18:45 +0100 |
---|---|---|
committer | Lars Hanisch <dvb@flensrocker.de> | 2011-02-02 14:18:45 +0100 |
commit | c03cb92fb43baab9136bd9122d757359e0590fda (patch) | |
tree | dbd9851e29274ba4b0189f3f859c1a29d20b8a88 /patches | |
download | vdr-plugin-dynamite-c03cb92fb43baab9136bd9122d757359e0590fda.tar.gz vdr-plugin-dynamite-c03cb92fb43baab9136bd9122d757359e0590fda.tar.bz2 |
initial commit of version 0.0.5c
Diffstat (limited to 'patches')
-rw-r--r-- | patches/sc-1.0.0pre-subdevice.patch | 215 | ||||
-rw-r--r-- | patches/vdr-1.7.16-dynamite-subdevice.patch | 361 |
2 files changed, 576 insertions, 0 deletions
diff --git a/patches/sc-1.0.0pre-subdevice.patch b/patches/sc-1.0.0pre-subdevice.patch new file mode 100644 index 0000000..39ca3e5 --- /dev/null +++ b/patches/sc-1.0.0pre-subdevice.patch @@ -0,0 +1,215 @@ +diff --git a/device.c b/device.c +index fe10d5e..b29a993 100644 +--- a/device.c ++++ b/device.c +@@ -1334,6 +1334,17 @@ bool cScDeviceProbe::Probe(int Adapter, int Frontend) + // -- cScDevices --------------------------------------------------------------- + + int cScDevices::budget=0; ++int cScDevices::numScDevices = 0; ++cScDevice *cScDevices::scdevice[MAXDEVICES] = { NULL }; ++ ++cScDevice *cScDevices::GetScDevice(int CardIndex) ++{ ++ for (int n = 0; n < numScDevices; n++) { ++ if (scdevice[n] && (scdevice[n]->CardIndex() == CardIndex)) ++ return scdevice[n]; ++ } ++ return NULL; ++} + + void cScDevices::DvbName(const char *Name, int a, int f, char *buffer, int len) + { +@@ -1439,16 +1450,16 @@ void cScDevices::Startup(void) + { + if(ScSetup.ForceTransfer) + SetTransferModeForDolbyDigital(2); +- for(int n=cDevice::NumDevices(); --n>=0;) { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(n)); ++ for(int n=cScDevices::numScDevices; --n>=0;) { ++ cScDevice *dev=cScDevices::scdevice[n]; + if(dev) dev->LateInit(); + } + } + + void cScDevices::Shutdown(void) + { +- for(int n=cDevice::NumDevices(); --n>=0;) { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(n)); ++ for(int n=cScDevices::numScDevices; --n>=0;) { ++ cScDevice *dev=cScDevices::scdevice[n]; + if(dev) dev->EarlyShutdown(); + } + } +@@ -1490,19 +1501,36 @@ cScDevice::cScDevice(int Adapter, int Frontend, int cafd) + :cDvbDevice(Adapter) + #endif + { ++ lateInit = false; + #ifndef SASC + decsa=0; tsBuffer=0; cam=0; fullts=false; + ciadapter=0; hwciadapter=0; + fd_ca=cafd; fd_ca2=dup(fd_ca); fd_dvr=-1; + softcsa=(fd_ca<0); ++#ifdef __DYNAMIC_DEVICE_PROBE ++ if (parentDevice) ++ LateInit(); ++#endif + #else + softcsa=fullts=false; + cam=new cCam(this,Adapter); + #endif // !SASC ++ index = 0; ++ while ((index < cScDevices::numScDevices) && (index < MAXDEVICES) && cScDevices::scdevice[index]) ++ index++; ++ if (index < MAXDEVICES) { ++ cScDevices::scdevice[index] = this; ++ if (index == cScDevices::numScDevices) ++ cScDevices::numScDevices++; ++ } ++ else ++ esyslog("too many sc-devices!"); + } + + cScDevice::~cScDevice() + { ++ if ((index >= 0) && (index < MAXDEVICES) && (cScDevices::scdevice[index] == this)) ++ cScDevices::scdevice[index] = NULL; + #ifndef SASC + DetachAllReceivers(); + Cancel(3); +@@ -1528,6 +1556,8 @@ void cScDevice::EarlyShutdown(void) + + void cScDevice::LateInit(void) + { ++ if (lateInit) return; ++ lateInit = true; + int n=CardIndex(); + if(DeviceNumber()!=n) + PRINTF(L_GEN_ERROR,"CardIndex - DeviceNumber mismatch! Put SC plugin first on VDR commandline!"); +@@ -1538,10 +1568,16 @@ void cScDevice::LateInit(void) + PRINTF(L_GEN_INFO,"Budget mode forced on card %d",n); + softcsa=true; + } +- ++#ifdef __DYNAMIC_DEVICE_PROBE ++ cDevice *cidev = parentDevice ? parentDevice : this; ++ if(fd_ca2>=0) hwciadapter=cDvbCiAdapter::CreateCiAdapter(cidev,fd_ca2); ++ cam=new cCam(this,n); ++ ciadapter=new cScCiAdapter(cidev,n,cam); ++#else + if(fd_ca2>=0) hwciadapter=cDvbCiAdapter::CreateCiAdapter(this,fd_ca2); + cam=new cCam(this,n); + ciadapter=new cScCiAdapter(this,n,cam); ++#endif + if(softcsa) { + decsa=new cDeCSA(n); + if(IsPrimaryDevice() && HasDecoder()) { +diff --git a/device.h b/device.h +index 5ad83f9..454d6ea 100644 +--- a/device.h ++++ b/device.h +@@ -88,6 +88,8 @@ public: + + // ---------------------------------------------------------------- + ++class cScDevice; ++ + class cScDevices : public cDvbDevice { + private: + static int budget; +@@ -106,6 +108,10 @@ public: + static bool ForceBudget(int n); + static void DvbName(const char *Name, int a, int f, char *buffer, int len); + static int DvbOpen(const char *Name, int a, int f, int Mode, bool ReportError=false); ++ ++ static int numScDevices; ++ static cScDevice *scdevice[MAXDEVICES]; ++ static cScDevice *GetScDevice(int CardIndex); + }; + + // ---------------------------------------------------------------- +@@ -123,6 +129,8 @@ private: + bool softcsa, fullts; + cMutex cafdMutex; + cTimeMs lastDump; ++ int index; ++ bool lateInit; + // + #ifndef SASC + void LateInit(void); +diff --git a/sc.c b/sc.c +index 82960bf..9f01217 100644 +--- a/sc.c ++++ b/sc.c +@@ -1009,7 +1009,7 @@ void cSoftCAM::Shutdown(void) + + char *cSoftCAM::CurrKeyStr(int CardNum, int num) + { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(CardNum)); ++ cScDevice *dev=cScDevices::GetScDevice(CardNum); + char *str=0; + if(dev) { + if(dev->Cam()) str=dev->Cam()->CurrentKeyStr(num); +@@ -1020,8 +1020,8 @@ char *cSoftCAM::CurrKeyStr(int CardNum, int num) + + bool cSoftCAM::Active(bool log) + { +- for(int n=cDevice::NumDevices(); --n>=0;) { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(n)); ++ for(int n=cScDevices::numScDevices; --n>=0;) { ++ cScDevice *dev=cScDevices::scdevice[n]; + if(dev && dev->Cam() && dev->Cam()->Active(log)) return true; + } + return false; +@@ -1029,33 +1029,33 @@ bool cSoftCAM::Active(bool log) + + void cSoftCAM::SetLogStatus(int CardNum, const cEcmInfo *ecm, bool on) + { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(CardNum)); ++ cScDevice *dev=cScDevices::GetScDevice(CardNum); + if(dev && dev->Cam()) dev->Cam()->LogEcmStatus(ecm,on); + } + + void cSoftCAM::AddHook(int CardNum, cLogHook *hook) + { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(CardNum)); ++ cScDevice *dev=cScDevices::GetScDevice(CardNum); + if(dev && dev->Cam()) dev->Cam()->AddHook(hook); + } + + bool cSoftCAM::TriggerHook(int CardNum, int id) + { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(CardNum)); ++ cScDevice *dev=cScDevices::GetScDevice(CardNum); + return dev && dev->Cam() && dev->Cam()->TriggerHook(id); + } + + void cSoftCAM::CaidsChanged(void) + { +- for(int n=cDevice::NumDevices(); --n>=0;) { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(n)); ++ for(int n=cScDevices::numScDevices; --n>=0;) { ++ cScDevice *dev=cScDevices::scdevice[n]; + if(dev) dev->CaidsChanged(); + } + } + + int cSoftCAM::FilterHandle(int CardNum) + { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(CardNum)); ++ cScDevice *dev=cScDevices::GetScDevice(CardNum); + return dev ? dev->FilterHandle() : -1; + } + +@@ -1086,8 +1086,8 @@ void cScHousekeeper::Action(void) + while(Running()) { + if(++c==20) { + c=0; +- for(int n=cDevice::NumDevices(); --n>=0;) { +- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(n)); ++ for(int n=cScDevices::numScDevices; --n>=0;) { ++ cScDevice *dev=cScDevices::scdevice[n]; + if(dev && dev->Cam()) dev->Cam()->HouseKeeping(); + } + } diff --git a/patches/vdr-1.7.16-dynamite-subdevice.patch b/patches/vdr-1.7.16-dynamite-subdevice.patch new file mode 100644 index 0000000..f0ee935 --- /dev/null +++ b/patches/vdr-1.7.16-dynamite-subdevice.patch @@ -0,0 +1,361 @@ +diff --git a/device.c b/device.c +index 681049b..aaee92f 100644 +--- a/device.c ++++ b/device.c +@@ -72,12 +72,18 @@ cDevice *cDevice::device[MAXDEVICES] = { NULL }; + cDevice *cDevice::primaryDevice = NULL; + cDevice *cDevice::avoidDevice = NULL; + cList<cDeviceHook> cDevice::deviceHooks; ++cDevice *cDevice::nextParentDevice = NULL; + +-cDevice::cDevice(void) ++cDevice::cDevice(cDevice *ParentDevice) + :patPmtParser(true) ++,parentDevice(ParentDevice) ++,subDevice(NULL) + { ++ if (!ParentDevice) ++ parentDevice = nextParentDevice; ++ cDevice::nextParentDevice = NULL; + cardIndex = nextCardIndex++; +- dsyslog("new device number %d", CardIndex() + 1); ++ dsyslog("new %sdevice number %d", parentDevice ? "sub-" : "", CardIndex() + 1); + + SetDescription("receiver on device %d", CardIndex() + 1); + +@@ -108,10 +114,14 @@ cDevice::cDevice(void) + for (int i = 0; i < MAXRECEIVERS; i++) + receiver[i] = NULL; + +- if (numDevices < MAXDEVICES) +- device[numDevices++] = this; ++ if (!parentDevice) { ++ if (numDevices < MAXDEVICES) ++ device[numDevices++] = this; ++ else ++ esyslog("ERROR: too many devices or \"dynamite\"-unpatched device creator!"); ++ } + else +- esyslog("ERROR: too many devices!"); ++ parentDevice->subDevice = this; + } + + cDevice::~cDevice() +@@ -120,6 +130,8 @@ cDevice::~cDevice() + DetachAllReceivers(); + delete liveSubtitle; + delete dvbSubtitleConverter; ++ if (parentDevice && (parentDevice->subDevice == this)) ++ parentDevice->subDevice = NULL; + } + + bool cDevice::WaitForAllDevicesReady(int Timeout) +@@ -158,6 +170,8 @@ int cDevice::NextCardIndex(int n) + + int cDevice::DeviceNumber(void) const + { ++ if (parentDevice) ++ return parentDevice->DeviceNumber(); + for (int i = 0; i < numDevices; i++) { + if (device[i] == this) + return i; +@@ -328,6 +342,10 @@ bool cDevice::HasCi(void) + + void cDevice::SetCamSlot(cCamSlot *CamSlot) + { ++ if (parentDevice) { ++ parentDevice->SetCamSlot(CamSlot); ++ return; ++ } + camSlot = CamSlot; + } + +@@ -531,6 +549,10 @@ bool cDevice::SetPid(cPidHandle *Handle, int Type, bool On) + + void cDevice::StartSectionHandler(void) + { ++ if (parentDevice) { ++ parentDevice->StartSectionHandler(); ++ return; ++ } + if (!sectionHandler) { + sectionHandler = new cSectionHandler(this); + AttachFilter(eitFilter = new cEitFilter); +@@ -542,6 +564,10 @@ void cDevice::StartSectionHandler(void) + + void cDevice::StopSectionHandler(void) + { ++ if (parentDevice) { ++ parentDevice->StopSectionHandler(); ++ return; ++ } + if (sectionHandler) { + delete nitFilter; + delete sdtFilter; +@@ -568,12 +594,20 @@ void cDevice::CloseFilter(int Handle) + + void cDevice::AttachFilter(cFilter *Filter) + { ++ if (parentDevice) { ++ parentDevice->AttachFilter(Filter); ++ return; ++ } + if (sectionHandler) + sectionHandler->Attach(Filter); + } + + void cDevice::Detach(cFilter *Filter) + { ++ if (parentDevice) { ++ parentDevice->Detach(Filter); ++ return; ++ } + if (sectionHandler) + sectionHandler->Detach(Filter); + } +@@ -1690,3 +1724,25 @@ uchar *cTSBuffer::Get(void) + } + return NULL; + } ++ ++// --- cDynamicDeviceProbe ------------------------------------------------------- ++ ++cList<cDynamicDeviceProbe> DynamicDeviceProbes; ++ ++cList<cDynamicDeviceProbe::cDynamicDeviceProbeItem> cDynamicDeviceProbe::commandQueue; ++ ++void cDynamicDeviceProbe::QueueDynamicDeviceCommand(eDynamicDeviceProbeCommand Cmd, const char *DevPath) ++{ ++ if (DevPath) ++ commandQueue.Add(new cDynamicDeviceProbeItem(Cmd, new cString(DevPath))); ++} ++ ++cDynamicDeviceProbe::cDynamicDeviceProbe(void) ++{ ++ DynamicDeviceProbes.Add(this); ++} ++ ++cDynamicDeviceProbe::~cDynamicDeviceProbe() ++{ ++ DynamicDeviceProbes.Del(this, false); ++} +diff --git a/device.h b/device.h +index cb3bc2c..0b6634b 100644 +--- a/device.h ++++ b/device.h +@@ -163,7 +163,6 @@ private: + static int nextCardIndex; + int cardIndex; + protected: +- cDevice(void); + virtual ~cDevice(); + virtual bool Ready(void); + ///< Returns true if this device is ready. Devices with conditional +@@ -191,8 +190,6 @@ protected: + ///< base class. + public: + bool IsPrimaryDevice(void) const { return this == primaryDevice; } +- int CardIndex(void) const { return cardIndex; } +- ///< Returns the card index of this device (0 ... MAXDEVICES - 1). + int DeviceNumber(void) const; + ///< Returns the number of this device (0 ... numDevices). + virtual bool HasDecoder(void) const; +@@ -365,9 +362,6 @@ public: + ///< Returns true if this device has a Common Interface. + void SetCamSlot(cCamSlot *CamSlot); + ///< Sets the given CamSlot to be used with this device. +- cCamSlot *CamSlot(void) const { return camSlot; } +- ///< Returns the CAM slot that is currently used with this device, +- ///< or NULL if no CAM slot is in use. + + // Image Grab facilities + +@@ -524,9 +518,6 @@ private: + cTsToPes tsToPesSubtitle; + bool isPlayingVideo; + protected: +- const cPatPmtParser *PatPmtParser(void) const { return &patPmtParser; } +- ///< Returns a pointer to the patPmtParser, so that a derived device +- ///< can use the stream information from it. + virtual bool CanReplay(void) const; + ///< Returns true if this device can currently start a replay session. + virtual bool SetPlayMode(ePlayMode PlayMode); +@@ -712,6 +703,30 @@ public: + ///< Detaches all receivers from this device for this pid. + void DetachAllReceivers(void); + ///< Detaches all receivers from this device. ++ ++// --- dynamite subdevice patch start --- ++ friend class cDynamicDevice; ++private: ++ static cDevice *nextParentDevice; ++ ///< Holds the parent device for the next subdevice ++ ///< so the dynamite-plugin can work with unpatched plugins ++protected: ++ cDevice *parentDevice; ++ cDevice *subDevice; ++ cDevice(cDevice *ParentDevice = NULL); ++ const cPatPmtParser *PatPmtParser(void) const { if (parentDevice) return parentDevice->PatPmtParser(); return &patPmtParser; } ++ ///< Returns a pointer to the patPmtParser, so that a derived device ++ ///< can use the stream information from it. ++public: ++ int CardIndex(void) const { if (parentDevice) return parentDevice->cardIndex; return cardIndex; } ++ ///< Returns the card index of this device (0 ... MAXDEVICES - 1). ++ cCamSlot *CamSlot(void) const { if (parentDevice) return parentDevice->CamSlot(); return camSlot; } ++ ///< Returns the CAM slot that is currently used with this device, ++ ///< or NULL if no CAM slot is in use. ++ bool IsSubDevice(void) const { return (parentDevice != NULL); } ++ bool HasSubDevice(void) const { return (subDevice != NULL); } ++ cDevice *SubDevice(void) const { return subDevice; } ++ // --- dynamite subdevice patch end --- + }; + + /// Derived cDevice classes that can receive channels will have to provide +@@ -735,4 +750,47 @@ public: + uchar *Get(void); + }; + ++/// A plugin that want to create devices handled by the dynamite-plugin needs to create ++/// a cDynamicDeviceProbe derived object on the heap in order to have its Probe() ++/// function called, where it can actually create the appropriate device. ++/// The cDynamicDeviceProbe object must be created in the plugin's constructor, ++/// and deleted in its destructor. ++/// The "DevPath" hasn't to be a physical device or a path in the filesystem. ++/// It can be any string a plugin may react on. ++ ++#define __DYNAMIC_DEVICE_PROBE ++ ++enum eDynamicDeviceProbeCommand { ddpcAttach, ddpcDetach }; ++ ++class cDynamicDeviceProbe : public cListObject { ++ friend class cDynamicDevice; ++private: ++ class cDynamicDeviceProbeItem : public cListObject { ++ public: ++ eDynamicDeviceProbeCommand cmd; ++ cString *devpath; ++ cDynamicDeviceProbeItem(eDynamicDeviceProbeCommand Cmd, cString *DevPath):cmd(Cmd),devpath(DevPath) {} ++ virtual ~cDynamicDeviceProbeItem() { if (devpath) delete devpath; } ++ }; ++ static cList<cDynamicDeviceProbeItem> commandQueue; ++ ///< A list where all attach/detach commands are queued ++ ///< so they can be processed in the MainThreadHook of ++ ///< the dynamite plugin. ++public: ++ static void QueueDynamicDeviceCommand(eDynamicDeviceProbeCommand Cmd, const char *DevPath); ++ ///< Plugins which support cDynamicDeviceProbe must use this function ++ ///< to queue the devices they normally create in their Initialize method. ++ ///< These devices are created as subdevices in the Start-method of the dynamite-plugin. ++ cDynamicDeviceProbe(void); ++ virtual ~cDynamicDeviceProbe(); ++ virtual cDevice *Attach(cDevice *ParentDevice, const char *DevPath) = 0; ++ ///< Probes for a device at the given device-path like /dev/dvb/adapter0/frontend0 ++ ///< or /dev/video0 etc. and creates the appropriate ++ ///< object derived from cDevice if applicable. ++ ///< Returns the device that has been created or NULL if not. ++ ///< The dynamite-plugin will delete the device if it is detached. ++ }; ++ ++extern cList<cDynamicDeviceProbe> DynamicDeviceProbes; ++ + #endif //__DEVICE_H +diff --git a/dvbci.c b/dvbci.c +index 5289bbd..ea54bdb 100644 +--- a/dvbci.c ++++ b/dvbci.c +@@ -41,6 +41,8 @@ cDvbCiAdapter::cDvbCiAdapter(cDevice *Device, int Fd) + cDvbCiAdapter::~cDvbCiAdapter() + { + Cancel(3); ++ if (device->IsSubDevice() || device->HasSubDevice()) ++ close(fd); + } + + int cDvbCiAdapter::Read(uint8_t *Buffer, int MaxLength) +diff --git a/dvbdevice.c b/dvbdevice.c +index f32b350..df2e679 100644 +--- a/dvbdevice.c ++++ b/dvbdevice.c +@@ -259,6 +259,7 @@ private: + int device; + int fd_frontend; + int adapter, frontend; ++ cDvbDevice *dvbdevice; + int tuneTimeout; + int lockTimeout; + time_t lastTimeoutReport; +@@ -273,7 +274,7 @@ private: + bool SetFrontend(void); + virtual void Action(void); + public: +- cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType); ++ cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType, cDvbDevice *Dvbdevice); + virtual ~cDvbTuner(); + const cChannel *GetTransponder(void) const { return &channel; } + bool IsTunedTo(const cChannel *Channel) const; +@@ -281,13 +282,14 @@ public: + bool Locked(int TimeoutMs = 0); + }; + +-cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType) ++cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType, cDvbDevice *Dvbdevice) + { + device = Device; + fd_frontend = Fd_Frontend; + adapter = Adapter; + frontend = Frontend; + frontendType = FrontendType; ++ dvbdevice = Dvbdevice; + tuneTimeout = 0; + lockTimeout = 0; + lastTimeoutReport = 0; +@@ -305,6 +307,8 @@ cDvbTuner::~cDvbTuner() + newSet.Broadcast(); + locked.Broadcast(); + Cancel(3); ++ if (dvbdevice && dvbdevice->IsSubDevice()) ++ close(fd_frontend); + } + + bool cDvbTuner::IsTunedTo(const cChannel *Channel) const +@@ -661,7 +665,8 @@ const char *DeliverySystems[] = { + NULL + }; + +-cDvbDevice::cDvbDevice(int Adapter, int Frontend) ++cDvbDevice::cDvbDevice(int Adapter, int Frontend, cDevice *ParentDevice) ++:cDevice(ParentDevice) + { + adapter = Adapter; + frontend = Frontend; +@@ -678,7 +683,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend) + + fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR); + if (fd_ca >= 0) +- ciAdapter = cDvbCiAdapter::CreateCiAdapter(this, fd_ca); ++ ciAdapter = cDvbCiAdapter::CreateCiAdapter(parentDevice ? parentDevice : this, fd_ca); + + // The DVR device (will be opened and closed as needed): + +@@ -718,7 +723,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend) + else + p = (char *)"unknown modulations"; + isyslog("frontend %d/%d provides %s with %s (\"%s\")", adapter, frontend, DeliverySystems[frontendType], p, frontendInfo.name); +- dvbTuner = new cDvbTuner(CardIndex() + 1, fd_frontend, adapter, frontend, frontendType); ++ dvbTuner = new cDvbTuner(CardIndex() + 1, fd_frontend, adapter, frontend, frontendType, this); + } + } + else +diff --git a/dvbdevice.h b/dvbdevice.h +index ff606fd..0ac3a24 100644 +--- a/dvbdevice.h ++++ b/dvbdevice.h +@@ -123,7 +123,7 @@ private: + fe_delivery_system frontendType; + int fd_dvr, fd_ca; + public: +- cDvbDevice(int Adapter, int Frontend); ++ cDvbDevice(int Adapter, int Frontend, cDevice *ParentDevice = NULL); + virtual ~cDvbDevice(); + virtual bool Ready(void); + |