mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-28 13:16:41 +00:00
vdr: update to vdr-1.7.33
This commit is contained in:
parent
a346645a0d
commit
2482039479
2
packages/3rdparty/multimedia/vdr/build
vendored
2
packages/3rdparty/multimedia/vdr/build
vendored
@ -44,5 +44,5 @@ LIBS += -liconv
|
|||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
make
|
make vdr
|
||||||
make include-dir
|
make include-dir
|
||||||
|
2
packages/3rdparty/multimedia/vdr/meta
vendored
2
packages/3rdparty/multimedia/vdr/meta
vendored
@ -20,7 +20,7 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
PKG_NAME="vdr"
|
PKG_NAME="vdr"
|
||||||
PKG_VERSION="1.7.27"
|
PKG_VERSION="1.7.33"
|
||||||
PKG_REV="1"
|
PKG_REV="1"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="GPL"
|
PKG_LICENSE="GPL"
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
diff --git a/font.c b/font.c
|
|
||||||
index 706a017..72c5ec3 100644
|
|
||||||
--- a/font.c
|
|
||||||
+++ b/font.c
|
|
||||||
@@ -482,7 +482,8 @@ cString cFont::GetFontFileName(const char *FontName)
|
|
||||||
FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
|
|
||||||
FcConfigSubstitute(NULL, pat, FcMatchPattern);
|
|
||||||
FcDefaultSubstitute(pat);
|
|
||||||
- FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, NULL);
|
|
||||||
+ FcResult fresult;
|
|
||||||
+ FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, &fresult);
|
|
||||||
if (fontset) {
|
|
||||||
for (int i = 0; i < fontset->nfont; i++) {
|
|
||||||
FcBool scalable;
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/recording.h b/recording.h
|
|
||||||
index 5f94ee2..0b44fe8 100644
|
|
||||||
--- a/recording.h
|
|
||||||
+++ b/recording.h
|
|
||||||
@@ -22,7 +22,7 @@
|
|
||||||
#define TIMERMACRO_TITLE "TITLE"
|
|
||||||
#define TIMERMACRO_EPISODE "EPISODE"
|
|
||||||
|
|
||||||
-//#define __RECORDING_H_DEPRECATED_DIRECT_MEMBER_ACCESS // Code enclosed with this macro is deprecated and may be removed in a future version
|
|
||||||
+#define __RECORDING_H_DEPRECATED_DIRECT_MEMBER_ACCESS // Code enclosed with this macro is deprecated and may be removed in a future version
|
|
||||||
|
|
||||||
extern bool VfatFileSystem;
|
|
||||||
extern int InstanceId;
|
|
@ -1,84 +0,0 @@
|
|||||||
Description: This patch allows tuning to encrypted channels which are
|
|
||||||
provided by a stremdev client device and therefore already are
|
|
||||||
decrypted on the streamdev server side.
|
|
||||||
See also: http://www.vdr-developer.org/mantisbt/view.php?id=429
|
|
||||||
Author: Tobias Grimm <tg@e-tobi.net>
|
|
||||||
|
|
||||||
Index: vdr-1.7.27/device.c
|
|
||||||
===================================================================
|
|
||||||
--- vdr-1.7.27.orig/device.c 2012-03-13 10:48:14.000000000 +0100
|
|
||||||
+++ vdr-1.7.27/device.c 2012-03-25 14:18:05.434975038 +0200
|
|
||||||
@@ -236,6 +236,7 @@
|
|
||||||
int NumCamSlots = CamSlots.Count();
|
|
||||||
int SlotPriority[NumCamSlots];
|
|
||||||
int NumUsableSlots = 0;
|
|
||||||
+ bool InternalCamNeeded = false;
|
|
||||||
if (Channel->Ca() >= CA_ENCRYPTED_MIN) {
|
|
||||||
for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) {
|
|
||||||
SlotPriority[CamSlot->Index()] = MAXPRIORITY + 1; // assumes it can't be used
|
|
||||||
@@ -249,7 +250,7 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!NumUsableSlots)
|
|
||||||
- return NULL; // no CAM is able to decrypt this channel
|
|
||||||
+ InternalCamNeeded = true; // no CAM is able to decrypt this channel
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NeedsDetachReceivers = false;
|
|
||||||
@@ -263,11 +264,13 @@
|
|
||||||
for (int i = 0; i < numDevices; i++) {
|
|
||||||
if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->CardIndex() + 1)
|
|
||||||
continue; // a specific card was requested, but not this one
|
|
||||||
- if (NumUsableSlots && !CamSlots.Get(j)->Assign(device[i], true))
|
|
||||||
+ if (InternalCamNeeded && !device[i]->HasInternalCam())
|
|
||||||
+ continue; // no CAM is able to decrypt this channel and the device uses vdr handled CAMs
|
|
||||||
+ if (NumUsableSlots && !device[i]->HasInternalCam() && !CamSlots.Get(j)->Assign(device[i], true))
|
|
||||||
continue; // CAM slot can't be used with this device
|
|
||||||
bool ndr;
|
|
||||||
if (device[i]->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basicly able to do the job
|
|
||||||
- if (NumUsableSlots && device[i]->CamSlot() && device[i]->CamSlot() != CamSlots.Get(j))
|
|
||||||
+ if (NumUsableSlots && !device[i]->HasInternalCam() && device[i]->CamSlot() && device[i]->CamSlot() != CamSlots.Get(j))
|
|
||||||
ndr = true; // using a different CAM slot requires detaching receivers
|
|
||||||
// Put together an integer number that reflects the "impact" using
|
|
||||||
// this device would have on the overall system. Each condition is represented
|
|
||||||
@@ -282,18 +285,18 @@
|
|
||||||
imp <<= 4; imp |= GetClippedNumProvidedSystems(4, device[i]) - 1; // avoid cards which support multiple delivery systems
|
|
||||||
imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device
|
|
||||||
imp <<= 8; imp |= device[i]->Priority() - IDLEPRIORITY; // use the device with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
|
|
||||||
- imp <<= 8; imp |= (NumUsableSlots ? SlotPriority[j] : IDLEPRIORITY) - IDLEPRIORITY; // use the CAM slot with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
|
|
||||||
+ imp <<= 8; imp |= ((NumUsableSlots && !device[i]->HasInternalCam()) ? SlotPriority[j] : IDLEPRIORITY) - IDLEPRIORITY; // use the CAM slot with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
|
|
||||||
imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers
|
|
||||||
- imp <<= 1; imp |= NumUsableSlots ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels
|
|
||||||
+ imp <<= 1; imp |= (NumUsableSlots || InternalCamNeeded) ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels
|
|
||||||
imp <<= 1; imp |= device[i]->AvoidRecording(); // avoid SD full featured cards
|
|
||||||
- imp <<= 1; imp |= NumUsableSlots ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel
|
|
||||||
+ imp <<= 1; imp |= (NumUsableSlots && !device[i]->HasInternalCam()) ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel
|
|
||||||
imp <<= 1; imp |= device[i]->IsPrimaryDevice(); // avoid the primary device
|
|
||||||
if (imp < Impact) {
|
|
||||||
// This device has less impact than any previous one, so we take it.
|
|
||||||
Impact = imp;
|
|
||||||
d = device[i];
|
|
||||||
NeedsDetachReceivers = ndr;
|
|
||||||
- if (NumUsableSlots)
|
|
||||||
+ if (NumUsableSlots && !device[i]->HasInternalCam())
|
|
||||||
s = CamSlots.Get(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Index: vdr-1.7.27/device.h
|
|
||||||
===================================================================
|
|
||||||
--- vdr-1.7.27.orig/device.h 2012-03-13 11:17:16.000000000 +0100
|
|
||||||
+++ vdr-1.7.27/device.h 2012-03-25 14:18:05.434975038 +0200
|
|
||||||
@@ -405,6 +405,13 @@
|
|
||||||
public:
|
|
||||||
virtual bool HasCi(void);
|
|
||||||
///< Returns true if this device has a Common Interface.
|
|
||||||
+#define INTERNAL_CAM_DEVICES_PATCH 1
|
|
||||||
+ virtual bool HasInternalCam(void) { return false; }
|
|
||||||
+ ///< Returns true if this device handles encrypted channels itself
|
|
||||||
+ ///< without VDR assistance. This can be e.g. when the device is a
|
|
||||||
+ ///< client that gets the stream from another VDR instance that has
|
|
||||||
+ ///< already decrypted the stream. In this case ProvidesChannel()
|
|
||||||
+ ///< shall check whether the channel can be decrypted.
|
|
||||||
void SetCamSlot(cCamSlot *CamSlot);
|
|
||||||
///< Sets the given CamSlot to be used with this device.
|
|
||||||
cCamSlot *CamSlot(void) const { return camSlot; }
|
|
@ -1,114 +0,0 @@
|
|||||||
diff --git a/device.h b/device.h
|
|
||||||
index e61edd0..dc2ea5f 100644
|
|
||||||
--- a/device.h
|
|
||||||
+++ b/device.h
|
|
||||||
@@ -24,6 +24,8 @@
|
|
||||||
#include "spu.h"
|
|
||||||
#include "thread.h"
|
|
||||||
#include "tools.h"
|
|
||||||
+#include <asm/types.h>
|
|
||||||
+#include <linux/dvb/frontend.h>
|
|
||||||
|
|
||||||
#define MAXDEVICES 16 // the maximum number of devices in the system
|
|
||||||
#define MAXPIDHANDLES 64 // the maximum number of different PIDs per device
|
|
||||||
@@ -331,7 +333,7 @@ public:
|
|
||||||
virtual bool HasProgramme(void);
|
|
||||||
///< Returns true if the device is currently showing any programme to
|
|
||||||
///< the user, either through replaying or live.
|
|
||||||
-
|
|
||||||
+ virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd) {return false;}
|
|
||||||
// PID handle facilities
|
|
||||||
|
|
||||||
private:
|
|
||||||
diff --git a/dvbdevice.c b/dvbdevice.c
|
|
||||||
index 65e9a4b..53a4a22 100644
|
|
||||||
--- a/dvbdevice.c
|
|
||||||
+++ b/dvbdevice.c
|
|
||||||
@@ -285,6 +285,7 @@ class cDvbTuner : public cThread {
|
|
||||||
private:
|
|
||||||
static cMutex bondMutex;
|
|
||||||
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
|
|
||||||
+ bool SendDiseqc;
|
|
||||||
const cDvbDevice *device;
|
|
||||||
int fd_frontend;
|
|
||||||
int adapter, frontend;
|
|
||||||
@@ -300,6 +301,7 @@ private:
|
|
||||||
cMutex mutex;
|
|
||||||
cCondVar locked;
|
|
||||||
cCondVar newSet;
|
|
||||||
+ dvb_diseqc_master_cmd diseqc_cmd;
|
|
||||||
cDvbTuner *bondedTuner;
|
|
||||||
bool bondedMaster;
|
|
||||||
bool bondedMasterFailed;
|
|
||||||
@@ -322,6 +324,7 @@ public:
|
|
||||||
uint32_t SubsystemId(void) const { return subsystemId; }
|
|
||||||
bool IsTunedTo(const cChannel *Channel) const;
|
|
||||||
void SetChannel(const cChannel *Channel);
|
|
||||||
+ bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd);
|
|
||||||
bool Locked(int TimeoutMs = 0);
|
|
||||||
int GetSignalStrength(void) const;
|
|
||||||
int GetSignalQuality(void) const;
|
|
||||||
@@ -333,6 +336,7 @@ cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int
|
|
||||||
{
|
|
||||||
device = Device;
|
|
||||||
fd_frontend = Fd_Frontend;
|
|
||||||
+ SendDiseqc=false;
|
|
||||||
adapter = Adapter;
|
|
||||||
frontend = Frontend;
|
|
||||||
subsystemId = cDvbDeviceProbe::GetSubsystemId(adapter, frontend);
|
|
||||||
@@ -860,6 +864,10 @@ void cDvbTuner::Action(void)
|
|
||||||
Status = NewStatus;
|
|
||||||
cMutexLock MutexLock(&mutex);
|
|
||||||
int WaitTime = 1000;
|
|
||||||
+ if (SendDiseqc) {
|
|
||||||
+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &diseqc_cmd));
|
|
||||||
+ SendDiseqc=false;
|
|
||||||
+ }
|
|
||||||
switch (tunerStatus) {
|
|
||||||
case tsIdle:
|
|
||||||
break;
|
|
||||||
@@ -913,6 +921,20 @@ void cDvbTuner::Action(void)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+bool cDvbTuner::SendDiseqcCmd(dvb_diseqc_master_cmd cmd)
|
|
||||||
+{
|
|
||||||
+ cMutexLock MutexLock(&mutex);
|
|
||||||
+ cDvbTransponderParameters dtp(channel.Parameters());
|
|
||||||
+ // Determine the required frontend type:
|
|
||||||
+ int frontendType = GetRequiredDeliverySystem(&channel, &dtp);
|
|
||||||
+ if ((frontendType!=SYS_DVBS2 && frontendType!=SYS_DVBS) || SendDiseqc)
|
|
||||||
+ return false;
|
|
||||||
+ diseqc_cmd=cmd;
|
|
||||||
+ SendDiseqc=true;
|
|
||||||
+ newSet.Broadcast();
|
|
||||||
+ return true;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
// --- cDvbSourceParam -------------------------------------------------------
|
|
||||||
|
|
||||||
class cDvbSourceParam : public cSourceParam {
|
|
||||||
@@ -1534,6 +1556,11 @@ bool cDvbDevice::HasLock(int TimeoutMs)
|
|
||||||
return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
+bool cDvbDevice::SendDiseqcCmd(dvb_diseqc_master_cmd cmd)
|
|
||||||
+{
|
|
||||||
+ return dvbTuner->SendDiseqcCmd(cmd);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void cDvbDevice::SetTransferModeForDolbyDigital(int Mode)
|
|
||||||
{
|
|
||||||
setTransferModeForDolbyDigital = Mode;
|
|
||||||
diff --git a/dvbdevice.h b/dvbdevice.h
|
|
||||||
index c53a208..4ffcb91 100644
|
|
||||||
--- a/dvbdevice.h
|
|
||||||
+++ b/dvbdevice.h
|
|
||||||
@@ -192,6 +192,7 @@ protected:
|
|
||||||
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
|
|
||||||
public:
|
|
||||||
virtual bool HasLock(int TimeoutMs = 0);
|
|
||||||
+ virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd);
|
|
||||||
|
|
||||||
// PID handle facilities
|
|
||||||
|
|
@ -1,258 +0,0 @@
|
|||||||
Description: Patch for VDR to support external CI devices
|
|
||||||
Origin: https://github.com/flensrocker/vdr-plugin-dynamite
|
|
||||||
Forwarded: no
|
|
||||||
Author: Lars Hanisch <dvb@flensrocker.de>
|
|
||||||
Index: vdr-1.7.27/ci.h
|
|
||||||
===================================================================
|
|
||||||
--- vdr-1.7.27.orig/ci.h 2012-03-25 14:47:30.464975099 +0200
|
|
||||||
+++ vdr-1.7.27/ci.h 2012-03-25 14:51:11.824975107 +0200
|
|
||||||
@@ -72,6 +72,7 @@
|
|
||||||
};
|
|
||||||
|
|
||||||
class cDevice;
|
|
||||||
+class cTSBufferBase;
|
|
||||||
class cCamSlot;
|
|
||||||
|
|
||||||
enum eModuleStatus { msNone, msReset, msPresent, msReady };
|
|
||||||
@@ -115,6 +116,11 @@
|
|
||||||
///< The derived class must call Cancel(3) in its destructor.
|
|
||||||
virtual bool Ready(void);
|
|
||||||
///< Returns 'true' if all present CAMs in this adapter are ready.
|
|
||||||
+#define EXTERNALCI_PATCH
|
|
||||||
+ virtual cTSBufferBase *GetTSBuffer(int FdDvr) { return NULL; }
|
|
||||||
+ ///< Derived classes can return a special TS buffer with features
|
|
||||||
+ ///< like rerouting the stream through an external ci.
|
|
||||||
+ ///< The caller must delete the buffer.
|
|
||||||
virtual bool SetIdle(bool Idle, bool TestOnly) { return false; }
|
|
||||||
virtual bool IsIdle(void) const { return false; }
|
|
||||||
};
|
|
||||||
Index: vdr-1.7.27/device.h
|
|
||||||
===================================================================
|
|
||||||
--- vdr-1.7.27.orig/device.h 2012-03-25 14:47:30.474975099 +0200
|
|
||||||
+++ vdr-1.7.27/device.h 2012-03-25 14:51:11.824975107 +0200
|
|
||||||
@@ -795,7 +795,14 @@
|
|
||||||
/// sure the returned data points to a TS packet and automatically
|
|
||||||
/// re-synchronizes after broken packets.
|
|
||||||
|
|
||||||
-class cTSBuffer : public cThread {
|
|
||||||
+class cTSBufferBase {
|
|
||||||
+public:
|
|
||||||
+ cTSBufferBase() {}
|
|
||||||
+ virtual ~cTSBufferBase() {}
|
|
||||||
+ virtual uchar *Get(void) = 0;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+class cTSBuffer : public cTSBufferBase, public cThread {
|
|
||||||
private:
|
|
||||||
int f;
|
|
||||||
int cardIndex;
|
|
||||||
@@ -804,8 +811,8 @@
|
|
||||||
virtual void Action(void);
|
|
||||||
public:
|
|
||||||
cTSBuffer(int File, int Size, int CardIndex);
|
|
||||||
- ~cTSBuffer();
|
|
||||||
- uchar *Get(void);
|
|
||||||
+ virtual ~cTSBuffer();
|
|
||||||
+ virtual uchar *Get(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A plugin that want to create devices handled by the dynamite-plugin needs to create
|
|
||||||
Index: vdr-1.7.27/dvbci.c
|
|
||||||
===================================================================
|
|
||||||
--- vdr-1.7.27.orig/dvbci.c 2012-03-25 14:47:30.474975099 +0200
|
|
||||||
+++ vdr-1.7.27/dvbci.c 2012-03-25 14:51:11.824975107 +0200
|
|
||||||
@@ -22,23 +22,8 @@
|
|
||||||
adapter = Adapter;
|
|
||||||
frontend = Frontend;
|
|
||||||
idle = false;
|
|
||||||
- ca_caps_t Caps;
|
|
||||||
- if (ioctl(fd, CA_GET_CAP, &Caps) == 0) {
|
|
||||||
- if ((Caps.slot_type & CA_CI_LINK) != 0) {
|
|
||||||
- int NumSlots = Caps.slot_num;
|
|
||||||
- if (NumSlots > 0) {
|
|
||||||
- for (int i = 0; i < NumSlots; i++)
|
|
||||||
- new cCamSlot(this);
|
|
||||||
- Start();
|
|
||||||
- }
|
|
||||||
- else
|
|
||||||
- esyslog("ERROR: no CAM slots found on device %d", device->DeviceNumber());
|
|
||||||
- }
|
|
||||||
- else
|
|
||||||
- isyslog("device %d doesn't support CI link layer interface", device->DeviceNumber());
|
|
||||||
- }
|
|
||||||
- else
|
|
||||||
- esyslog("ERROR: can't get CA capabilities on device %d", device->DeviceNumber());
|
|
||||||
+ GetNumCamSlots(Device, Fd, this);
|
|
||||||
+ Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
cDvbCiAdapter::~cDvbCiAdapter()
|
|
||||||
@@ -48,6 +33,13 @@
|
|
||||||
CloseCa();
|
|
||||||
}
|
|
||||||
|
|
||||||
+cTSBufferBase *cDvbCiAdapter::GetTSBuffer(int FdDvr)
|
|
||||||
+{
|
|
||||||
+ if (device)
|
|
||||||
+ return new cTSBuffer(FdDvr, MEGABYTE(2), device->CardIndex() + 1);
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
bool cDvbCiAdapter::OpenCa(void)
|
|
||||||
{
|
|
||||||
if (fd >= 0)
|
|
||||||
@@ -142,10 +134,60 @@
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
+int cDvbCiAdapter::GetNumCamSlots(cDevice *Device, int Fd, cCiAdapter *CiAdapter)
|
|
||||||
+{
|
|
||||||
+ int NumSlots = -1;
|
|
||||||
+ if (Fd >= 0) {
|
|
||||||
+ ca_caps_t Caps;
|
|
||||||
+ if (ioctl(Fd, CA_GET_CAP, &Caps) == 0) {
|
|
||||||
+ if ((Caps.slot_type & CA_CI_LINK) != 0) {
|
|
||||||
+ NumSlots = Caps.slot_num;
|
|
||||||
+ if (NumSlots == 0)
|
|
||||||
+ esyslog("ERROR: no CAM slots found on device %d", Device->DeviceNumber());
|
|
||||||
+ else if (CiAdapter != NULL) {
|
|
||||||
+ for (int i = 0; i < NumSlots; i++)
|
|
||||||
+ new cCamSlot(CiAdapter);
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ return NumSlots;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ isyslog("device %d doesn't support CI link layer interface", Device->DeviceNumber());
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ esyslog("ERROR: can't get CA capabilities on device %d", Device->DeviceNumber());
|
|
||||||
+ }
|
|
||||||
+ return -1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
cDvbCiAdapter *cDvbCiAdapter::CreateCiAdapter(cDevice *Device, int Fd, int Adapter, int Frontend)
|
|
||||||
{
|
|
||||||
- // TODO check whether a CI is actually present?
|
|
||||||
- if (Device)
|
|
||||||
+ // don't create a ci-adapter if it's not useable
|
|
||||||
+ if (Device && (Fd >= 0) && (GetNumCamSlots(Device, Fd, NULL) > 0))
|
|
||||||
return new cDvbCiAdapter(Device, Fd, Adapter, Frontend);
|
|
||||||
- return NULL;
|
|
||||||
+
|
|
||||||
+ if (Fd >= 0)
|
|
||||||
+ close(Fd);
|
|
||||||
+
|
|
||||||
+ // try to find an external ci-adapter
|
|
||||||
+ for (cDvbCiAdapterProbe *cp = DvbCiAdapterProbes.First(); cp; cp = DvbCiAdapterProbes.Next(cp)) {
|
|
||||||
+ cDvbCiAdapter *ca = cp->Probe(Device);
|
|
||||||
+ if (ca)
|
|
||||||
+ return ca;
|
|
||||||
+ }
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+// --- cDvbCiAdapterProbe -------------------------------------------------------
|
|
||||||
+
|
|
||||||
+cList<cDvbCiAdapterProbe> DvbCiAdapterProbes;
|
|
||||||
+
|
|
||||||
+cDvbCiAdapterProbe::cDvbCiAdapterProbe(void)
|
|
||||||
+{
|
|
||||||
+ DvbCiAdapterProbes.Add(this);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+cDvbCiAdapterProbe::~cDvbCiAdapterProbe()
|
|
||||||
+{
|
|
||||||
+ DvbCiAdapterProbes.Del(this, false);
|
|
||||||
}
|
|
||||||
Index: vdr-1.7.27/dvbci.h
|
|
||||||
===================================================================
|
|
||||||
--- vdr-1.7.27.orig/dvbci.h 2012-03-25 14:47:30.474975099 +0200
|
|
||||||
+++ vdr-1.7.27/dvbci.h 2012-03-25 14:51:11.824975107 +0200
|
|
||||||
@@ -31,9 +31,33 @@
|
|
||||||
cDvbCiAdapter(cDevice *Device, int Fd, int Adapter = -1, int Frontend = -1);
|
|
||||||
public:
|
|
||||||
virtual ~cDvbCiAdapter();
|
|
||||||
+ virtual cTSBufferBase *GetTSBuffer(int FdDvr);
|
|
||||||
+ static int GetNumCamSlots(cDevice *Device, int Fd, cCiAdapter *CiAdapter);
|
|
||||||
+ ///< Tests if the CA device is usable for vdr.
|
|
||||||
+ ///< If CiAdapter is not NULL it will create the CamSlots for the given ci-adapter.
|
|
||||||
virtual bool SetIdle(bool Idle, bool TestOnly);
|
|
||||||
virtual bool IsIdle(void) const { return idle; }
|
|
||||||
static cDvbCiAdapter *CreateCiAdapter(cDevice *Device, int Fd, int Adapter = -1, int Frontend = -1);
|
|
||||||
};
|
|
||||||
|
|
||||||
+// A plugin that implements an external DVB ci-adapter derived from cDvbCiAdapter needs to create
|
|
||||||
+// a cDvbCiAdapterProbe derived object on the heap in order to have its Probe()
|
|
||||||
+// function called, where it can actually create the appropriate ci-adapter.
|
|
||||||
+// The cDvbCiAdapterProbe object must be created in the plugin's constructor,
|
|
||||||
+// and deleted in its destructor.
|
|
||||||
+// Every plugin has to track its own list of already used device nodes.
|
|
||||||
+// The Probes are always called if the base cDvbCiAdapter can't create a ci-adapter on its own.
|
|
||||||
+
|
|
||||||
+class cDvbCiAdapterProbe : public cListObject {
|
|
||||||
+public:
|
|
||||||
+ cDvbCiAdapterProbe(void);
|
|
||||||
+ virtual ~cDvbCiAdapterProbe();
|
|
||||||
+ virtual cDvbCiAdapter *Probe(cDevice *Device) = 0;
|
|
||||||
+ ///< Probes for a DVB ci-adapter for the given Device and creates the appropriate
|
|
||||||
+ ///< object derived from cDvbCiAdapter if applicable.
|
|
||||||
+ ///< Returns NULL if no adapter has been created.
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+extern cList<cDvbCiAdapterProbe> DvbCiAdapterProbes;
|
|
||||||
+
|
|
||||||
#endif //__DVBCI_H
|
|
||||||
Index: vdr-1.7.27/dvbdevice.c
|
|
||||||
===================================================================
|
|
||||||
--- vdr-1.7.27.orig/dvbdevice.c 2012-03-25 14:47:30.474975099 +0200
|
|
||||||
+++ vdr-1.7.27/dvbdevice.c 2012-03-25 14:51:11.824975107 +0200
|
|
||||||
@@ -1106,9 +1106,8 @@
|
|
||||||
|
|
||||||
// Common Interface:
|
|
||||||
|
|
||||||
- fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR);
|
|
||||||
- if (fd_ca >= 0)
|
|
||||||
- ciAdapter = cDvbCiAdapter::CreateCiAdapter(parentDevice ? parentDevice : this, fd_ca, adapter, frontend);
|
|
||||||
+ int fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR);
|
|
||||||
+ ciAdapter = cDvbCiAdapter::CreateCiAdapter(parentDevice ? parentDevice : this, fd_ca, adapter, frontend);
|
|
||||||
|
|
||||||
// The DVR device (will be opened and closed as needed):
|
|
||||||
|
|
||||||
@@ -1665,8 +1664,12 @@
|
|
||||||
{
|
|
||||||
CloseDvr();
|
|
||||||
fd_dvr = DvbOpen(DEV_DVB_DVR, adapter, frontend, O_RDONLY | O_NONBLOCK, true);
|
|
||||||
- if (fd_dvr >= 0)
|
|
||||||
- tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(2), CardIndex() + 1);
|
|
||||||
+ if (fd_dvr >= 0) {
|
|
||||||
+ if (ciAdapter)
|
|
||||||
+ tsBuffer = ciAdapter->GetTSBuffer(fd_dvr);
|
|
||||||
+ if (tsBuffer == NULL)
|
|
||||||
+ tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(2), CardIndex() + 1);
|
|
||||||
+ }
|
|
||||||
return fd_dvr >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Index: vdr-1.7.27/dvbdevice.h
|
|
||||||
===================================================================
|
|
||||||
--- vdr-1.7.27.orig/dvbdevice.h 2012-03-25 14:50:28.174975106 +0200
|
|
||||||
+++ vdr-1.7.27/dvbdevice.h 2012-03-25 14:51:11.824975107 +0200
|
|
||||||
@@ -127,7 +127,7 @@
|
|
||||||
int deliverySystems[MAXDELIVERYSYSTEMS];
|
|
||||||
int numDeliverySystems;
|
|
||||||
int numModulations;
|
|
||||||
- int fd_dvr, fd_ca;
|
|
||||||
+ int fd_dvr;
|
|
||||||
static cMutex bondMutex;
|
|
||||||
cDvbDevice *bondedDevice;
|
|
||||||
mutable bool needsDetachBondedReceivers;
|
|
||||||
@@ -227,7 +227,7 @@
|
|
||||||
// Receiver facilities
|
|
||||||
|
|
||||||
private:
|
|
||||||
- cTSBuffer *tsBuffer;
|
|
||||||
+ cTSBufferBase *tsBuffer;
|
|
||||||
protected:
|
|
||||||
virtual bool OpenDvr(void);
|
|
||||||
virtual void CloseDvr(void);
|
|
@ -1,16 +0,0 @@
|
|||||||
diff --git a/dvbdevice.c b/dvbdevice.c
|
|
||||||
index 42ec5b1..9c397d7 100644
|
|
||||||
--- a/dvbdevice.c
|
|
||||||
+++ b/dvbdevice.c
|
|
||||||
@@ -839,7 +839,11 @@ bool cDvbTuner::SetFrontend(void)
|
|
||||||
SETCMD(DTV_HIERARCHY, dtp.Hierarchy());
|
|
||||||
if (frontendType == SYS_DVBT2) {
|
|
||||||
// DVB-T2
|
|
||||||
+#ifdef DTV_DVBT2_PLP_ID
|
|
||||||
SETCMD(DTV_DVBT2_PLP_ID, dtp.PlpId());
|
|
||||||
+#else
|
|
||||||
+ SETCMD(DTV_DVBT2_PLP_ID_LEGACY, dtp.PlpId());
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
tuneTimeout = DVBT_TUNE_TIMEOUT;
|
|
@ -1,21 +1,5 @@
|
|||||||
From a13c75ec46f2783b2d258af48d7de28d44666715 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Saraev <stefan@saraev.ca>
|
|
||||||
Date: Sat, 5 May 2012 21:50:48 +0300
|
|
||||||
Subject: [PATCH 2/2] dynamite
|
|
||||||
|
|
||||||
---
|
|
||||||
ci.c | 2 +
|
|
||||||
ci.h | 2 +
|
|
||||||
device.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
|
|
||||||
device.h | 85 ++++++++++++++++++++++++++++++++++++-----
|
|
||||||
dvbci.c | 51 +++++++++++++++++++++++--
|
|
||||||
dvbci.h | 12 +++++-
|
|
||||||
dvbdevice.c | 95 ++++++++++++++++++++++++++++++++++++++++++----
|
|
||||||
dvbdevice.h | 6 ++-
|
|
||||||
8 files changed, 339 insertions(+), 35 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ci.c b/ci.c
|
diff --git a/ci.c b/ci.c
|
||||||
index 0135d07..cf21952 100644
|
index 904697e..1e95313 100644
|
||||||
--- a/ci.c
|
--- a/ci.c
|
||||||
+++ b/ci.c
|
+++ b/ci.c
|
||||||
@@ -1571,6 +1571,8 @@ cCamSlot::cCamSlot(cCiAdapter *CiAdapter)
|
@@ -1571,6 +1571,8 @@ cCamSlot::cCamSlot(cCiAdapter *CiAdapter)
|
||||||
@ -28,29 +12,43 @@ index 0135d07..cf21952 100644
|
|||||||
DeleteAllConnections();
|
DeleteAllConnections();
|
||||||
}
|
}
|
||||||
diff --git a/ci.h b/ci.h
|
diff --git a/ci.h b/ci.h
|
||||||
index 74e0270..d38e2dd 100644
|
index 74e0270..818ea29 100644
|
||||||
--- a/ci.h
|
--- a/ci.h
|
||||||
+++ b/ci.h
|
+++ b/ci.h
|
||||||
@@ -115,6 +115,8 @@ public:
|
@@ -72,6 +72,7 @@ public:
|
||||||
|
};
|
||||||
|
|
||||||
|
class cDevice;
|
||||||
|
+class cTSBufferBase;
|
||||||
|
class cCamSlot;
|
||||||
|
|
||||||
|
enum eModuleStatus { msNone, msReset, msPresent, msReady };
|
||||||
|
@@ -115,6 +116,13 @@ public:
|
||||||
///< The derived class must call Cancel(3) in its destructor.
|
///< The derived class must call Cancel(3) in its destructor.
|
||||||
virtual bool Ready(void);
|
virtual bool Ready(void);
|
||||||
///< Returns 'true' if all present CAMs in this adapter are ready.
|
///< Returns 'true' if all present CAMs in this adapter are ready.
|
||||||
|
+#define EXTERNALCI_PATCH
|
||||||
|
+ virtual cTSBufferBase *GetTSBuffer(int FdDvr) { return NULL; }
|
||||||
|
+ ///< Derived classes can return a special TS buffer with features
|
||||||
|
+ ///< like rerouting the stream through an external ci.
|
||||||
|
+ ///< The caller must delete the buffer.
|
||||||
+ virtual bool SetIdle(bool Idle, bool TestOnly) { return false; }
|
+ virtual bool SetIdle(bool Idle, bool TestOnly) { return false; }
|
||||||
+ virtual bool IsIdle(void) const { return false; }
|
+ virtual bool IsIdle(void) const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class cTPDU;
|
class cTPDU;
|
||||||
diff --git a/device.c b/device.c
|
diff --git a/device.c b/device.c
|
||||||
index 273757e..f83e789 100644
|
index 2678d68..56c2b9c 100644
|
||||||
--- a/device.c
|
--- a/device.c
|
||||||
+++ b/device.c
|
+++ b/device.c
|
||||||
@@ -69,12 +69,22 @@ int cDevice::currentChannel = 1;
|
@@ -69,12 +69,22 @@ int cDevice::currentChannel = 1;
|
||||||
cDevice *cDevice::device[MAXDEVICES] = { NULL };
|
cDevice *cDevice::device[MAXDEVICES] = { NULL };
|
||||||
cDevice *cDevice::primaryDevice = NULL;
|
cDevice *cDevice::primaryDevice = NULL;
|
||||||
cList<cDeviceHook> cDevice::deviceHooks;
|
cList<cDeviceHook> cDevice::deviceHooks;
|
||||||
+cDevice *cDevice::nextParentDevice = NULL;
|
-
|
||||||
|
|
||||||
-cDevice::cDevice(void)
|
-cDevice::cDevice(void)
|
||||||
|
+cDevice *cDevice::nextParentDevice = NULL;
|
||||||
|
+
|
||||||
+cDevice::cDevice(cDevice *ParentDevice)
|
+cDevice::cDevice(cDevice *ParentDevice)
|
||||||
:patPmtParser(true)
|
:patPmtParser(true)
|
||||||
-{
|
-{
|
||||||
@ -128,7 +126,7 @@ index 273757e..f83e789 100644
|
|||||||
for (int i = 0; i < numDevices; i++) {
|
for (int i = 0; i < numDevices; i++) {
|
||||||
if (device[i] == this)
|
if (device[i] == this)
|
||||||
return i;
|
return i;
|
||||||
@@ -349,6 +388,8 @@ bool cDevice::HasCi(void)
|
@@ -355,6 +394,8 @@ bool cDevice::HasCi(void)
|
||||||
|
|
||||||
void cDevice::SetCamSlot(cCamSlot *CamSlot)
|
void cDevice::SetCamSlot(cCamSlot *CamSlot)
|
||||||
{
|
{
|
||||||
@ -137,7 +135,7 @@ index 273757e..f83e789 100644
|
|||||||
camSlot = CamSlot;
|
camSlot = CamSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,6 +602,10 @@ void cDevice::DelLivePids(void)
|
@@ -567,6 +608,10 @@ void cDevice::DelLivePids(void)
|
||||||
|
|
||||||
void cDevice::StartSectionHandler(void)
|
void cDevice::StartSectionHandler(void)
|
||||||
{
|
{
|
||||||
@ -148,7 +146,7 @@ index 273757e..f83e789 100644
|
|||||||
if (!sectionHandler) {
|
if (!sectionHandler) {
|
||||||
sectionHandler = new cSectionHandler(this);
|
sectionHandler = new cSectionHandler(this);
|
||||||
AttachFilter(eitFilter = new cEitFilter);
|
AttachFilter(eitFilter = new cEitFilter);
|
||||||
@@ -572,6 +617,10 @@ void cDevice::StartSectionHandler(void)
|
@@ -578,6 +623,10 @@ void cDevice::StartSectionHandler(void)
|
||||||
|
|
||||||
void cDevice::StopSectionHandler(void)
|
void cDevice::StopSectionHandler(void)
|
||||||
{
|
{
|
||||||
@ -159,7 +157,7 @@ index 273757e..f83e789 100644
|
|||||||
if (sectionHandler) {
|
if (sectionHandler) {
|
||||||
delete nitFilter;
|
delete nitFilter;
|
||||||
delete sdtFilter;
|
delete sdtFilter;
|
||||||
@@ -598,12 +647,17 @@ void cDevice::CloseFilter(int Handle)
|
@@ -609,12 +658,17 @@ void cDevice::CloseFilter(int Handle)
|
||||||
|
|
||||||
void cDevice::AttachFilter(cFilter *Filter)
|
void cDevice::AttachFilter(cFilter *Filter)
|
||||||
{
|
{
|
||||||
@ -177,7 +175,7 @@ index 273757e..f83e789 100644
|
|||||||
if (sectionHandler)
|
if (sectionHandler)
|
||||||
sectionHandler->Detach(Filter);
|
sectionHandler->Detach(Filter);
|
||||||
}
|
}
|
||||||
@@ -765,6 +819,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
@@ -776,6 +830,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
||||||
sectionHandler->SetStatus(false);
|
sectionHandler->SetStatus(false);
|
||||||
sectionHandler->SetChannel(NULL);
|
sectionHandler->SetChannel(NULL);
|
||||||
}
|
}
|
||||||
@ -185,7 +183,7 @@ index 273757e..f83e789 100644
|
|||||||
// Tell the camSlot about the channel switch and add all PIDs of this
|
// Tell the camSlot about the channel switch and add all PIDs of this
|
||||||
// channel to it, for possible later decryption:
|
// channel to it, for possible later decryption:
|
||||||
if (camSlot)
|
if (camSlot)
|
||||||
@@ -811,19 +866,27 @@ void cDevice::ForceTransferMode(void)
|
@@ -822,19 +877,27 @@ void cDevice::ForceTransferMode(void)
|
||||||
{
|
{
|
||||||
if (!cTransferControl::ReceiverDevice()) {
|
if (!cTransferControl::ReceiverDevice()) {
|
||||||
cChannel *Channel = Channels.GetByNumber(CurrentChannel());
|
cChannel *Channel = Channels.GetByNumber(CurrentChannel());
|
||||||
@ -214,7 +212,7 @@ index 273757e..f83e789 100644
|
|||||||
if (Seconds >= 0)
|
if (Seconds >= 0)
|
||||||
occupiedTimeout = time(NULL) + min(Seconds, MAXOCCUPIEDTIMEOUT);
|
occupiedTimeout = time(NULL) + min(Seconds, MAXOCCUPIEDTIMEOUT);
|
||||||
}
|
}
|
||||||
@@ -1196,7 +1259,10 @@ bool cDevice::Transferring(void) const
|
@@ -1209,7 +1272,10 @@ bool cDevice::Transferring(void) const
|
||||||
|
|
||||||
bool cDevice::AttachPlayer(cPlayer *Player)
|
bool cDevice::AttachPlayer(cPlayer *Player)
|
||||||
{
|
{
|
||||||
@ -225,7 +223,7 @@ index 273757e..f83e789 100644
|
|||||||
if (player)
|
if (player)
|
||||||
Detach(player);
|
Detach(player);
|
||||||
DELETENULL(liveSubtitle);
|
DELETENULL(liveSubtitle);
|
||||||
@@ -1215,6 +1281,8 @@ bool cDevice::AttachPlayer(cPlayer *Player)
|
@@ -1228,6 +1294,8 @@ bool cDevice::AttachPlayer(cPlayer *Player)
|
||||||
|
|
||||||
void cDevice::Detach(cPlayer *Player)
|
void cDevice::Detach(cPlayer *Player)
|
||||||
{
|
{
|
||||||
@ -234,7 +232,7 @@ index 273757e..f83e789 100644
|
|||||||
if (Player && player == Player) {
|
if (Player && player == Player) {
|
||||||
cPlayer *p = player;
|
cPlayer *p = player;
|
||||||
player = NULL; // avoids recursive calls to Detach()
|
player = NULL; // avoids recursive calls to Detach()
|
||||||
@@ -1234,6 +1302,8 @@ void cDevice::Detach(cPlayer *Player)
|
@@ -1247,6 +1315,8 @@ void cDevice::Detach(cPlayer *Player)
|
||||||
|
|
||||||
void cDevice::StopReplay(void)
|
void cDevice::StopReplay(void)
|
||||||
{
|
{
|
||||||
@ -243,7 +241,7 @@ index 273757e..f83e789 100644
|
|||||||
if (player) {
|
if (player) {
|
||||||
Detach(player);
|
Detach(player);
|
||||||
if (IsPrimaryDevice())
|
if (IsPrimaryDevice())
|
||||||
@@ -1516,6 +1586,8 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
@@ -1529,6 +1599,8 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
||||||
|
|
||||||
int cDevice::Priority(void) const
|
int cDevice::Priority(void) const
|
||||||
{
|
{
|
||||||
@ -252,7 +250,7 @@ index 273757e..f83e789 100644
|
|||||||
int priority = IDLEPRIORITY;
|
int priority = IDLEPRIORITY;
|
||||||
if (IsPrimaryDevice() && !Replaying() && ActualDevice() == PrimaryDevice())
|
if (IsPrimaryDevice() && !Replaying() && ActualDevice() == PrimaryDevice())
|
||||||
priority = TRANSFERPRIORITY; // we use the same value here, no matter whether it's actual Transfer Mode or real live viewing
|
priority = TRANSFERPRIORITY; // we use the same value here, no matter whether it's actual Transfer Mode or real live viewing
|
||||||
@@ -1534,6 +1606,8 @@ bool cDevice::Ready(void)
|
@@ -1547,6 +1619,8 @@ bool cDevice::Ready(void)
|
||||||
|
|
||||||
bool cDevice::Receiving(bool Dummy) const
|
bool cDevice::Receiving(bool Dummy) const
|
||||||
{
|
{
|
||||||
@ -261,7 +259,7 @@ index 273757e..f83e789 100644
|
|||||||
cMutexLock MutexLock(&mutexReceiver);
|
cMutexLock MutexLock(&mutexReceiver);
|
||||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||||
if (receiver[i])
|
if (receiver[i])
|
||||||
@@ -1614,10 +1688,13 @@ bool cDevice::GetTSPacket(uchar *&Data)
|
@@ -1627,10 +1701,13 @@ bool cDevice::GetTSPacket(uchar *&Data)
|
||||||
|
|
||||||
bool cDevice::AttachReceiver(cReceiver *Receiver)
|
bool cDevice::AttachReceiver(cReceiver *Receiver)
|
||||||
{
|
{
|
||||||
@ -275,7 +273,7 @@ index 273757e..f83e789 100644
|
|||||||
// activate the following line if you need it - actually the driver should be fixed!
|
// activate the following line if you need it - actually the driver should be fixed!
|
||||||
//#define WAIT_FOR_TUNER_LOCK
|
//#define WAIT_FOR_TUNER_LOCK
|
||||||
#ifdef WAIT_FOR_TUNER_LOCK
|
#ifdef WAIT_FOR_TUNER_LOCK
|
||||||
@@ -1656,6 +1733,8 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
|
@@ -1669,6 +1746,8 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
|
||||||
|
|
||||||
void cDevice::Detach(cReceiver *Receiver)
|
void cDevice::Detach(cReceiver *Receiver)
|
||||||
{
|
{
|
||||||
@ -284,7 +282,7 @@ index 273757e..f83e789 100644
|
|||||||
if (!Receiver || Receiver->device != this)
|
if (!Receiver || Receiver->device != this)
|
||||||
return;
|
return;
|
||||||
bool receiversLeft = false;
|
bool receiversLeft = false;
|
||||||
@@ -1681,6 +1760,8 @@ void cDevice::Detach(cReceiver *Receiver)
|
@@ -1694,6 +1773,8 @@ void cDevice::Detach(cReceiver *Receiver)
|
||||||
|
|
||||||
void cDevice::DetachAll(int Pid)
|
void cDevice::DetachAll(int Pid)
|
||||||
{
|
{
|
||||||
@ -293,7 +291,7 @@ index 273757e..f83e789 100644
|
|||||||
if (Pid) {
|
if (Pid) {
|
||||||
cMutexLock MutexLock(&mutexReceiver);
|
cMutexLock MutexLock(&mutexReceiver);
|
||||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||||
@@ -1693,6 +1774,8 @@ void cDevice::DetachAll(int Pid)
|
@@ -1706,6 +1787,8 @@ void cDevice::DetachAll(int Pid)
|
||||||
|
|
||||||
void cDevice::DetachAllReceivers(void)
|
void cDevice::DetachAllReceivers(void)
|
||||||
{
|
{
|
||||||
@ -302,7 +300,7 @@ index 273757e..f83e789 100644
|
|||||||
cMutexLock MutexLock(&mutexReceiver);
|
cMutexLock MutexLock(&mutexReceiver);
|
||||||
for (int i = 0; i < MAXRECEIVERS; i++)
|
for (int i = 0; i < MAXRECEIVERS; i++)
|
||||||
Detach(receiver[i]);
|
Detach(receiver[i]);
|
||||||
@@ -1764,3 +1847,25 @@ uchar *cTSBuffer::Get(void)
|
@@ -1778,3 +1861,25 @@ uchar *cTSBuffer::Get(void)
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -329,10 +327,18 @@ index 273757e..f83e789 100644
|
|||||||
+ DynamicDeviceProbes.Del(this, false);
|
+ DynamicDeviceProbes.Del(this, false);
|
||||||
+}
|
+}
|
||||||
diff --git a/device.h b/device.h
|
diff --git a/device.h b/device.h
|
||||||
index dc2ea5f..e5e92a3 100644
|
index e2847d8..3a8aa01 100644
|
||||||
--- a/device.h
|
--- a/device.h
|
||||||
+++ b/device.h
|
+++ b/device.h
|
||||||
@@ -171,7 +171,6 @@ private:
|
@@ -24,6 +24,7 @@
|
||||||
|
#include "spu.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "tools.h"
|
||||||
|
+#include <linux/dvb/frontend.h>
|
||||||
|
|
||||||
|
#define MAXDEVICES 16 // the maximum number of devices in the system
|
||||||
|
#define MAXPIDHANDLES 64 // the maximum number of different PIDs per device
|
||||||
|
@@ -169,7 +170,6 @@ private:
|
||||||
static int nextCardIndex;
|
static int nextCardIndex;
|
||||||
int cardIndex;
|
int cardIndex;
|
||||||
protected:
|
protected:
|
||||||
@ -340,7 +346,7 @@ index dc2ea5f..e5e92a3 100644
|
|||||||
virtual ~cDevice();
|
virtual ~cDevice();
|
||||||
virtual bool Ready(void);
|
virtual bool Ready(void);
|
||||||
///< Returns true if this device is ready. Devices with conditional
|
///< Returns true if this device is ready. Devices with conditional
|
||||||
@@ -198,9 +197,6 @@ protected:
|
@@ -196,9 +196,6 @@ protected:
|
||||||
///< A derived class must call the MakePrimaryDevice() function of its
|
///< A derived class must call the MakePrimaryDevice() function of its
|
||||||
///< base class.
|
///< base class.
|
||||||
public:
|
public:
|
||||||
@ -349,8 +355,16 @@ index dc2ea5f..e5e92a3 100644
|
|||||||
- ///< Returns the card index of this device (0 ... MAXDEVICES - 1).
|
- ///< Returns the card index of this device (0 ... MAXDEVICES - 1).
|
||||||
int DeviceNumber(void) const;
|
int DeviceNumber(void) const;
|
||||||
///< Returns the number of this device (0 ... numDevices).
|
///< Returns the number of this device (0 ... numDevices).
|
||||||
virtual cString DeviceName(void) const;
|
virtual cString DeviceType(void) const;
|
||||||
@@ -416,9 +412,6 @@ public:
|
@@ -338,6 +335,7 @@ public:
|
||||||
|
///< Returns true if the device is currently showing any programme to
|
||||||
|
///< the user, either through replaying or live.
|
||||||
|
|
||||||
|
+ virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd) {return false;}
|
||||||
|
// PID handle facilities
|
||||||
|
|
||||||
|
private:
|
||||||
|
@@ -423,9 +421,6 @@ public:
|
||||||
///< shall check whether the channel can be decrypted.
|
///< shall check whether the channel can be decrypted.
|
||||||
void SetCamSlot(cCamSlot *CamSlot);
|
void SetCamSlot(cCamSlot *CamSlot);
|
||||||
///< Sets the given CamSlot to be used with this device.
|
///< Sets the given CamSlot to be used with this device.
|
||||||
@ -360,7 +374,7 @@ index dc2ea5f..e5e92a3 100644
|
|||||||
|
|
||||||
// Image Grab facilities
|
// Image Grab facilities
|
||||||
|
|
||||||
@@ -574,9 +567,6 @@ private:
|
@@ -581,9 +576,6 @@ private:
|
||||||
cTsToPes tsToPesSubtitle;
|
cTsToPes tsToPesSubtitle;
|
||||||
bool isPlayingVideo;
|
bool isPlayingVideo;
|
||||||
protected:
|
protected:
|
||||||
@ -370,11 +384,11 @@ index dc2ea5f..e5e92a3 100644
|
|||||||
virtual bool CanReplay(void) const;
|
virtual bool CanReplay(void) const;
|
||||||
///< Returns true if this device can currently start a replay session.
|
///< Returns true if this device can currently start a replay session.
|
||||||
virtual bool SetPlayMode(ePlayMode PlayMode);
|
virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||||
@@ -761,6 +751,38 @@ public:
|
@@ -795,6 +787,38 @@ public:
|
||||||
///< Detaches all receivers from this device for this pid.
|
///< Detaches all receivers from this device for this pid.
|
||||||
virtual void DetachAllReceivers(void);
|
virtual void DetachAllReceivers(void);
|
||||||
///< Detaches all receivers from this device.
|
///< Detaches all receivers from this device.
|
||||||
+
|
+
|
||||||
+// --- dynamite subdevice patch start ---
|
+// --- dynamite subdevice patch start ---
|
||||||
+ friend class cDynamicDevice;
|
+ friend class cDynamicDevice;
|
||||||
+private:
|
+private:
|
||||||
@ -409,10 +423,32 @@ index dc2ea5f..e5e92a3 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Derived cDevice classes that can receive channels will have to provide
|
/// Derived cDevice classes that can receive channels will have to provide
|
||||||
@@ -784,4 +806,47 @@ public:
|
@@ -805,7 +829,14 @@ public:
|
||||||
uchar *Get(void);
|
/// sure the returned data points to a TS packet and automatically
|
||||||
};
|
/// re-synchronizes after broken packets.
|
||||||
|
|
||||||
|
-class cTSBuffer : public cThread {
|
||||||
|
+class cTSBufferBase {
|
||||||
|
+public:
|
||||||
|
+ cTSBufferBase() {}
|
||||||
|
+ virtual ~cTSBufferBase() {}
|
||||||
|
+ virtual uchar *Get(void) = 0;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+class cTSBuffer : public cTSBufferBase, public cThread {
|
||||||
|
private:
|
||||||
|
int f;
|
||||||
|
int cardIndex;
|
||||||
|
@@ -814,8 +845,51 @@ private:
|
||||||
|
virtual void Action(void);
|
||||||
|
public:
|
||||||
|
cTSBuffer(int File, int Size, int CardIndex);
|
||||||
|
- ~cTSBuffer();
|
||||||
|
- uchar *Get(void);
|
||||||
|
+ virtual ~cTSBuffer();
|
||||||
|
+ virtual uchar *Get(void);
|
||||||
|
+ };
|
||||||
|
+
|
||||||
+/// A plugin that want to create devices handled by the dynamite-plugin needs to create
|
+/// 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()
|
+/// a cDynamicDeviceProbe derived object on the heap in order to have its Probe()
|
||||||
+/// function called, where it can actually create the appropriate device.
|
+/// function called, where it can actually create the appropriate device.
|
||||||
@ -452,16 +488,16 @@ index dc2ea5f..e5e92a3 100644
|
|||||||
+ ///< object derived from cDevice if applicable.
|
+ ///< object derived from cDevice if applicable.
|
||||||
+ ///< Returns the device that has been created or NULL if not.
|
+ ///< Returns the device that has been created or NULL if not.
|
||||||
+ ///< The dynamite-plugin will delete the device if it is detached.
|
+ ///< The dynamite-plugin will delete the device if it is detached.
|
||||||
+ };
|
};
|
||||||
+
|
|
||||||
+extern cList<cDynamicDeviceProbe> DynamicDeviceProbes;
|
+extern cList<cDynamicDeviceProbe> DynamicDeviceProbes;
|
||||||
+
|
+
|
||||||
#endif //__DEVICE_H
|
#endif //__DEVICE_H
|
||||||
diff --git a/dvbci.c b/dvbci.c
|
diff --git a/dvbci.c b/dvbci.c
|
||||||
index 5289bbd..fea3a83 100644
|
index 5289bbd..baa70bc 100644
|
||||||
--- a/dvbci.c
|
--- a/dvbci.c
|
||||||
+++ b/dvbci.c
|
+++ b/dvbci.c
|
||||||
@@ -10,15 +10,18 @@
|
@@ -10,41 +10,70 @@
|
||||||
#include "dvbci.h"
|
#include "dvbci.h"
|
||||||
#include <linux/dvb/ca.h>
|
#include <linux/dvb/ca.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@ -476,13 +512,30 @@ index 5289bbd..fea3a83 100644
|
|||||||
device = Device;
|
device = Device;
|
||||||
SetDescription("CI adapter on device %d", device->DeviceNumber());
|
SetDescription("CI adapter on device %d", device->DeviceNumber());
|
||||||
fd = Fd;
|
fd = Fd;
|
||||||
|
- ca_caps_t Caps;
|
||||||
|
- if (ioctl(fd, CA_GET_CAP, &Caps) == 0) {
|
||||||
|
- if ((Caps.slot_type & CA_CI_LINK) != 0) {
|
||||||
|
- int NumSlots = Caps.slot_num;
|
||||||
|
- if (NumSlots > 0) {
|
||||||
|
- for (int i = 0; i < NumSlots; i++)
|
||||||
|
- new cCamSlot(this);
|
||||||
|
- Start();
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- esyslog("ERROR: no CAM slots found on device %d", device->DeviceNumber());
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- isyslog("device %d doesn't support CI link layer interface", device->DeviceNumber());
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- esyslog("ERROR: can't get CA capabilities on device %d", device->DeviceNumber());
|
||||||
+ adapter = Adapter;
|
+ adapter = Adapter;
|
||||||
+ frontend = Frontend;
|
+ frontend = Frontend;
|
||||||
+ idle = false;
|
+ idle = false;
|
||||||
ca_caps_t Caps;
|
+ GetNumCamSlots(Device, Fd, this);
|
||||||
if (ioctl(fd, CA_GET_CAP, &Caps) == 0) {
|
+ Start();
|
||||||
if ((Caps.slot_type & CA_CI_LINK) != 0) {
|
}
|
||||||
@@ -41,10 +44,44 @@ cDvbCiAdapter::cDvbCiAdapter(cDevice *Device, int Fd)
|
|
||||||
cDvbCiAdapter::~cDvbCiAdapter()
|
cDvbCiAdapter::~cDvbCiAdapter()
|
||||||
{
|
{
|
||||||
Cancel(3);
|
Cancel(3);
|
||||||
@ -518,6 +571,13 @@ index 5289bbd..fea3a83 100644
|
|||||||
+ OpenCa();
|
+ OpenCa();
|
||||||
+ idle = Idle;
|
+ idle = Idle;
|
||||||
+ return true;
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+cTSBufferBase *cDvbCiAdapter::GetTSBuffer(int FdDvr)
|
||||||
|
+{
|
||||||
|
+ if (device)
|
||||||
|
+ return new cTSBuffer(FdDvr, MEGABYTE(5), device->CardIndex() + 1);
|
||||||
|
+ return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cDvbCiAdapter::Read(uint8_t *Buffer, int MaxLength)
|
int cDvbCiAdapter::Read(uint8_t *Buffer, int MaxLength)
|
||||||
@ -527,7 +587,7 @@ index 5289bbd..fea3a83 100644
|
|||||||
if (Buffer && MaxLength > 0) {
|
if (Buffer && MaxLength > 0) {
|
||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
pfd[0].fd = fd;
|
pfd[0].fd = fd;
|
||||||
@@ -61,6 +98,8 @@ int cDvbCiAdapter::Read(uint8_t *Buffer, int MaxLength)
|
@@ -61,6 +90,8 @@ int cDvbCiAdapter::Read(uint8_t *Buffer, int MaxLength)
|
||||||
|
|
||||||
void cDvbCiAdapter::Write(const uint8_t *Buffer, int Length)
|
void cDvbCiAdapter::Write(const uint8_t *Buffer, int Length)
|
||||||
{
|
{
|
||||||
@ -536,7 +596,7 @@ index 5289bbd..fea3a83 100644
|
|||||||
if (Buffer && Length > 0) {
|
if (Buffer && Length > 0) {
|
||||||
if (safe_write(fd, Buffer, Length) != Length)
|
if (safe_write(fd, Buffer, Length) != Length)
|
||||||
esyslog("ERROR: can't write to CI adapter on device %d: %m", device->DeviceNumber());
|
esyslog("ERROR: can't write to CI adapter on device %d: %m", device->DeviceNumber());
|
||||||
@@ -69,6 +108,8 @@ void cDvbCiAdapter::Write(const uint8_t *Buffer, int Length)
|
@@ -69,6 +100,8 @@ void cDvbCiAdapter::Write(const uint8_t *Buffer, int Length)
|
||||||
|
|
||||||
bool cDvbCiAdapter::Reset(int Slot)
|
bool cDvbCiAdapter::Reset(int Slot)
|
||||||
{
|
{
|
||||||
@ -545,7 +605,7 @@ index 5289bbd..fea3a83 100644
|
|||||||
if (ioctl(fd, CA_RESET, 1 << Slot) != -1)
|
if (ioctl(fd, CA_RESET, 1 << Slot) != -1)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
@@ -78,6 +119,8 @@ bool cDvbCiAdapter::Reset(int Slot)
|
@@ -78,6 +111,8 @@ bool cDvbCiAdapter::Reset(int Slot)
|
||||||
|
|
||||||
eModuleStatus cDvbCiAdapter::ModuleStatus(int Slot)
|
eModuleStatus cDvbCiAdapter::ModuleStatus(int Slot)
|
||||||
{
|
{
|
||||||
@ -554,24 +614,77 @@ index 5289bbd..fea3a83 100644
|
|||||||
ca_slot_info_t sinfo;
|
ca_slot_info_t sinfo;
|
||||||
sinfo.num = Slot;
|
sinfo.num = Slot;
|
||||||
if (ioctl(fd, CA_GET_SLOT_INFO, &sinfo) != -1) {
|
if (ioctl(fd, CA_GET_SLOT_INFO, &sinfo) != -1) {
|
||||||
@@ -99,10 +142,10 @@ bool cDvbCiAdapter::Assign(cDevice *Device, bool Query)
|
@@ -99,10 +134,60 @@ bool cDvbCiAdapter::Assign(cDevice *Device, bool Query)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
-cDvbCiAdapter *cDvbCiAdapter::CreateCiAdapter(cDevice *Device, int Fd)
|
-cDvbCiAdapter *cDvbCiAdapter::CreateCiAdapter(cDevice *Device, int Fd)
|
||||||
+cDvbCiAdapter *cDvbCiAdapter::CreateCiAdapter(cDevice *Device, int Fd, int Adapter, int Frontend)
|
+int cDvbCiAdapter::GetNumCamSlots(cDevice *Device, int Fd, cCiAdapter *CiAdapter)
|
||||||
{
|
{
|
||||||
// TODO check whether a CI is actually present?
|
- // TODO check whether a CI is actually present?
|
||||||
if (Device)
|
- if (Device)
|
||||||
- return new cDvbCiAdapter(Device, Fd);
|
- return new cDvbCiAdapter(Device, Fd);
|
||||||
|
- return NULL;
|
||||||
|
+ int NumSlots = -1;
|
||||||
|
+ if (Fd >= 0) {
|
||||||
|
+ ca_caps_t Caps;
|
||||||
|
+ if (ioctl(Fd, CA_GET_CAP, &Caps) == 0) {
|
||||||
|
+ if ((Caps.slot_type & CA_CI_LINK) != 0) {
|
||||||
|
+ NumSlots = Caps.slot_num;
|
||||||
|
+ if (NumSlots == 0)
|
||||||
|
+ esyslog("ERROR: no CAM slots found on device %d", Device->DeviceNumber());
|
||||||
|
+ else if (CiAdapter != NULL) {
|
||||||
|
+ for (int i = 0; i < NumSlots; i++)
|
||||||
|
+ new cCamSlot(CiAdapter);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ return NumSlots;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ isyslog("device %d doesn't support CI link layer interface", Device->DeviceNumber());
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ esyslog("ERROR: can't get CA capabilities on device %d", Device->DeviceNumber());
|
||||||
|
+ }
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+cDvbCiAdapter *cDvbCiAdapter::CreateCiAdapter(cDevice *Device, int Fd, int Adapter, int Frontend)
|
||||||
|
+{
|
||||||
|
+ // don't create a ci-adapter if it's not useable
|
||||||
|
+ if (Device && (Fd >= 0) && (GetNumCamSlots(Device, Fd, NULL) > 0))
|
||||||
+ return new cDvbCiAdapter(Device, Fd, Adapter, Frontend);
|
+ return new cDvbCiAdapter(Device, Fd, Adapter, Frontend);
|
||||||
return NULL;
|
+
|
||||||
|
+ if (Fd >= 0)
|
||||||
|
+ close(Fd);
|
||||||
|
+
|
||||||
|
+ // try to find an external ci-adapter
|
||||||
|
+ for (cDvbCiAdapterProbe *cp = DvbCiAdapterProbes.First(); cp; cp = DvbCiAdapterProbes.Next(cp)) {
|
||||||
|
+ cDvbCiAdapter *ca = cp->Probe(Device);
|
||||||
|
+ if (ca)
|
||||||
|
+ return ca;
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// --- cDvbCiAdapterProbe -------------------------------------------------------
|
||||||
|
+
|
||||||
|
+cList<cDvbCiAdapterProbe> DvbCiAdapterProbes;
|
||||||
|
+
|
||||||
|
+cDvbCiAdapterProbe::cDvbCiAdapterProbe(void)
|
||||||
|
+{
|
||||||
|
+ DvbCiAdapterProbes.Add(this);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+cDvbCiAdapterProbe::~cDvbCiAdapterProbe()
|
||||||
|
+{
|
||||||
|
+ DvbCiAdapterProbes.Del(this, false);
|
||||||
}
|
}
|
||||||
diff --git a/dvbci.h b/dvbci.h
|
diff --git a/dvbci.h b/dvbci.h
|
||||||
index adbe40d..6d117b2 100644
|
index adbe40d..d908b2f 100644
|
||||||
--- a/dvbci.h
|
--- a/dvbci.h
|
||||||
+++ b/dvbci.h
|
+++ b/dvbci.h
|
||||||
@@ -16,16 +16,24 @@ class cDvbCiAdapter : public cCiAdapter {
|
@@ -16,16 +16,48 @@ class cDvbCiAdapter : public cCiAdapter {
|
||||||
private:
|
private:
|
||||||
cDevice *device;
|
cDevice *device;
|
||||||
int fd;
|
int fd;
|
||||||
@ -592,26 +705,53 @@ index adbe40d..6d117b2 100644
|
|||||||
public:
|
public:
|
||||||
virtual ~cDvbCiAdapter();
|
virtual ~cDvbCiAdapter();
|
||||||
- static cDvbCiAdapter *CreateCiAdapter(cDevice *Device, int Fd);
|
- static cDvbCiAdapter *CreateCiAdapter(cDevice *Device, int Fd);
|
||||||
|
+ virtual cTSBufferBase *GetTSBuffer(int FdDvr);
|
||||||
|
+ static int GetNumCamSlots(cDevice *Device, int Fd, cCiAdapter *CiAdapter);
|
||||||
|
+ ///< Tests if the CA device is usable for vdr.
|
||||||
|
+ ///< If CiAdapter is not NULL it will create the CamSlots for the given ci-adapter.
|
||||||
+ virtual bool SetIdle(bool Idle, bool TestOnly);
|
+ virtual bool SetIdle(bool Idle, bool TestOnly);
|
||||||
+ virtual bool IsIdle(void) const { return idle; }
|
+ virtual bool IsIdle(void) const { return idle; }
|
||||||
+ static cDvbCiAdapter *CreateCiAdapter(cDevice *Device, int Fd, int Adapter = -1, int Frontend = -1);
|
+ static cDvbCiAdapter *CreateCiAdapter(cDevice *Device, int Fd, int Adapter = -1, int Frontend = -1);
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+// A plugin that implements an external DVB ci-adapter derived from cDvbCiAdapter needs to create
|
||||||
|
+// a cDvbCiAdapterProbe derived object on the heap in order to have its Probe()
|
||||||
|
+// function called, where it can actually create the appropriate ci-adapter.
|
||||||
|
+// The cDvbCiAdapterProbe object must be created in the plugin's constructor,
|
||||||
|
+// and deleted in its destructor.
|
||||||
|
+// Every plugin has to track its own list of already used device nodes.
|
||||||
|
+// The Probes are always called if the base cDvbCiAdapter can't create a ci-adapter on its own.
|
||||||
|
+
|
||||||
|
+class cDvbCiAdapterProbe : public cListObject {
|
||||||
|
+public:
|
||||||
|
+ cDvbCiAdapterProbe(void);
|
||||||
|
+ virtual ~cDvbCiAdapterProbe();
|
||||||
|
+ virtual cDvbCiAdapter *Probe(cDevice *Device) = 0;
|
||||||
|
+ ///< Probes for a DVB ci-adapter for the given Device and creates the appropriate
|
||||||
|
+ ///< object derived from cDvbCiAdapter if applicable.
|
||||||
|
+ ///< Returns NULL if no adapter has been created.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
+extern cList<cDvbCiAdapterProbe> DvbCiAdapterProbes;
|
||||||
|
+
|
||||||
#endif //__DVBCI_H
|
#endif //__DVBCI_H
|
||||||
diff --git a/dvbdevice.c b/dvbdevice.c
|
diff --git a/dvbdevice.c b/dvbdevice.c
|
||||||
index 53a4a22..7fc12a4 100644
|
index 43e8544..49b5f61 100644
|
||||||
--- a/dvbdevice.c
|
--- a/dvbdevice.c
|
||||||
+++ b/dvbdevice.c
|
+++ b/dvbdevice.c
|
||||||
@@ -287,7 +287,7 @@ private:
|
@@ -287,9 +287,10 @@ class cDvbTuner : public cThread {
|
||||||
|
private:
|
||||||
|
static cMutex bondMutex;
|
||||||
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
|
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
|
||||||
bool SendDiseqc;
|
+ bool SendDiseqc;
|
||||||
|
int frontendType;
|
||||||
const cDvbDevice *device;
|
const cDvbDevice *device;
|
||||||
- int fd_frontend;
|
- int fd_frontend;
|
||||||
+ mutable int fd_frontend;
|
+ mutable int fd_frontend;
|
||||||
int adapter, frontend;
|
int adapter, frontend;
|
||||||
uint32_t subsystemId;
|
uint32_t subsystemId;
|
||||||
int tuneTimeout;
|
int tuneTimeout;
|
||||||
@@ -298,7 +298,7 @@ private:
|
@@ -300,7 +301,7 @@ private:
|
||||||
const cScr *scr;
|
const cScr *scr;
|
||||||
bool lnbPowerTurnedOn;
|
bool lnbPowerTurnedOn;
|
||||||
eTunerStatus tunerStatus;
|
eTunerStatus tunerStatus;
|
||||||
@ -619,8 +759,14 @@ index 53a4a22..7fc12a4 100644
|
|||||||
+ mutable cMutex mutex;
|
+ mutable cMutex mutex;
|
||||||
cCondVar locked;
|
cCondVar locked;
|
||||||
cCondVar newSet;
|
cCondVar newSet;
|
||||||
dvb_diseqc_master_cmd diseqc_cmd;
|
cDvbTuner *bondedTuner;
|
||||||
@@ -313,6 +313,10 @@ private:
|
@@ -308,11 +309,16 @@ private:
|
||||||
|
bool SetFrontendType(const cChannel *Channel);
|
||||||
|
cString GetBondingParams(const cChannel *Channel = NULL) const;
|
||||||
|
void ClearEventQueue(void) const;
|
||||||
|
+ dvb_diseqc_master_cmd diseqc_cmd;
|
||||||
|
bool GetFrontendStatus(fe_status_t &Status) const;
|
||||||
|
void ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency);
|
||||||
void ResetToneAndVoltage(void);
|
void ResetToneAndVoltage(void);
|
||||||
bool SetFrontend(void);
|
bool SetFrontend(void);
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
@ -631,24 +777,37 @@ index 53a4a22..7fc12a4 100644
|
|||||||
public:
|
public:
|
||||||
cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int Frontend);
|
cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int Frontend);
|
||||||
virtual ~cDvbTuner();
|
virtual ~cDvbTuner();
|
||||||
@@ -324,6 +328,8 @@ public:
|
@@ -325,9 +331,13 @@ public:
|
||||||
uint32_t SubsystemId(void) const { return subsystemId; }
|
uint32_t SubsystemId(void) const { return subsystemId; }
|
||||||
bool IsTunedTo(const cChannel *Channel) const;
|
bool IsTunedTo(const cChannel *Channel) const;
|
||||||
void SetChannel(const cChannel *Channel);
|
void SetChannel(const cChannel *Channel);
|
||||||
+ bool SetIdle(bool Idle);
|
+ bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd);
|
||||||
+ bool IsIdle(void) const { return isIdle; }
|
|
||||||
bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd);
|
|
||||||
bool Locked(int TimeoutMs = 0);
|
bool Locked(int TimeoutMs = 0);
|
||||||
int GetSignalStrength(void) const;
|
int GetSignalStrength(void) const;
|
||||||
@@ -350,6 +356,7 @@ cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int
|
int GetSignalQuality(void) const;
|
||||||
|
+
|
||||||
|
+ bool SetIdle(bool Idle);
|
||||||
|
+ bool IsIdle(void) const { return isIdle; }
|
||||||
|
};
|
||||||
|
|
||||||
|
cMutex cDvbTuner::bondMutex;
|
||||||
|
@@ -337,6 +347,7 @@ cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int
|
||||||
|
frontendType = SYS_UNDEFINED;
|
||||||
|
device = Device;
|
||||||
|
fd_frontend = Fd_Frontend;
|
||||||
|
+ SendDiseqc=false;
|
||||||
|
adapter = Adapter;
|
||||||
|
frontend = Frontend;
|
||||||
|
subsystemId = cDvbDeviceProbe::GetSubsystemId(adapter, frontend);
|
||||||
|
@@ -349,6 +360,7 @@ cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int
|
||||||
|
tunerStatus = tsIdle;
|
||||||
bondedTuner = NULL;
|
bondedTuner = NULL;
|
||||||
bondedMaster = false;
|
bondedMaster = false;
|
||||||
bondedMasterFailed = false;
|
|
||||||
+ isIdle = false;
|
+ isIdle = false;
|
||||||
SetDescription("tuner on frontend %d/%d", adapter, frontend);
|
SetDescription("tuner on frontend %d/%d", adapter, frontend);
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
@@ -367,6 +374,8 @@ cDvbTuner::~cDvbTuner()
|
@@ -366,6 +378,8 @@ cDvbTuner::~cDvbTuner()
|
||||||
ExecuteDiseqc(lastDiseqc, &Frequency);
|
ExecuteDiseqc(lastDiseqc, &Frequency);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -657,7 +816,7 @@ index 53a4a22..7fc12a4 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool cDvbTuner::Bond(cDvbTuner *Tuner)
|
bool cDvbTuner::Bond(cDvbTuner *Tuner)
|
||||||
@@ -524,6 +533,8 @@ bool cDvbTuner::Locked(int TimeoutMs)
|
@@ -510,6 +524,8 @@ bool cDvbTuner::Locked(int TimeoutMs)
|
||||||
|
|
||||||
void cDvbTuner::ClearEventQueue(void) const
|
void cDvbTuner::ClearEventQueue(void) const
|
||||||
{
|
{
|
||||||
@ -666,8 +825,28 @@ index 53a4a22..7fc12a4 100644
|
|||||||
cPoller Poller(fd_frontend);
|
cPoller Poller(fd_frontend);
|
||||||
if (Poller.Poll(TUNER_POLL_TIMEOUT)) {
|
if (Poller.Poll(TUNER_POLL_TIMEOUT)) {
|
||||||
dvb_frontend_event Event;
|
dvb_frontend_event Event;
|
||||||
@@ -714,6 +725,8 @@ static int GetRequiredDeliverySystem(const cChannel *Channel, const cDvbTranspon
|
@@ -710,8 +726,28 @@ static int GetRequiredDeliverySystem(const cChannel *Channel, const cDvbTranspon
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool cDvbTuner::SendDiseqcCmd(dvb_diseqc_master_cmd cmd)
|
||||||
|
+{
|
||||||
|
+ cMutexLock MutexLock(&mutex);
|
||||||
|
+ cDvbTransponderParameters dtp(channel.Parameters());
|
||||||
|
+
|
||||||
|
+ // Determine the required frontend type:
|
||||||
|
+ int frontendType = GetRequiredDeliverySystem(&channel, &dtp);
|
||||||
|
+
|
||||||
|
+ if ((frontendType!=SYS_DVBS2 && frontendType!=SYS_DVBS) || SendDiseqc)
|
||||||
|
+ return false;
|
||||||
|
+ if (!OpenFrontend())
|
||||||
|
+ return false;
|
||||||
|
+ diseqc_cmd=cmd;
|
||||||
|
+ SendDiseqc=true;
|
||||||
|
+ newSet.Broadcast();
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
bool cDvbTuner::SetFrontend(void)
|
bool cDvbTuner::SetFrontend(void)
|
||||||
{
|
{
|
||||||
+ if (!OpenFrontend())
|
+ if (!OpenFrontend())
|
||||||
@ -675,7 +854,7 @@ index 53a4a22..7fc12a4 100644
|
|||||||
#define MAXFRONTENDCMDS 16
|
#define MAXFRONTENDCMDS 16
|
||||||
#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);\
|
||||||
@@ -859,9 +872,11 @@ void cDvbTuner::Action(void)
|
@@ -857,10 +893,16 @@ void cDvbTuner::Action(void)
|
||||||
bool LostLock = false;
|
bool LostLock = false;
|
||||||
fe_status_t Status = (fe_status_t)0;
|
fe_status_t Status = (fe_status_t)0;
|
||||||
while (Running()) {
|
while (Running()) {
|
||||||
@ -688,10 +867,15 @@ index 53a4a22..7fc12a4 100644
|
|||||||
+ Status = NewStatus;
|
+ Status = NewStatus;
|
||||||
+ }
|
+ }
|
||||||
cMutexLock MutexLock(&mutex);
|
cMutexLock MutexLock(&mutex);
|
||||||
|
+ if (SendDiseqc) {
|
||||||
|
+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &diseqc_cmd));
|
||||||
|
+ SendDiseqc=false;
|
||||||
|
+ }
|
||||||
int WaitTime = 1000;
|
int WaitTime = 1000;
|
||||||
if (SendDiseqc) {
|
switch (tunerStatus) {
|
||||||
@@ -935,6 +950,40 @@ bool cDvbTuner::SendDiseqcCmd(dvb_diseqc_master_cmd cmd)
|
case tsIdle:
|
||||||
return true;
|
@@ -912,6 +954,40 @@ void cDvbTuner::Action(void)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+bool cDvbTuner::SetIdle(bool Idle)
|
+bool cDvbTuner::SetIdle(bool Idle)
|
||||||
@ -731,7 +915,7 @@ index 53a4a22..7fc12a4 100644
|
|||||||
// --- cDvbSourceParam -------------------------------------------------------
|
// --- cDvbSourceParam -------------------------------------------------------
|
||||||
|
|
||||||
class cDvbSourceParam : public cSourceParam {
|
class cDvbSourceParam : public cSourceParam {
|
||||||
@@ -1020,7 +1069,8 @@ const char *DeliverySystemNames[] = {
|
@@ -997,7 +1073,8 @@ const char *DeliverySystemNames[] = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -741,16 +925,19 @@ index 53a4a22..7fc12a4 100644
|
|||||||
{
|
{
|
||||||
adapter = Adapter;
|
adapter = Adapter;
|
||||||
frontend = Frontend;
|
frontend = Frontend;
|
||||||
@@ -1040,7 +1090,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend)
|
@@ -1015,9 +1092,8 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend)
|
||||||
|
|
||||||
fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR);
|
// Common Interface:
|
||||||
if (fd_ca >= 0)
|
|
||||||
|
- fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR);
|
||||||
|
- if (fd_ca >= 0)
|
||||||
- ciAdapter = cDvbCiAdapter::CreateCiAdapter(this, fd_ca);
|
- ciAdapter = cDvbCiAdapter::CreateCiAdapter(this, fd_ca);
|
||||||
+ ciAdapter = cDvbCiAdapter::CreateCiAdapter(parentDevice ? parentDevice : this, fd_ca, adapter, frontend);
|
+ int fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR);
|
||||||
|
+ ciAdapter = cDvbCiAdapter::CreateCiAdapter(parentDevice ? parentDevice : this, fd_ca, adapter, frontend);
|
||||||
|
|
||||||
// The DVR device (will be opened and closed as needed):
|
// The DVR device (will be opened and closed as needed):
|
||||||
|
|
||||||
@@ -1257,7 +1307,11 @@ bool cDvbDevice::BondDevices(const char *Bondings)
|
@@ -1245,7 +1321,11 @@ bool cDvbDevice::BondDevices(const char *Bondings)
|
||||||
if (d >= 0) {
|
if (d >= 0) {
|
||||||
int ErrorDevice = 0;
|
int ErrorDevice = 0;
|
||||||
if (cDevice *Device1 = cDevice::GetDevice(i)) {
|
if (cDevice *Device1 = cDevice::GetDevice(i)) {
|
||||||
@ -762,7 +949,7 @@ index 53a4a22..7fc12a4 100644
|
|||||||
if (cDvbDevice *DvbDevice1 = dynamic_cast<cDvbDevice *>(Device1)) {
|
if (cDvbDevice *DvbDevice1 = dynamic_cast<cDvbDevice *>(Device1)) {
|
||||||
if (cDvbDevice *DvbDevice2 = dynamic_cast<cDvbDevice *>(Device2)) {
|
if (cDvbDevice *DvbDevice2 = dynamic_cast<cDvbDevice *>(Device2)) {
|
||||||
if (!DvbDevice1->Bond(DvbDevice2))
|
if (!DvbDevice1->Bond(DvbDevice2))
|
||||||
@@ -1291,7 +1345,10 @@ bool cDvbDevice::BondDevices(const char *Bondings)
|
@@ -1279,7 +1359,10 @@ bool cDvbDevice::BondDevices(const char *Bondings)
|
||||||
void cDvbDevice::UnBondDevices(void)
|
void cDvbDevice::UnBondDevices(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cDevice::NumDevices(); i++) {
|
for (int i = 0; i < cDevice::NumDevices(); i++) {
|
||||||
@ -774,7 +961,7 @@ index 53a4a22..7fc12a4 100644
|
|||||||
d->UnBond();
|
d->UnBond();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1345,6 +1402,26 @@ bool cDvbDevice::BondingOk(const cChannel *Channel, bool ConsiderOccupied) const
|
@@ -1333,6 +1416,26 @@ bool cDvbDevice::BondingOk(const cChannel *Channel, bool ConsiderOccupied) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,7 +988,7 @@ index 53a4a22..7fc12a4 100644
|
|||||||
bool cDvbDevice::HasCi(void)
|
bool cDvbDevice::HasCi(void)
|
||||||
{
|
{
|
||||||
return ciAdapter;
|
return ciAdapter;
|
||||||
@@ -1511,7 +1588,7 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
|
@@ -1499,7 +1602,7 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
|
||||||
|
|
||||||
bool cDvbDevice::ProvidesEIT(void) const
|
bool cDvbDevice::ProvidesEIT(void) const
|
||||||
{
|
{
|
||||||
@ -810,8 +997,35 @@ index 53a4a22..7fc12a4 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cDvbDevice::NumProvidedSystems(void) const
|
int cDvbDevice::NumProvidedSystems(void) const
|
||||||
|
@@ -1544,6 +1647,11 @@ bool cDvbDevice::HasLock(int TimeoutMs)
|
||||||
|
return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool cDvbDevice::SendDiseqcCmd(dvb_diseqc_master_cmd cmd)
|
||||||
|
+{
|
||||||
|
+ return dvbTuner->SendDiseqcCmd(cmd);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void cDvbDevice::SetTransferModeForDolbyDigital(int Mode)
|
||||||
|
{
|
||||||
|
setTransferModeForDolbyDigital = Mode;
|
||||||
|
@@ -1553,8 +1661,12 @@ bool cDvbDevice::OpenDvr(void)
|
||||||
|
{
|
||||||
|
CloseDvr();
|
||||||
|
fd_dvr = DvbOpen(DEV_DVB_DVR, adapter, frontend, O_RDONLY | O_NONBLOCK, true);
|
||||||
|
- if (fd_dvr >= 0)
|
||||||
|
- tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(5), CardIndex() + 1);
|
||||||
|
+ if (fd_dvr >= 0) {
|
||||||
|
+ if (ciAdapter)
|
||||||
|
+ tsBuffer = ciAdapter->GetTSBuffer(fd_dvr);
|
||||||
|
+ if (tsBuffer == NULL)
|
||||||
|
+ tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(5), CardIndex() + 1);
|
||||||
|
+ }
|
||||||
|
return fd_dvr >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
diff --git a/dvbdevice.h b/dvbdevice.h
|
diff --git a/dvbdevice.h b/dvbdevice.h
|
||||||
index 4ffcb91..e9b7cd6 100644
|
index 7da9c56..6cd4abf 100644
|
||||||
--- a/dvbdevice.h
|
--- a/dvbdevice.h
|
||||||
+++ b/dvbdevice.h
|
+++ b/dvbdevice.h
|
||||||
@@ -107,7 +107,7 @@ class cDvbTuner;
|
@@ -107,7 +107,7 @@ class cDvbTuner;
|
||||||
@ -823,7 +1037,14 @@ index 4ffcb91..e9b7cd6 100644
|
|||||||
static cString DvbName(const char *Name, int Adapter, int Frontend);
|
static cString DvbName(const char *Name, int Adapter, int Frontend);
|
||||||
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError = false);
|
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError = false);
|
||||||
private:
|
private:
|
||||||
@@ -133,12 +133,14 @@ private:
|
@@ -127,19 +127,20 @@ private:
|
||||||
|
int deliverySystems[MAXDELIVERYSYSTEMS];
|
||||||
|
int numDeliverySystems;
|
||||||
|
int numModulations;
|
||||||
|
- int fd_dvr, fd_ca;
|
||||||
|
+ int fd_dvr;
|
||||||
|
static cMutex bondMutex;
|
||||||
|
cDvbDevice *bondedDevice;
|
||||||
mutable bool needsDetachBondedReceivers;
|
mutable bool needsDetachBondedReceivers;
|
||||||
bool QueryDeliverySystems(int fd_frontend);
|
bool QueryDeliverySystems(int fd_frontend);
|
||||||
public:
|
public:
|
||||||
@ -833,12 +1054,26 @@ index 4ffcb91..e9b7cd6 100644
|
|||||||
int Adapter(void) const { return adapter; }
|
int Adapter(void) const { return adapter; }
|
||||||
int Frontend(void) const { return frontend; }
|
int Frontend(void) const { return frontend; }
|
||||||
virtual bool Ready(void);
|
virtual bool Ready(void);
|
||||||
|
virtual cString DeviceType(void) const;
|
||||||
virtual cString DeviceName(void) const;
|
virtual cString DeviceName(void) const;
|
||||||
+ virtual bool SetIdleDevice(bool Idle, bool TestOnly);
|
+ virtual bool SetIdleDevice(bool Idle, bool TestOnly);
|
||||||
+
|
|
||||||
static bool BondDevices(const char *Bondings);
|
static bool BondDevices(const char *Bondings);
|
||||||
///< Bonds the devices as defined in the given Bondings string.
|
///< Bonds the devices as defined in the given Bondings string.
|
||||||
///< A bonding is a sequence of device numbers (starting at 1),
|
///< A bonding is a sequence of device numbers (starting at 1),
|
||||||
--
|
@@ -193,6 +194,7 @@ protected:
|
||||||
1.7.2.5
|
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
|
||||||
|
public:
|
||||||
|
virtual bool HasLock(int TimeoutMs = 0);
|
||||||
|
+ virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd);
|
||||||
|
|
||||||
|
// PID handle facilities
|
||||||
|
|
||||||
|
@@ -225,7 +227,7 @@ public:
|
||||||
|
// Receiver facilities
|
||||||
|
|
||||||
|
private:
|
||||||
|
- cTSBuffer *tsBuffer;
|
||||||
|
+ cTSBufferBase *tsBuffer;
|
||||||
|
protected:
|
||||||
|
virtual bool OpenDvr(void);
|
||||||
|
virtual void CloseDvr(void);
|
Loading…
x
Reference in New Issue
Block a user