summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2017-04-15 09:39:55 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2017-04-15 09:39:55 +0200
commit1a160e7afeddd6a2479a40ee6110477093942707 (patch)
tree757f2ac9c91c8399c7f652ce37a70fbd8ebde495
parent016e10c1b0d20b8c73b593afcaf492219b5a0064 (diff)
downloadvdr-1a160e7afeddd6a2479a40ee6110477093942707.tar.gz
vdr-1a160e7afeddd6a2479a40ee6110477093942707.tar.bz2
The function cCamSlot::Decrypt() can now also be called with Data == NULL
-rw-r--r--HISTORY9
-rw-r--r--ci.c5
-rw-r--r--ci.h9
-rw-r--r--device.c6
-rw-r--r--device.h8
-rw-r--r--dvbdevice.c14
-rw-r--r--dvbdevice.h3
7 files changed, 38 insertions, 16 deletions
diff --git a/HISTORY b/HISTORY
index bf95d376..1c35633e 100644
--- a/HISTORY
+++ b/HISTORY
@@ -8925,7 +8925,7 @@ Video Disk Recorder Revision History
- Now stopping any ongoing recordings before stopping the plugins, to avoid
a crash when stopping VDR while recording.
-2017-04-06: Version 2.3.4
+2017-04-15: Version 2.3.4
- The functionality of HandleRemoteModifications(), which synchronizes changes to
timers between peer VDR machines, has been moved to timers.[ch] and renamed to
@@ -8965,3 +8965,10 @@ Video Disk Recorder Revision History
recording being replayed.
- Signal strength and quality (CNR) are now determined via DVB API 5 (if available).
Fallback is the old DVB API 3 method.
+- The function cCamSlot::Decrypt() can now also be called with Data == NULL.
+ This is necessary to allow CAMs that copy the incoming data into a separate buffer
+ to return previously received and decrypted TS packets. See ci.h for details.
+ Plugins that implement a derived cCamSlot need to properly handle this case, and
+ plugins that implement a derived cDevice need to call Decrypt() in their
+ GetTSPacket() function even if the incoming buffer is currently empty (see
+ cDvbDevice::GetTSPacket()).
diff --git a/ci.c b/ci.c
index db2f1404..d3244e54 100644
--- a/ci.c
+++ b/ci.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: ci.c 4.10 2017/04/02 10:02:13 kls Exp $
+ * $Id: ci.c 4.11 2017/04/11 16:45:55 kls Exp $
*/
#include "ci.h"
@@ -2415,7 +2415,8 @@ bool cCamSlot::IsDecrypting(void)
uchar *cCamSlot::Decrypt(uchar *Data, int &Count)
{
- Count = TS_SIZE;
+ if (Data)
+ Count = TS_SIZE;
return Data;
}
diff --git a/ci.h b/ci.h
index 0e8253d9..8d1323ac 100644
--- a/ci.h
+++ b/ci.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: ci.h 4.5 2017/03/23 14:23:33 kls Exp $
+ * $Id: ci.h 4.6 2017/04/10 09:17:56 kls Exp $
*/
#ifndef __CI_H
@@ -345,7 +345,12 @@ public:
///< in hardware, it can implement this function to be given access
///< to the data in the device's TS buffer. Data points to a buffer
///< of Count bytes of TS data. The first byte in Data is guaranteed
- ///< to be a TS_SYNC_BYTE.
+ ///< to be a TS_SYNC_BYTE, and Count is at least TS_SIZE.
+ ///< Note that Decrypt() may be called with Data == NULL! This is necessary
+ ///< to allow CAMs that copy the incoming data into a separate buffer to
+ ///< return previously received and decrypted TS packets. If Data is NULL,
+ ///< Count is 0 and must not be modified, and the return value shall point to the
+ ///< next available decrypted TS packet (if any).
///< There are three possible ways a CAM can handle decryption:
///< 1. If the full TS data is physically routed through the CAM in hardware,
///< there is no need to reimplement this function.
diff --git a/device.c b/device.c
index 1c7f2225..38eb77f3 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 4.12 2017/04/02 10:08:49 kls Exp $
+ * $Id: device.c 4.13 2017/04/14 09:38:42 kls Exp $
*/
#include "device.h"
@@ -1860,13 +1860,15 @@ void cTSBuffer::Action(void)
}
}
-uchar *cTSBuffer::Get(int *Available)
+uchar *cTSBuffer::Get(int *Available, bool CheckAvailable)
{
int Count = 0;
if (delivered) {
ringBuffer->Del(TS_SIZE);
delivered = false;
}
+ if (CheckAvailable && ringBuffer->Available() < TS_SIZE)
+ return NULL;
uchar *p = ringBuffer->Get(Count);
if (p && Count >= TS_SIZE) {
if (*p != TS_SYNC_BYTE) {
diff --git a/device.h b/device.h
index 7e3592b1..97d8ad91 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.h 4.5 2017/04/02 10:08:49 kls Exp $
+ * $Id: device.h 4.6 2017/04/14 09:59:20 kls Exp $
*/
#ifndef __DEVICE_H
@@ -846,13 +846,17 @@ private:
public:
cTSBuffer(int File, int Size, int CardIndex);
virtual ~cTSBuffer();
- uchar *Get(int *Available = NULL);
+ uchar *Get(int *Available = NULL, bool CheckAvailable = false);
///< Returns a pointer to the first TS packet in the buffer. If Available is given,
///< it will return the total number of consecutive bytes pointed to in the buffer.
///< It is guaranteed that the returned pointer points to a TS_SYNC_BYTE and that
///< there are at least TS_SIZE bytes in the buffer. Otherwise NULL will be
///< returned and the value in Available (if given) is undefined.
///< Each call to Get() returns a pointer to the next TS packet in the buffer.
+ ///< If CheckAvailable is true, the buffer will be checked whether it contains
+ ///< at least TS_SIZE bytes before trying to get any data from it. Otherwise, if
+ ///< the buffer is empty, this function will wait a little while for the buffer
+ ///< to be filled again.
void Skip(int Count);
///< If after a call to Get() more or less than TS_SIZE of the available data
///< has been processed, a call to Skip() with the number of processed bytes
diff --git a/dvbdevice.c b/dvbdevice.c
index 9bf15b71..7775465d 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.c 4.5 2017/04/06 17:02:35 kls Exp $
+ * $Id: dvbdevice.c 4.6 2017/04/14 10:05:15 kls Exp $
*/
#include "dvbdevice.h"
@@ -1187,6 +1187,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend)
fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR);
if (fd_ca >= 0)
ciAdapter = cDvbCiAdapter::CreateCiAdapter(this, fd_ca);
+ checkTsBuffer = false;
// The DVR device (will be opened and closed as needed):
@@ -1763,11 +1764,12 @@ bool cDvbDevice::GetTSPacket(uchar *&Data)
if (cCamSlot *cs = CamSlot()) {
if (cs->WantsTsData()) {
int Available;
- Data = tsBuffer->Get(&Available);
- if (Data) {
- Data = cs->Decrypt(Data, Available);
- tsBuffer->Skip(Available);
- }
+ Data = tsBuffer->Get(&Available, checkTsBuffer);
+ if (!Data)
+ Available = 0;
+ Data = cs->Decrypt(Data, Available);
+ tsBuffer->Skip(Available);
+ checkTsBuffer = Data != NULL;
return true;
}
}
diff --git a/dvbdevice.h b/dvbdevice.h
index 5ae4952f..a799c0d2 100644
--- a/dvbdevice.h
+++ b/dvbdevice.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.h 4.1 2015/04/18 13:57:27 kls Exp $
+ * $Id: dvbdevice.h 4.2 2017/04/14 09:31:29 kls Exp $
*/
#ifndef __DVBDEVICE_H
@@ -187,6 +187,7 @@ private:
int numDeliverySystems;
int numModulations;
int fd_dvr, fd_ca;
+ bool checkTsBuffer;
static cMutex bondMutex;
cDvbDevice *bondedDevice;
mutable bool needsDetachBondedReceivers;