diff options
| author | Klaus Schmidinger <vdr@tvdr.de> | 2017-04-15 09:39:55 +0200 | 
|---|---|---|
| committer | Klaus Schmidinger <vdr@tvdr.de> | 2017-04-15 09:39:55 +0200 | 
| commit | 1a160e7afeddd6a2479a40ee6110477093942707 (patch) | |
| tree | 757f2ac9c91c8399c7f652ce37a70fbd8ebde495 | |
| parent | 016e10c1b0d20b8c73b593afcaf492219b5a0064 (diff) | |
| download | vdr-1a160e7afeddd6a2479a40ee6110477093942707.tar.gz vdr-1a160e7afeddd6a2479a40ee6110477093942707.tar.bz2 | |
The function cCamSlot::Decrypt() can now also be called with Data == NULL
| -rw-r--r-- | HISTORY | 9 | ||||
| -rw-r--r-- | ci.c | 5 | ||||
| -rw-r--r-- | ci.h | 9 | ||||
| -rw-r--r-- | device.c | 6 | ||||
| -rw-r--r-- | device.h | 8 | ||||
| -rw-r--r-- | dvbdevice.c | 14 | ||||
| -rw-r--r-- | dvbdevice.h | 3 | 
7 files changed, 38 insertions, 16 deletions
| @@ -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()). @@ -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;  } @@ -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. @@ -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) { @@ -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; | 
