LIBS += -lpcsclite
endif
+HAVE_SD := $(wildcard ../dvbsddevice/dvbsddevice.c)
+ifneq ($(strip $(HAVE_SD)),)
+ DEFINES += -DWITH_SDDVB
+ DEVPLUGTARGETS += $(LIBDIR)/libsc-dvbsddevice-$(SCAPIVERS).so.$(APIVERSION)
+endif
+HAVE_HD := $(wildcard ../dvbhddevice/dvbhddevice.c)
+ifneq ($(strip $(HAVE_HD)),)
+ DEFINES += -DWITH_HDDVB
+ DEVPLUGTARGETS += $(LIBDIR)/libsc-dvbhddevice-$(SCAPIVERS).so.$(APIVERSION)
+endif
+
# max number of CAIDs per slot
MAXCAID := $(shell sed -ne '/define MAXCASYSTEMIDS/ s/^.[a-zA-Z ]*\([0-9]*\).*$$/\1/p' $(VDRDIR)/ci.c)
ifneq ($(strip $(MAXCAID)),)
BUILDTARGETS = $(LIBDIR)/libvdr-$(PLUGIN).a
SHAREDDEFINES += -DSTATICBUILD
else
-BUILDTARGETS = $(LIBDIR)/libvdr-$(PLUGIN).so.$(APIVERSION) systems-pre
+BUILDTARGETS = $(LIBDIR)/libvdr-$(PLUGIN).so.$(APIVERSION) systems-pre $(DEVPLUGTARGETS)
endif
BUILDTARGETS += $(FFDECSATEST) systems i18n
$(LIBDIR)/libvdr-$(PLUGIN).a: $(OBJS)
$(AR) r $@ $(OBJS)
+libsc-dvbsddevice.so: device-sd.o
+ $(CXX) $(CXXFLAGS) -shared $< $(SHAREDLIBS) -o $@
+
+$(LIBDIR)/libsc-dvbsddevice-$(SCAPIVERS).so.$(APIVERSION): libsc-dvbsddevice.so
+ @cp -p $< $@
+
+libsc-dvbhddevice.so: device-hd.o
+ $(CXX) $(CXXFLAGS) -shared $< $(SHAREDLIBS) -o $@
+
+$(LIBDIR)/libsc-dvbhddevice-$(SCAPIVERS).so.$(APIVERSION): libsc-dvbhddevice.so
+ @cp -p $< $@
+
$(FFDECSA) $(FFDECSATEST): $(FFDECSADIR)/*.c $(FFDECSADIR)/*.h
@$(MAKE) COMPILER="$(CXX)" FLAGS="$(CSAFLAGS) -march=$(CPUOPT)" PARALLEL_MODE=$(PARALLEL) -C $(FFDECSADIR) all
with AES and IDEA enabled, as support for openssl without these will be removed
in the near future.
+**** VDR 1.7.11+ notes ****
+If you want to use VDR 1.7.11+ together with a full-featured DVB card:
+- the source code for the dvbhddevice and/or dvbsddevice has to be available in
+ the VDR plugin source directory, i.e. at the parent directory level of this
+ plugin source. The presence of these plugin sources will be detected
+ automatically and support for them will be enabled at compile time.
+- the compiled dvbhddevice and/or dvbsddevice plugin libraries (i.e. the *.so
+ files) have to be available in the VDR plugin library directory at runtime.
+- DO NOT load the dvbhddevice and/or dvbsddevice on the VDR commandline (i.e.
+ with parameter -P). They will be loaded internaly from this plugin. It will
+ not work correctly if you load them from commandline!
+
Now follow the VDR instruction to compile plugins (make plugins). Beside the
core plugin (libvdr-sc.so), the make process (if successfull) creates an
additional shared library object for every supported system (libsc-*.so). You
--- /dev/null
+/*
+ * Softcam plugin to VDR (C++)
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifndef SASC
+
+#include <vdr/channels.h>
+#include <vdr/ci.h>
+#include <vdr/dvbci.h>
+
+#include "device.h"
+#include "cam.h"
+#include "scsetup.h"
+#include "log-core.h"
+#include "version.h"
+
+SCAPIVERSTAG();
+
+#if APIVERSNUM >= 10711
+#ifdef WITH_HDDVB
+
+// -- cScDvbSdFfDevice ---------------------------------------------------------
+
+#include "../dvbhddevice/dvbhdffdevice.h"
+#define SCDEVICE cScDvbHdFfDevice
+#define DVBDEVICE cDvbHdFfDevice
+#include "device-tmpl.c"
+#undef SCDEVICE
+#undef DVBDEVICE
+
+// -- cScHdDevicePlugin --------------------------------------------------------
+
+class cScHdDevicePlugin : public cScDevicePlugin {
+public:
+ virtual cDevice *Probe(int Adapter, int Frontend, uint32_t SubSystemId);
+ virtual bool LateInit(cDevice *dev);
+ virtual bool EarlyShutdown(cDevice *dev);
+ };
+
+static cScHdDevicePlugin _hddevplugin;
+
+cDevice *cScHdDevicePlugin::Probe(int Adapter, int Frontend, uint32_t SubSystemId)
+{
+ static uint32_t SubsystemIds[] = {
+ 0x13C23009, // Technotrend S2-6400 HDFF development samples
+ 0x13C2300A, // Technotrend S2-6400 HDFF production version
+ 0x00000000
+ };
+ for(uint32_t *sid=SubsystemIds; *sid; sid++) {
+ if(*sid==SubSystemId) {
+ PRINTF(L_GEN_DEBUG,"creating HD-FF device %d/%d",Adapter,Frontend);
+ return new cScDvbHdFfDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR));
+ }
+ }
+ return 0;
+}
+
+bool cScHdDevicePlugin::LateInit(cDevice *dev)
+{
+ cScDvbHdFfDevice *d=dynamic_cast<cScDvbHdFfDevice *>(dev);
+ if(d) d->LateInit();
+ return d!=0;
+}
+
+bool cScHdDevicePlugin::EarlyShutdown(cDevice *dev)
+{
+ cScDvbHdFfDevice *d=dynamic_cast<cScDvbHdFfDevice *>(dev);
+ if(d) d->EarlyShutdown();
+ return d!=0;
+}
+
+#endif //WITH_HDDVB
+#endif //APIVERSNUM >= 10711
+#endif //SASC
--- /dev/null
+/*
+ * Softcam plugin to VDR (C++)
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifndef SASC
+
+#include <vdr/channels.h>
+#include <vdr/ci.h>
+#include <vdr/dvbci.h>
+
+#include "device.h"
+#include "cam.h"
+#include "scsetup.h"
+#include "log-core.h"
+#include "version.h"
+
+SCAPIVERSTAG();
+
+#if APIVERSNUM >= 10711
+#ifdef WITH_SDDVB
+
+// -- cScDvbSdFfDevice ---------------------------------------------------------
+
+#include "../dvbsddevice/dvbsdffdevice.h"
+#define SCDEVICE cScDvbSdFfDevice
+#define DVBDEVICE cDvbSdFfDevice
+#include "device-tmpl.c"
+#undef SCDEVICE
+#undef DVBDEVICE
+
+// -- cScSdDevicePlugin --------------------------------------------------------
+
+class cScSdDevicePlugin : public cScDevicePlugin {
+public:
+ virtual cDevice *Probe(int Adapter, int Frontend, uint32_t SubSystemId);
+ virtual bool LateInit(cDevice *dev);
+ virtual bool EarlyShutdown(cDevice *dev);
+ };
+
+static cScSdDevicePlugin _sddevplugin;
+
+cDevice *cScSdDevicePlugin::Probe(int Adapter, int Frontend, uint32_t SubSystemId)
+{
+ static uint32_t SubsystemIds[] = {
+ 0x110A0000, // Fujitsu Siemens DVB-C
+ 0x13C20000, // Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C
+ 0x13C20001, // Technotrend/Hauppauge WinTV DVB-T rev1.X
+ 0x13C20002, // Technotrend/Hauppauge WinTV DVB-C rev2.X
+ 0x13C20003, // Technotrend/Hauppauge WinTV Nexus-S rev2.X
+ 0x13C20004, // Galaxis DVB-S rev1.3
+ 0x13C20006, // Fujitsu Siemens DVB-S rev1.6
+ 0x13C20008, // Technotrend/Hauppauge DVB-T
+ 0x13C2000A, // Technotrend/Hauppauge WinTV Nexus-CA rev1.X
+ 0x13C2000E, // Technotrend/Hauppauge WinTV Nexus-S rev2.3
+ 0x13C21002, // Technotrend/Hauppauge WinTV DVB-S rev1.3 SE
+ 0x00000000
+ };
+ for(uint32_t *sid=SubsystemIds; *sid; sid++) {
+ if(*sid==SubSystemId) {
+ PRINTF(L_GEN_DEBUG,"creating SD-FF device %d/%d",Adapter,Frontend);
+ return new cScDvbSdFfDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR));
+ }
+ }
+ return 0;
+}
+
+bool cScSdDevicePlugin::LateInit(cDevice *dev)
+{
+ cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(dev);
+ if(d) d->LateInit();
+ return d!=0;
+}
+
+bool cScSdDevicePlugin::EarlyShutdown(cDevice *dev)
+{
+ cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(dev);
+ if(d) d->EarlyShutdown();
+ return d!=0;
+}
+
+#endif //WITH_SDDVB
+#endif //APIVERSNUM >= 10711
+#endif //SASC
--- /dev/null
+/*
+ * Softcam plugin to VDR (C++)
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+// -- cScDevice ----------------------------------------------------------------
+
+class SCDEVICE : public DVBDEVICE {
+private:
+ cDeCsaTSBuffer *tsBuffer;
+ cMutex tsMutex;
+ cCam *cam;
+ cCiAdapter *hwciadapter;
+ int fd_dvr, fd_ca, fd_ca2;
+ bool softcsa, fullts;
+ char devId[8];
+ //
+#ifndef SASC
+ bool ScActive(void);
+#endif //SASC
+protected:
+#ifndef SASC
+ virtual bool Ready(void);
+ virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
+ virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
+ virtual bool OpenDvr(void);
+ virtual void CloseDvr(void);
+ virtual bool GetTSPacket(uchar *&Data);
+#endif //SASC
+public:
+ SCDEVICE(int Adapter, int Frontend, int cafd);
+ ~SCDEVICE();
+#ifndef SASC
+ virtual bool HasCi(void);
+ void LateInit(void);
+ void EarlyShutdown(void);
+#endif //SASC
+ };
+
+SCDEVICE::SCDEVICE(int Adapter, int Frontend, int cafd)
+#if APIVERSNUM >= 10711
+:DVBDEVICE(Adapter,Frontend)
+#else
+:DVBDEVICE(Adapter)
+#endif
+{
+ tsBuffer=0; softcsa=fullts=false;
+ cam=0; hwciadapter=0;
+ fd_ca=cafd; fd_ca2=dup(fd_ca); fd_dvr=-1;
+#ifdef SASC
+ cam=new cCam(this,Adapter);
+#endif // !SASC
+#if APIVERSNUM >= 10711
+ snprintf(devId,sizeof(devId),"%d/%d",Adapter,Frontend);
+#else
+ snprintf(devId,sizeof(devId),"%d",Adapter);
+#endif
+}
+
+SCDEVICE::~SCDEVICE()
+{
+#ifndef SASC
+ DetachAllReceivers();
+ Cancel(3);
+ EarlyShutdown();
+ if(fd_ca>=0) close(fd_ca);
+ if(fd_ca2>=0) close(fd_ca2);
+#else
+ delete cam;
+#endif // !SASC
+}
+
+#ifndef SASC
+
+void SCDEVICE::EarlyShutdown(void)
+{
+ SetCamSlot(0);
+ delete cam; cam=0;
+ delete hwciadapter; hwciadapter=0;
+}
+
+void SCDEVICE::LateInit(void)
+{
+ int n=CardIndex();
+ if(DeviceNumber()!=n)
+ PRINTF(L_GEN_ERROR,"CardIndex - DeviceNumber mismatch! Put SC plugin first on VDR commandline!");
+ softcsa=(fd_ca<0);
+ if(softcsa) {
+ if(HasDecoder()) PRINTF(L_GEN_ERROR,"Card %s is a full-featured card but no ca device found!",devId);
+ }
+ else if(cScDevices::ForceBudget(n)) {
+ PRINTF(L_GEN_INFO,"Budget mode forced on card %s",devId);
+ softcsa=true;
+ }
+ if(softcsa) {
+ if(IsPrimaryDevice() && HasDecoder()) {
+ PRINTF(L_GEN_INFO,"Enabling hybrid full-ts mode on card %s",devId);
+ fullts=true;
+ }
+ else PRINTF(L_GEN_INFO,"Using software decryption on card %s",devId);
+ }
+ if(fd_ca2>=0) hwciadapter=cDvbCiAdapter::CreateCiAdapter(this,fd_ca2);
+ cam=new cCam(this,DVB_DEV_SPEC,devId,fd_ca,softcsa,fullts);
+}
+
+bool SCDEVICE::HasCi(void)
+{
+ return cam || hwciadapter;
+}
+
+bool SCDEVICE::Ready(void)
+{
+ return (cam ? cam->Ready():true) &&
+ (hwciadapter ? hwciadapter->Ready():true);
+}
+
+bool SCDEVICE::SetPid(cPidHandle *Handle, int Type, bool On)
+{
+ if(cam) cam->SetPid(Type,Handle->pid,On);
+ tsMutex.Lock();
+ if(tsBuffer) tsBuffer->SetActive(ScActive());
+ tsMutex.Unlock();
+ return DVBDEVICE::SetPid(Handle,Type,On);
+}
+
+bool SCDEVICE::SetChannelDevice(const cChannel *Channel, bool LiveView)
+{
+ if(cam) cam->Tune(Channel);
+ bool ret=DVBDEVICE::SetChannelDevice(Channel,LiveView);
+ if(ret && cam) cam->PostTune();
+ return ret;
+}
+
+bool SCDEVICE::ScActive(void)
+{
+ return cam && cam->OwnSlot(CamSlot());
+}
+
+bool SCDEVICE::OpenDvr(void)
+{
+ CloseDvr();
+ fd_dvr=cScDevices::DvbOpen(DEV_DVB_DVR,DVB_DEV_SPEC,O_RDONLY|O_NONBLOCK,true);
+ if(fd_dvr>=0) {
+ cDeCSA *decsa=cam ? cam->DeCSA() : 0;
+ tsMutex.Lock();
+ tsBuffer=new cDeCsaTSBuffer(fd_dvr,MEGABYTE(ScSetup.DeCsaTsBuffSize),CardIndex()+1,decsa,ScActive());
+ tsMutex.Unlock();
+ }
+ return fd_dvr>=0;
+}
+
+void SCDEVICE::CloseDvr(void)
+{
+ tsMutex.Lock();
+ delete tsBuffer; tsBuffer=0;
+ tsMutex.Unlock();
+ if(fd_dvr>=0) { close(fd_dvr); fd_dvr=-1; }
+}
+
+bool SCDEVICE::GetTSPacket(uchar *&Data)
+{
+ if(tsBuffer) { Data=tsBuffer->Get(); return true; }
+ return false;
+}
+
+#endif // !SASC
// -- cDeCsaTSBuffer -----------------------------------------------------------
-class cDeCsaTSBuffer : public cThread {
-private:
- int f;
- int cardIndex, size;
- bool delivered;
- cRingBufferLinear *ringBuffer;
- //
- cDeCSA *decsa;
- bool scActive;
- //
- virtual void Action(void);
-public:
- cDeCsaTSBuffer(int File, int Size, int CardIndex, cDeCSA *DeCsa, bool ScActive);
- ~cDeCsaTSBuffer();
- uchar *Get(void);
- void SetActive(bool ScActive);
- };
-
cDeCsaTSBuffer::cDeCsaTSBuffer(int File, int Size, int CardIndex, cDeCSA *DeCsa, bool ScActive)
{
SetDescription("TS buffer on device %d", CardIndex);
return NULL;
}
-// --- cScDeviceProbe ----------------------------------------------------------
+// --- cScDevicePlugin ---------------------------------------------------------
+
+static cSimpleList<cScDevicePlugin> devplugins;
+
+cScDevicePlugin::cScDevicePlugin(void)
+{
+ devplugins.Add(this);
+}
+
+cScDevicePlugin::~cScDevicePlugin()
+{
+ devplugins.Del(this,false);
+}
+
+// -- cScDvbDevice -------------------------------------------------------------
+
+#define SCDEVICE cScDvbDevice
+#define DVBDEVICE cDvbDevice
+#include "device-tmpl.c"
+#undef SCDEVICE
+#undef DVBDEVICE
+
+// -- cScDvbDevicePlugin -------------------------------------------------------
+
+class cScDvbDevicePlugin : public cScDevicePlugin {
+public:
+ virtual cDevice *Probe(int Adapter, int Frontend, uint32_t SubSystemId);
+ virtual bool LateInit(cDevice *dev);
+ virtual bool EarlyShutdown(cDevice *dev);
+ };
+
+cDevice *cScDvbDevicePlugin::Probe(int Adapter, int Frontend, uint32_t SubSystemId)
+{
+ PRINTF(L_GEN_DEBUG,"creating standard device %d/%d",Adapter,Frontend);
+ return new cScDvbDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR));
+}
+
+bool cScDvbDevicePlugin::LateInit(cDevice *dev)
+{
+ cScDvbDevice *d=dynamic_cast<cScDvbDevice *>(dev);
+ if(d) d->LateInit();
+ return d!=0;
+}
-#define DEV_DVB_ADAPTER "/dev/dvb/adapter"
-#define DEV_DVB_FRONTEND "frontend"
-#define DEV_DVB_DVR "dvr"
-#define DEV_DVB_DEMUX "demux"
-#define DEV_DVB_CA "ca"
+bool cScDvbDevicePlugin::EarlyShutdown(cDevice *dev)
+{
+ cScDvbDevice *d=dynamic_cast<cScDvbDevice *>(dev);
+ if(d) d->EarlyShutdown();
+ return d!=0;
+}
+
+// --- cScDeviceProbe ----------------------------------------------------------
#if APIVERSNUM >= 10711
virtual bool Probe(int Adapter, int Frontend);
static void Install(void);
static void Remove(void);
+#if APIVERSNUM < 10719
+ uint32_t GetSubsystemId(int Adapter, int Frontend);
+#endif
};
cScDeviceProbe *cScDeviceProbe::probe=0;
bool cScDeviceProbe::Probe(int Adapter, int Frontend)
{
- PRINTF(L_GEN_DEBUG,"capturing device %d/%d",Adapter,Frontend);
- new cScDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR));
- return true;
+ uint32_t subid=GetSubsystemId(Adapter,Frontend);
+ PRINTF(L_GEN_DEBUG,"capturing device %d/%d (subsystem ID %08x)",Adapter,Frontend,subid);
+ for(cScDevicePlugin *dp=devplugins.First(); dp; dp=devplugins.Next(dp))
+ if(dp->Probe(Adapter,Frontend,subid)) return true;
+ return false;
}
-#endif
+
+#if APIVERSNUM < 10719
+uint32_t cScDeviceProbe::GetSubsystemId(int Adapter, int Frontend)
+{
+ cString FileName;
+ cReadLine ReadLine;
+ FILE *f = NULL;
+ uint32_t SubsystemId = 0;
+ FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
+ if ((f = fopen(FileName, "r")) != NULL) {
+ if (char *s = ReadLine.Read(f))
+ SubsystemId = strtoul(s, NULL, 0) << 16;
+ fclose(f);
+ }
+ FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
+ if ((f = fopen(FileName, "r")) != NULL) {
+ if (char *s = ReadLine.Read(f))
+ SubsystemId |= strtoul(s, NULL, 0);
+ fclose(f);
+ }
+ return SubsystemId;
+}
+#endif //APIVERSNUM < 10719
+
+#endif //APIVERSNUM >= 10711
// -- cScDevices ---------------------------------------------------------------
#endif
if(vdr_nci && vdr_ud) { vdr_save_ud=*vdr_ud; *vdr_ud=1<<30; }
#endif
+ // default device plugin must be last in the list
+ new cScDvbDevicePlugin;
}
void cScDevices::OnPluginUnload(void)
if(f>=0) {
close(f);
PRINTF(L_GEN_DEBUG,"capturing device %d",i);
- new cScDevice(i,0,cScDevices::DvbOpen(DEV_DVB_CA,i,0,O_RDWR));
+ devplugins.First()->Probe(i,0,0);
found++;
}
else {
if(ScSetup.ForceTransfer)
SetTransferModeForDolbyDigital(2);
for(int n=cDevice::NumDevices(); --n>=0;) {
- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(n));
- if(dev) dev->LateInit();
+ cDevice *dev=cDevice::GetDevice(n);
+ for(cScDevicePlugin *dp=devplugins.First(); dp; dp=devplugins.Next(dp))
+ if(dp->LateInit(dev)) break;
}
}
void cScDevices::Shutdown(void)
{
for(int n=cDevice::NumDevices(); --n>=0;) {
- cScDevice *dev=dynamic_cast<cScDevice *>(cDevice::GetDevice(n));
- if(dev) dev->EarlyShutdown();
+ cDevice *dev=cDevice::GetDevice(n);
+ for(cScDevicePlugin *dp=devplugins.First(); dp; dp=devplugins.Next(dp))
+ if(dp->EarlyShutdown(dev)) break;
}
}
bool cScDevices::ForceBudget(int n) { return true; }
#endif //SASC
-
-// -- cScDevice ----------------------------------------------------------------
-
-#if APIVERSNUM >= 10711
-#define DVB_DEV_SPEC adapter,frontend
-#else
-#define DVB_DEV_SPEC CardIndex(),0
-#endif
-
-cScDevice::cScDevice(int Adapter, int Frontend, int cafd)
-#if APIVERSNUM >= 10711
-:cDvbDevice(Adapter,Frontend)
-#else
-:cDvbDevice(Adapter)
-#endif
-{
- tsBuffer=0; softcsa=fullts=false;
- cam=0; hwciadapter=0;
- fd_ca=cafd; fd_ca2=dup(fd_ca); fd_dvr=-1;
-#ifdef SASC
- cam=new cCam(this,Adapter);
-#endif // !SASC
-#if APIVERSNUM >= 10711
- snprintf(devId,sizeof(devId),"%d/%d",Adapter,Frontend);
-#else
- snprintf(devId,sizeof(devId),"%d",Adapter);
-#endif
-}
-
-cScDevice::~cScDevice()
-{
-#ifndef SASC
- DetachAllReceivers();
- Cancel(3);
- EarlyShutdown();
- if(fd_ca>=0) close(fd_ca);
- if(fd_ca2>=0) close(fd_ca2);
-#else
- delete cam;
-#endif // !SASC
-}
-
-#ifndef SASC
-
-void cScDevice::EarlyShutdown(void)
-{
- SetCamSlot(0);
- delete cam; cam=0;
- delete hwciadapter; hwciadapter=0;
-}
-
-void cScDevice::LateInit(void)
-{
- int n=CardIndex();
- if(DeviceNumber()!=n)
- PRINTF(L_GEN_ERROR,"CardIndex - DeviceNumber mismatch! Put SC plugin first on VDR commandline!");
- softcsa=(fd_ca<0);
- if(softcsa) {
- if(HasDecoder()) PRINTF(L_GEN_ERROR,"Card %s is a full-featured card but no ca device found!",devId);
- }
- else if(cScDevices::ForceBudget(n)) {
- PRINTF(L_GEN_INFO,"Budget mode forced on card %s",devId);
- softcsa=true;
- }
- if(softcsa) {
- if(IsPrimaryDevice() && HasDecoder()) {
- PRINTF(L_GEN_INFO,"Enabling hybrid full-ts mode on card %s",devId);
- fullts=true;
- }
- else PRINTF(L_GEN_INFO,"Using software decryption on card %s",devId);
- }
- if(fd_ca2>=0) hwciadapter=cDvbCiAdapter::CreateCiAdapter(this,fd_ca2);
- cam=new cCam(this,DVB_DEV_SPEC,devId,fd_ca,softcsa,fullts);
-}
-
-bool cScDevice::HasCi(void)
-{
- return cam || hwciadapter;
-}
-
-bool cScDevice::Ready(void)
-{
- return (cam ? cam->Ready():true) &&
- (hwciadapter ? hwciadapter->Ready():true);
-}
-
-bool cScDevice::SetPid(cPidHandle *Handle, int Type, bool On)
-{
- if(cam) cam->SetPid(Type,Handle->pid,On);
- tsMutex.Lock();
- if(tsBuffer) tsBuffer->SetActive(ScActive());
- tsMutex.Unlock();
- return cDvbDevice::SetPid(Handle,Type,On);
-}
-
-bool cScDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
-{
- if(cam) cam->Tune(Channel);
- bool ret=cDvbDevice::SetChannelDevice(Channel,LiveView);
- if(ret && cam) cam->PostTune();
- return ret;
-}
-
-bool cScDevice::ScActive(void)
-{
- return cam && cam->OwnSlot(CamSlot());
-}
-
-bool cScDevice::OpenDvr(void)
-{
- CloseDvr();
- fd_dvr=cScDevices::DvbOpen(DEV_DVB_DVR,DVB_DEV_SPEC,O_RDONLY|O_NONBLOCK,true);
- if(fd_dvr>=0) {
- cDeCSA *decsa=cam ? cam->DeCSA() : 0;
- tsMutex.Lock();
- tsBuffer=new cDeCsaTSBuffer(fd_dvr,MEGABYTE(ScSetup.DeCsaTsBuffSize),CardIndex()+1,decsa,ScActive());
- tsMutex.Unlock();
- }
- return fd_dvr>=0;
-}
-
-void cScDevice::CloseDvr(void)
-{
- tsMutex.Lock();
- delete tsBuffer; tsBuffer=0;
- tsMutex.Unlock();
- if(fd_dvr>=0) { close(fd_dvr); fd_dvr=-1; }
-}
-
-bool cScDevice::GetTSPacket(uchar *&Data)
-{
- if(tsBuffer) { Data=tsBuffer->Get(); return true; }
- return false;
-}
-
-#endif // !SASC
#include <vdr/dvbdevice.h>
#include <vdr/thread.h>
+#include "misc.h"
-class cCam;
class cDeCSA;
-class cDeCsaTSBuffer;
-class cScCiAdapter;
+
+// ----------------------------------------------------------------
+
+#define DEV_DVB_ADAPTER "/dev/dvb/adapter"
+#define DEV_DVB_FRONTEND "frontend"
+#define DEV_DVB_DVR "dvr"
+#define DEV_DVB_DEMUX "demux"
+#define DEV_DVB_CA "ca"
+#define DEV_DVB_OSD "osd"
+
+#if APIVERSNUM >= 10711
+#define DVB_DEV_SPEC adapter,frontend
+#else
+#define DVB_DEV_SPEC CardIndex(),0
+#endif
+
+// ----------------------------------------------------------------
+
+class cDeCsaTSBuffer : public cThread {
+private:
+ int f;
+ int cardIndex, size;
+ bool delivered;
+ cRingBufferLinear *ringBuffer;
+ //
+ cDeCSA *decsa;
+ bool scActive;
+ //
+ virtual void Action(void);
+public:
+ cDeCsaTSBuffer(int File, int Size, int CardIndex, cDeCSA *DeCsa, bool ScActive);
+ ~cDeCsaTSBuffer();
+ uchar *Get(void);
+ void SetActive(bool ScActive);
+ };
// ----------------------------------------------------------------
// ----------------------------------------------------------------
-class cScDevice : public cDvbDevice {
-friend class cScDevices;
-private:
- cDeCsaTSBuffer *tsBuffer;
- cMutex tsMutex;
- cCam *cam;
- cCiAdapter *hwciadapter;
- int fd_dvr, fd_ca, fd_ca2;
- bool softcsa, fullts;
- char devId[8];
- //
-#ifndef SASC
- void LateInit(void);
- void EarlyShutdown(void);
- bool ScActive(void);
-#endif //SASC
- //
-protected:
-#ifndef SASC
- virtual bool Ready(void);
- virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
- virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
- virtual bool OpenDvr(void);
- virtual void CloseDvr(void);
- virtual bool GetTSPacket(uchar *&Data);
-#endif //SASC
+class cScDevicePlugin : public cSimpleItem {
public:
- cScDevice(int Adapter, int Frontend, int cafd);
- ~cScDevice();
-#ifndef SASC
- virtual bool HasCi(void);
-#endif //SASC
+ cScDevicePlugin(void);
+ virtual ~cScDevicePlugin();
+ virtual cDevice *Probe(int Adapter, int Frontend, uint32_t SubSystemId)=0;
+ virtual bool LateInit(cDevice *dev)=0;
+ virtual bool EarlyShutdown(cDevice *dev)=0;
};
#endif // ___DEVICE_H
public:
cScDll(const char *FileName);
~cScDll();
- bool Load(void);
+ bool Load(bool check);
};
cScDll::cScDll(const char *FileName)
free(fileName);
}
-bool cScDll::Load(void)
+bool cScDll::Load(bool check)
{
char *base=rindex(fileName,'/');
if(base) base++; else base=fileName;
PRINTF(L_CORE_DYN,"loading library: %s",base);
if(!handle) {
- handle=dlopen(fileName,RTLD_NOW|RTLD_LOCAL);
+ handle=dlopen(fileName,RTLD_NOW|(check?RTLD_LOCAL:RTLD_GLOBAL));
if(handle) {
+ if(!check) return true;
dlerror();
int *libapivers=(int *)dlsym(handle,"ScLibApiVersion");
const char *error=dlerror();
// --- cScDlls -----------------------------------------------------------------
+#define LIBVDR_PREFIX "libvdr-"
#define LIBSC_PREFIX "libsc-"
#define SO_INDICATOR ".so."
if((p=rindex(path,'/'))) *p=0;
PRINTF(L_CORE_DYN,"library path %sn",path);
- char pat[32];
+ char pat[64];
+#if APIVERSNUM >= 10711
+#ifdef WITH_SDDVB
+ {
+ snprintf(pat,sizeof(pat),"%s%s%s%s",LIBVDR_PREFIX,"dvbsddevice",SO_INDICATOR,APIVERSION);
+ cScDll *dll=new cScDll(AddDirectory(path,pat));
+ if(dll) {
+ if(dll->Load(false)) {
+ PRINTF(L_GEN_INFO,"VDR dvbsddevice plugin loaded as subplugin");
+ }
+ Ins(dll);
+ }
+ }
+#endif //WITH_SDDVB
+#ifdef WITH_HDDVB
+ {
+ snprintf(pat,sizeof(pat),"%s%s%s%s",LIBVDR_PREFIX,"dvbhddevice",SO_INDICATOR,APIVERSION);
+ cScDll *dll=new cScDll(AddDirectory(path,pat));
+ if(dll) {
+ if(dll->Load(false)) {
+ PRINTF(L_GEN_INFO,"VDR dvbhddevice plugin loaded as subplugin");
+ }
+ Ins(dll);
+ }
+ }
+#endif //WITH_HDDVB
+#endif //APIVERSNUM >= 10711
+
snprintf(pat,sizeof(pat),"%s*-%d%s%s",LIBSC_PREFIX,SCAPIVERS,SO_INDICATOR,APIVERSION);
bool res=true;
cReadDir dir(path);
if(!fnmatch(pat,e->d_name,FNM_PATHNAME|FNM_NOESCAPE)) {
cScDll *dll=new cScDll(AddDirectory(path,e->d_name));
if(dll) {
- if(!dll->Load()) res=false;
+ if(!dll->Load(true)) res=false;
Ins(dll);
}
}
return res;
}
-#endif
+#endif //STATICBUILD
// --- cScPlugin ---------------------------------------------------------------