From 5638a2a40bba939604200aa0c330b819313f89ac Mon Sep 17 00:00:00 2001 From: root Date: Sun, 9 Jun 2013 22:06:24 +0200 Subject: [PATCH] Fix for decrypting 2 channels in parallel. If CAM-Module decrypts one channel it's now possible to add a second recording which needs also decryption without destroying the first or both recordings. During LiveTV it speeds up decryption at channel changes. --- mythtv/libs/libmythtv/dtvrecorder.cpp | 1 + mythtv/libs/libmythtv/dtvsignalmonitor.cpp | 11 ---- mythtv/libs/libmythtv/dtvsignalmonitor.h | 2 - mythtv/libs/libmythtv/dvbcam.cpp | 86 +++++++++++++++++++++---- mythtv/libs/libmythtv/dvbcam.h | 1 + mythtv/libs/libmythtv/dvbchannel.cpp | 4 ++ mythtv/libs/libmythtv/dvbrecorder.cpp | 3 + mythtv/libs/libmythtv/dvbsignalmonitor.cpp | 15 +++-- mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp | 2 +- 9 files changed, 94 insertions(+), 31 deletions(-) diff --git a/mythtv/libs/libmythtv/dtvrecorder.cpp b/mythtv/libs/libmythtv/dtvrecorder.cpp index c87ed36..489d73b 100644 --- a/mythtv/libs/libmythtv/dtvrecorder.cpp +++ b/mythtv/libs/libmythtv/dtvrecorder.cpp @@ -1222,6 +1222,7 @@ void DTVRecorder::HandlePMT(uint progNum, const ProgramMapTable *_pmt) } _has_no_av = has_no_av; + _stream_data->TestDecryption(_input_pmt); SetCAMPMT(_input_pmt); delete oldpmt; } diff --git a/mythtv/libs/libmythtv/dtvsignalmonitor.cpp b/mythtv/libs/libmythtv/dtvsignalmonitor.cpp index 06cdd42..e80596f 100644 --- a/mythtv/libs/libmythtv/dtvsignalmonitor.cpp +++ b/mythtv/libs/libmythtv/dtvsignalmonitor.cpp @@ -4,7 +4,6 @@ using namespace std; #include "dtvchannel.h" -#include "dvbchannel.h" #include "dtvsignalmonitor.h" #include "scanstreamdata.h" #include "mpegtables.h" @@ -370,12 +369,7 @@ void DTVSignalMonitor::HandlePMT(uint, const ProgramMapTable *pmt) { if (pmt->IsEncrypted(GetDTVChannel()->GetSIStandard()) && !ignore_encrypted) - { - DVBChannel *dvbchannel = GetDVBChannel(); - if (dvbchannel) - dvbchannel->SetPMT(pmt); AddFlags(kDTVSigMon_WaitForCrypt); - } AddFlags(kDTVSigMon_PMTMatch); } @@ -539,11 +533,6 @@ const ScanStreamData *DTVSignalMonitor::GetScanStreamData() const return dynamic_cast(stream_data); } -DVBChannel *DTVSignalMonitor::GetDVBChannel(void) -{ - return dynamic_cast(channel); -} - bool DTVSignalMonitor::IsAllGood(void) const { QMutexLocker locker(&statusLock); diff --git a/mythtv/libs/libmythtv/dtvsignalmonitor.h b/mythtv/libs/libmythtv/dtvsignalmonitor.h index 2be4302..0d14b7f 100644 --- a/mythtv/libs/libmythtv/dtvsignalmonitor.h +++ b/mythtv/libs/libmythtv/dtvsignalmonitor.h @@ -11,7 +11,6 @@ using namespace std; #include "streamlisteners.h" class DTVChannel; -class DVBChannel; class DTVSignalMonitor : public SignalMonitor, public MPEGStreamListener, @@ -104,7 +103,6 @@ class DTVSignalMonitor : public SignalMonitor, protected: DTVChannel *GetDTVChannel(void); - DVBChannel *GetDVBChannel(void); void UpdateMonitorValues(void); void UpdateListeningForEIT(void); diff --git a/mythtv/libs/libmythtv/dvbcam.cpp b/mythtv/libs/libmythtv/dvbcam.cpp index 74a2e96..36dfe86 100644 --- a/mythtv/libs/libmythtv/dvbcam.cpp +++ b/mythtv/libs/libmythtv/dvbcam.cpp @@ -146,6 +146,7 @@ bool DVBCam::Stop(void) for (it = PMTAddList.begin(); it != PMTAddList.end(); ++it) delete *it; PMTAddList.clear(); + progNumAdded.clear(); return true; } @@ -156,7 +157,7 @@ void DVBCam::HandleUserIO(void) if (enq != NULL) { if (enq->Text() != NULL) - LOG(VB_DVBCAM, LOG_INFO, LOC + QString("CAM: Received message: %1") + LOG(VB_GENERAL, LOG_INFO, LOC + QString("CAM: Received message: %1") .arg(enq->Text())); delete enq; } @@ -165,18 +166,18 @@ void DVBCam::HandleUserIO(void) if (menu != NULL) { if (menu->TitleText() != NULL) - LOG(VB_DVBCAM, LOG_INFO, LOC + QString("CAM: Menu Title: %1") + LOG(VB_GENERAL, LOG_INFO, LOC + QString("CAM: Menu Title: %1") .arg(menu->TitleText())); if (menu->SubTitleText() != NULL) - LOG(VB_DVBCAM, LOG_INFO, LOC + QString("CAM: Menu SubTitle: %1") + LOG(VB_GENERAL, LOG_INFO, LOC + QString("CAM: Menu SubTitle: %1") .arg(menu->SubTitleText())); if (menu->BottomText() != NULL) - LOG(VB_DVBCAM, LOG_INFO, LOC + QString("CAM: Menu BottomText: %1") + LOG(VB_GENERAL, LOG_INFO, LOC + QString("CAM: Menu BottomText: %1") .arg(menu->BottomText())); for (int i=0; iNumEntries(); i++) if (menu->Entry(i) != NULL) - LOG(VB_DVBCAM, LOG_INFO, LOC + QString("CAM: Menu Entry: %1") + LOG(VB_GENERAL, LOG_INFO, LOC + QString("CAM: Menu Entry: %1") .arg(menu->Entry(i))); if (menu->Selectable()) @@ -203,7 +204,7 @@ void DVBCam::HandlePMT(void) LOG(VB_DVBCAM, LOG_INFO, LOC + "CiHandler needs CA_PMT"); QMutexLocker locker(&pmt_lock); - if (pmt_sent && pmt_added && !pmt_updated) + if (pmt_sent && pmt_added && pmt_updated) { // Send added PMT while (PMTAddList.size() > 0) @@ -286,30 +287,91 @@ void DVBCam::SetPMT(const ChannelBase *chan, const ProgramMapTable *pmt) pmt_list_t::iterator it = PMTList.find(chan); pmt_list_t::iterator it2 = PMTAddList.find(chan); + int currentProgramNumber; + if (pmt) + currentProgramNumber = pmt->ProgramNumber(); if (!pmt && (it != PMTList.end())) { + LOG(VB_DVBCAM, LOG_INFO, LOC + + QString("Program %1 not used any more") + .arg(chan->GetCurrentName())); delete *it; PMTList.erase(it); - pmt_updated = true; + if (PMTList.size() == 1) + { + progNumAdded.clear(); + progNumAdded.append((*PMTList.begin())->ProgramNumber()); + LOG(VB_DVBCAM, LOG_INFO, LOC + + QString("Decrypted PID List cleared")); + } +// pmt_updated = true; } else if (!pmt && (it2 != PMTAddList.end())) { + LOG(VB_DVBCAM, LOG_INFO, LOC + + QString("Take Program %1 from AddList") + .arg(chan->GetCurrentName())); delete *it2; PMTAddList.erase(it2); pmt_added = !PMTAddList.empty(); } - else if (pmt && (PMTList.empty() || (it != PMTList.end()))) + else if (pmt && (PMTList.empty())) { - if (it != PMTList.end()) - delete *it; + LOG(VB_DVBCAM, LOG_INFO, LOC + + QString("Sending Program %1 to CAM") + .arg(currentProgramNumber)); PMTList[chan] = new ProgramMapTable(*pmt); + progNumAdded.append(currentProgramNumber); have_pmt = true; pmt_updated = true; } + else if (pmt && (it != PMTList.end())) + { + int oldProgramNumber = (*it)->ProgramNumber(); + if (currentProgramNumber != oldProgramNumber) + { + LOG(VB_DVBCAM, LOG_INFO, LOC + + QString("Updating Program %1 to Program %2") + .arg(oldProgramNumber) + .arg(currentProgramNumber)); + progNumAdded.removeAll(oldProgramNumber); + delete *it; + PMTList.erase(it); + if (PMTList.empty()) + { + LOG(VB_DVBCAM, LOG_INFO, LOC + + QString("Sending Program %1 to CAM") + .arg(currentProgramNumber)); + PMTList[chan] = new ProgramMapTable(*pmt); + progNumAdded.append(currentProgramNumber); + pmt_updated = true; + } + else if (!progNumAdded.contains(currentProgramNumber)) + { + LOG(VB_DVBCAM, LOG_INFO, LOC + + QString("Add Program %1 to AddList") + .arg(currentProgramNumber)); + PMTAddList[chan] = new ProgramMapTable(*pmt); + progNumAdded.append(oldProgramNumber); + progNumAdded.append(currentProgramNumber); + pmt_added = true; + pmt_updated = true; + } + else + progNumAdded.append(oldProgramNumber); + } + } else if (pmt && (it == PMTList.end())) { - PMTAddList[chan] = new ProgramMapTable(*pmt); - pmt_added = true; + if (!progNumAdded.contains(currentProgramNumber)) + { + LOG(VB_DVBCAM, LOG_INFO, LOC + + QString("Add Program %1 to AddList") + .arg(currentProgramNumber)); + PMTAddList[chan] = new ProgramMapTable(*pmt); + progNumAdded.append(currentProgramNumber); + pmt_added = true; + } } } diff --git a/mythtv/libs/libmythtv/dvbcam.h b/mythtv/libs/libmythtv/dvbcam.h index 03a5a5e..317a172 100644 --- a/mythtv/libs/libmythtv/dvbcam.h +++ b/mythtv/libs/libmythtv/dvbcam.h @@ -61,6 +61,7 @@ class DVBCam : public QRunnable bool pmt_sent; bool pmt_updated; bool pmt_added; + QList progNumAdded; }; #endif // DVBCAM_H diff --git a/mythtv/libs/libmythtv/dvbchannel.cpp b/mythtv/libs/libmythtv/dvbchannel.cpp index 0d6f6bd..5a129e2 100644 --- a/mythtv/libs/libmythtv/dvbchannel.cpp +++ b/mythtv/libs/libmythtv/dvbchannel.cpp @@ -124,7 +124,11 @@ DVBChannel::~DVBChannel() master_map_lock.lockForRead(); MasterMap::iterator mit = master_map.find(devname); if ((*mit).empty()) + { + if (dvbcam->IsRunning()) + dvbcam->Stop(); delete dvbcam; + } dvbcam = NULL; master_map_lock.unlock(); diff --git a/mythtv/libs/libmythtv/dvbrecorder.cpp b/mythtv/libs/libmythtv/dvbrecorder.cpp index 92f3413..7a66648 100644 --- a/mythtv/libs/libmythtv/dvbrecorder.cpp +++ b/mythtv/libs/libmythtv/dvbrecorder.cpp @@ -182,7 +182,10 @@ QString DVBRecorder::GetSIStandard(void) const void DVBRecorder::SetCAMPMT(const ProgramMapTable *pmt) { if (pmt->IsEncrypted(_channel->GetSIStandard())) + { + LOG(VB_DVBCAM, LOG_INFO, LOC + "DVBRecorder SetPMT and decrypt channel"); _channel->SetPMT(pmt); + } } void DVBRecorder::UpdateCAMTimeOffset(void) diff --git a/mythtv/libs/libmythtv/dvbsignalmonitor.cpp b/mythtv/libs/libmythtv/dvbsignalmonitor.cpp index 33bcf26..bdabd6c 100644 --- a/mythtv/libs/libmythtv/dvbsignalmonitor.cpp +++ b/mythtv/libs/libmythtv/dvbsignalmonitor.cpp @@ -17,6 +17,7 @@ #include "cardutil.h" #include "dvbtypes.h" +#include "dvbchannel.h" #include "dvbrecorder.h" #include "dvbstreamhandler.h" @@ -171,13 +172,17 @@ void DVBSignalMonitor::HandlePMT(uint program_num, const ProgramMapTable *pmt) { DTVSignalMonitor::HandlePMT(program_num, pmt); -/* if (pmt->ProgramNumber() == (uint)programNumber) + if (pmt->ProgramNumber() == (uint)programNumber) { - DVBChannel *dvbchannel = GetDVBChannel(); - if (dvbchannel) - dvbchannel->SetPMT(pmt); + if (pmt->IsEncrypted(GetDVBChannel()->GetSIStandard()) && + !ignore_encrypted) + { + LOG(VB_DVBCAM, LOG_INFO, LOC + "DVBSignalmonitor SetPMT and decrypt channel"); + DVBChannel *dvbchannel = GetDVBChannel(); + if (dvbchannel) + dvbchannel->SetPMT(pmt); + } } -*/ } void DVBSignalMonitor::HandleSTT(const SystemTimeTable *stt) diff --git a/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp b/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp index 0191064..448b8c0 100644 --- a/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp +++ b/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp @@ -1821,7 +1821,7 @@ void MPEGStreamData::AddEncryptionTestPID(uint pnum, uint pid, bool isvideo) AddListeningPID(pid); - _encryption_pid_to_info[pid] = CryptInfo((isvideo) ? 10000 : 500, 8); + _encryption_pid_to_info[pid] = CryptInfo((isvideo) ? 1000 : 50, (isvideo) ? 1000 : 50); _encryption_pid_to_pnums[pid].push_back(pnum); _encryption_pnum_to_pids[pnum].push_back(pid);