diff --git a/HISTORY b/HISTORY index 221a1bc4..2c758be2 100644 --- a/HISTORY +++ b/HISTORY @@ -8882,7 +8882,7 @@ Video Disk Recorder Revision History - Added a short sleep to cTSBuffer::Action() to avoid high CPU usage (thanks to Sergey Chernyavskiy). -2017-02-14: Version 2.3.3 +2017-02-21: Version 2.3.3 - Added 'S3W ABS-3A' to sources.conf (thanks to Frank Richter). - Fixed a possible deadlock in the recordings handler thread. @@ -8912,3 +8912,5 @@ Video Disk Recorder Revision History - The Setup/CAM menu now only displays master CAMs. - Fixed setting the local machine's SVDRP host name (was overwritten if setup.conf contained an empty string). +- PIDs can now be added to and deleted from a cReceiver while it is attached to + a cDevice, without having to detach it first and re-attach it afterwards. diff --git a/ci.c b/ci.c index 1096721b..8f2256e3 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.5 2017/01/23 11:42:14 kls Exp $ + * $Id: ci.c 4.6 2017/02/21 14:17:07 kls Exp $ */ #include "ci.h" @@ -121,8 +121,6 @@ private: int length; void AddEmmPid(int Pid); void DelEmmPids(void); -protected: - virtual void Activate(bool On); public: cCaPidReceiver(void); virtual ~cCaPidReceiver() { Detach(); } @@ -156,11 +154,6 @@ void cCaPidReceiver::DelEmmPids(void) emmPids.Clear(); } -void cCaPidReceiver::Activate(bool On) -{ - catVersion = -1; // can be done independent of 'On' -} - void cCaPidReceiver::Receive(const uchar *Data, int Length) { if (TsPid(Data) == CATPID) { @@ -208,10 +201,6 @@ void cCaPidReceiver::Receive(const uchar *Data, int Length) } } if (p) { - int OldCatVersion = catVersion; // must preserve the current version number - cDevice *AttachedDevice = Device(); - if (AttachedDevice) - AttachedDevice->Detach(this); DelEmmPids(); for (int i = 0; i < length - 4; i++) { // -4 = checksum if (p[i] == 0x09) { @@ -228,9 +217,6 @@ void cCaPidReceiver::Receive(const uchar *Data, int Length) i += p[i + 1] + 2 - 1; // -1 to compensate for the loop increment } } - if (AttachedDevice) - AttachedDevice->AttachReceiver(this); - catVersion = OldCatVersion; p = NULL; bufp = 0; length = 0; @@ -1747,9 +1733,10 @@ cCamSlot::cCamSlot(cCiAdapter *CiAdapter, bool WantsTsData, cCamSlot *MasterSlot tc[i] = NULL; CamSlots.Add(this); slotNumber = Index() + 1; - if (ciAdapter) + if (ciAdapter) { ciAdapter->AddCamSlot(this); - Reset(); + Reset(); + } } cCamSlot::~cCamSlot() @@ -1767,20 +1754,28 @@ bool cCamSlot::Assign(cDevice *Device, bool Query) cMutexLock MutexLock(&mutex); if (ciAdapter) { if (ciAdapter->Assign(Device, true)) { - if (!Device && assignedDevice) + if (!Device && assignedDevice) { + if (caPidReceiver) + assignedDevice->Detach(caPidReceiver); assignedDevice->SetCamSlot(NULL); + } if (!Query || !Device) { StopDecrypting(); source = transponder = 0; if (ciAdapter->Assign(Device)) { + int OldDeviceNumber = assignedDevice ? assignedDevice->DeviceNumber() + 1 : 0; assignedDevice = Device; if (Device) { Device->SetCamSlot(this); - dsyslog("CAM %d: assigned to device %d", slotNumber, Device->DeviceNumber() + 1); + if (caPidReceiver) { + caPidReceiver->Reset(); + Device->AttachReceiver(caPidReceiver); + } + dsyslog("CAM %d: assigned to device %d", MasterSlotNumber(), Device->DeviceNumber() + 1); } else { CancelActivation(); - dsyslog("CAM %d: unassigned", slotNumber); + dsyslog("CAM %d: unassigned from device %d", MasterSlotNumber(), OldDeviceNumber); } } else @@ -2014,10 +2009,6 @@ void cCamSlot::SendCaPmt(uint8_t CmdId) const int *CaSystemIds = cas->GetCaSystemIds(); if (CaSystemIds && *CaSystemIds) { if (caProgramList.Count()) { - if (caPidReceiver && caPidReceiver->HasCaPids()) { - if (cDevice *d = Device()) - d->Detach(caPidReceiver); - } for (int Loop = 1; Loop <= 2; Loop++) { for (cCiCaProgramData *p = caProgramList.First(); p; p = caProgramList.Next(p)) { if (p->modified || resendPmt) { @@ -2048,20 +2039,11 @@ void cCamSlot::SendCaPmt(uint8_t CmdId) } } } - if (caPidReceiver && caPidReceiver->HasCaPids()) { - if (cDevice *d = Device()) - d->AttachReceiver(caPidReceiver); - } resendPmt = false; } else { cCiCaPmt CaPmt(CmdId, 0, 0, 0, NULL); cas->SendPMT(&CaPmt); - if (caPidReceiver) { - if (cDevice *d = Device()) - d->Detach(caPidReceiver); - caPidReceiver->Reset(); - } } } } diff --git a/device.c b/device.c index 2b350e86..0c8b0018 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.6 2017/01/23 11:43:05 kls Exp $ + * $Id: device.c 4.7 2017/02/21 13:38:01 kls Exp $ */ #include "device.h" @@ -451,6 +451,7 @@ void cDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect) bool cDevice::HasPid(int Pid) const { + cMutexLock MutexLock(&mutexPids); for (int i = 0; i < MAXPIDHANDLES; i++) { if (pidHandles[i].pid == Pid) return true; @@ -460,6 +461,7 @@ bool cDevice::HasPid(int Pid) const bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType) { + cMutexLock MutexLock(&mutexPids); if (Pid || PidType == ptPcr) { int n = -1; int a = -1; @@ -524,6 +526,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType) void cDevice::DelPid(int Pid, ePidType PidType) { + cMutexLock MutexLock(&mutexPids); if (Pid || PidType == ptPcr) { int n = -1; if (PidType == ptPcr) @@ -559,6 +562,7 @@ bool cDevice::SetPid(cPidHandle *Handle, int Type, bool On) void cDevice::DelLivePids(void) { + cMutexLock MutexLock(&mutexPids); for (int i = ptAudio; i < ptOther; i++) { if (pidHandles[i].pid) DelPid(pidHandles[i].pid, ePidType(i)); diff --git a/device.h b/device.h index 2639e855..581c187a 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.3 2017/01/09 12:51:05 kls Exp $ + * $Id: device.h 4.4 2017/02/21 13:23:24 kls Exp $ */ #ifndef __DEVICE_H @@ -109,6 +109,7 @@ public: class cDevice : public cThread { friend class cLiveSubtitle; friend class cDeviceHook; + friend class cReceiver; private: static int numDevices; static int useDevice; @@ -355,6 +356,7 @@ public: // PID handle facilities private: + mutable cMutex mutexPids; virtual void Action(void); protected: enum ePidType { ptAudio, ptVideo, ptPcr, ptTeletext, ptDolby, ptOther }; diff --git a/receiver.c b/receiver.c index 8d647c02..dd61fd65 100644 --- a/receiver.c +++ b/receiver.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: receiver.c 4.1 2015/09/16 11:19:47 kls Exp $ + * $Id: receiver.c 4.2 2017/02/21 10:59:27 kls Exp $ */ #include "receiver.h" @@ -38,8 +38,11 @@ bool cReceiver::AddPid(int Pid) { if (Pid) { if (numPids < MAXRECEIVEPIDS) { - if (!WantsPid(Pid)) + if (!WantsPid(Pid)) { pids[numPids++] = Pid; + if (device) + device->AddPid(Pid); + } } else { dsyslog("too many PIDs in cReceiver (Pid = %d)", Pid); @@ -87,6 +90,8 @@ void cReceiver::DelPid(int Pid) for ( ; i < numPids; i++) // we also copy the terminating 0! pids[i] = pids[i + 1]; numPids--; + if (device) + device->DelPid(Pid); return; } }