summaryrefslogtreecommitdiff
path: root/patches/vdr-1.7.16-dynamite-subdevice.patch
diff options
context:
space:
mode:
authorLars Hanisch <dvb@flensrocker.de>2011-02-02 14:18:45 +0100
committerLars Hanisch <dvb@flensrocker.de>2011-02-02 14:18:45 +0100
commitc03cb92fb43baab9136bd9122d757359e0590fda (patch)
treedbd9851e29274ba4b0189f3f859c1a29d20b8a88 /patches/vdr-1.7.16-dynamite-subdevice.patch
downloadvdr-plugin-dynamite-c03cb92fb43baab9136bd9122d757359e0590fda.tar.gz
vdr-plugin-dynamite-c03cb92fb43baab9136bd9122d757359e0590fda.tar.bz2
initial commit of version 0.0.5c
Diffstat (limited to 'patches/vdr-1.7.16-dynamite-subdevice.patch')
-rw-r--r--patches/vdr-1.7.16-dynamite-subdevice.patch361
1 files changed, 361 insertions, 0 deletions
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);
+