MythTV  master
channelscan_sm.cpp
Go to the documentation of this file.
1 /* -*- Mode: c++ -*-
2  * vim: set expandtab tabstop=4 shiftwidth=4:
3  *
4  * Original Project
5  * MythTV http://www.mythtv.org
6  *
7  * Copyright (c) 2004, 2005 John Pullan <john@pullan.org>
8  * Copyright (c) 2005 - 2007 Daniel Kristjansson
9  *
10  * Description:
11  * Collection of classes to provide channel scanning functionallity
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27  *
28  */
29 
30 // C includes
31 #include <unistd.h>
32 
33 // C++ includes
34 #include <algorithm>
35 #include <utility>
36 
37 // Qt includes
38 #include <QMutexLocker>
39 #include <QObject>
40 
41 // MythTV includes - General
42 #include "channelscan_sm.h"
43 #include "frequencies.h"
44 #include "scanwizardconfig.h"
45 #include "mythdbcon.h"
46 #include "channelutil.h"
47 #include "cardutil.h"
48 #include "sourceutil.h"
49 #include "mthread.h"
50 #include "mythdb.h"
51 #include "mythlogging.h"
52 
53 // MythTV includes - DTV
54 #include "dtvsignalmonitor.h"
55 #include "scanstreamdata.h"
56 
57 // MythTV includes - ATSC
58 #include "atsctables.h"
59 
60 // MythTV includes - DVB
61 #include "dvbsignalmonitor.h"
62 #include "dvbtables.h"
63 
64 #include "dvbchannel.h"
65 #include "hdhrchannel.h"
66 #include "v4lchannel.h"
67 
71 const std::chrono::milliseconds ChannelScanSM::kDVBTableTimeout = 30s;
73 const std::chrono::milliseconds ChannelScanSM::kATSCTableTimeout = 10s;
75 const std::chrono::milliseconds ChannelScanSM::kMPEGTableTimeout = 15s;
76 
77 // Freesat and Sky
78 static const uint kRegionUndefined = 0xFFFF; // Not regional
79 
80 QString ChannelScanSM::loc(const ChannelScanSM *siscan)
81 {
82  if (siscan && siscan->m_channel)
83  return QString("ChannelScanSM[%1]").arg(siscan->m_channel->GetInputID());
84  return "ChannelScanSM(u)";
85 }
86 
87 #define LOC (ChannelScanSM::loc(this) + ": ")
88 
89 #define kDecryptionTimeout 4250
90 
92 {
93  public:
94  ScannedChannelInfo() = default;
95 
96  bool IsEmpty() const
97  {
98  return m_pats.empty() && m_pmts.empty() &&
99  m_programEncryptionStatus.isEmpty() &&
100  !m_mgt && m_cvcts.empty() &&
101  m_tvcts.empty() && m_nits.empty() &&
102  m_sdts.empty() && m_bats.empty();
103  }
104 
105  // MPEG
108  QMap<uint,uint> m_programEncryptionStatus; // pnum->enc_status
109 
110  // ATSC
111  const MasterGuideTable *m_mgt {nullptr};
114 
115  // DVB
119 };
120 
145  const QString &_cardtype, ChannelBase *_channel,
146  int _sourceID, std::chrono::milliseconds signal_timeout,
147  std::chrono::milliseconds channel_timeout, QString _inputname,
148  bool test_decryption)
149  : // Set in constructor
150  m_scanMonitor(_scan_monitor),
151  m_channel(_channel),
152  m_signalMonitor(SignalMonitor::Init(_cardtype, m_channel->GetInputID(),
153  _channel, true)),
154  m_sourceID(_sourceID),
155  m_signalTimeout(signal_timeout),
156  m_channelTimeout(channel_timeout),
157  m_inputName(std::move(_inputname)),
158  m_testDecryption(test_decryption),
159  // Misc
160  m_analogSignalHandler(new AnalogSignalHandler(this))
161 {
162  m_current = m_scanTransports.end();
163 
164  // Create a stream data for digital signal monitors
165  DTVSignalMonitor* dtvSigMon = GetDTVSignalMonitor();
166  if (dtvSigMon)
167  {
168  LOG(VB_CHANSCAN, LOG_INFO, LOC + "Connecting up DTVSignalMonitor");
169  auto *data = new ScanStreamData();
170 
171  MSqlQuery query(MSqlQuery::InitCon());
172  query.prepare(
173  "SELECT dvb_nit_id, bouquet_id, region_id, lcnoffset "
174  "FROM videosource "
175  "WHERE videosource.sourceid = :SOURCEID");
176  query.bindValue(":SOURCEID", _sourceID);
177  if (!query.exec() || !query.isActive())
178  {
179  MythDB::DBError("ChannelScanSM", query);
180  }
181  else if (query.next())
182  {
183  int nitid = query.value(0).toInt();
184  data->SetRealNetworkID(nitid);
185  LOG(VB_CHANSCAN, LOG_INFO, LOC +
186  QString("Setting NIT-ID to %1").arg(nitid));
187 
188  m_bouquetId = query.value(1).toUInt();
189  m_regionId = query.value(2).toUInt();
190  m_lcnOffset = query.value(3).toUInt();
191  m_nitId = nitid > 0 ? nitid : 0;
192  }
193 
194  LOG(VB_CHANSCAN, LOG_INFO, LOC +
195  QString("Freesat/Sky bouquet_id:%1 region_id:%2")
196  .arg(m_bouquetId).arg(m_regionId));
197 
198  dtvSigMon->SetStreamData(data);
203 
204 #ifdef USING_DVB
205  auto *dvbchannel = dynamic_cast<DVBChannel*>(m_channel);
206  if (dvbchannel && dvbchannel->GetRotor())
208 #endif
209 
210  data->AddMPEGListener(this);
211  data->AddATSCMainListener(this);
212  data->AddDVBMainListener(this);
213  data->AddDVBOtherListener(this);
214  }
215 }
216 
218 {
219  StopScanner();
220  LOG(VB_CHANSCAN, LOG_INFO, LOC + "ChannelScanSM Stopped");
221 
222  ScanStreamData *sd = nullptr;
223  if (GetDTVSignalMonitor())
224  {
226  }
227 
228  if (m_signalMonitor)
229  {
231  delete m_signalMonitor;
232  m_signalMonitor = nullptr;
233  }
234 
235  delete sd;
236 
238  {
239  delete m_analogSignalHandler;
240  m_analogSignalHandler = nullptr;
241  }
242 
244 }
245 
246 void ChannelScanSM::SetAnalog(bool is_analog)
247 {
249 
250  if (is_analog)
252 }
253 
255 {
256  QMutexLocker locker(&m_lock);
257 
258  QString cur_chan = (*m_current).m_friendlyName;
259 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
260  QStringList list = cur_chan.split(" ", QString::SkipEmptyParts);
261 #else
262  QStringList list = cur_chan.split(" ", Qt::SkipEmptyParts);
263 #endif
264  QString freqid = (list.size() >= 2) ? list[1] : cur_chan;
265 
266  QString msg = QObject::tr("Updated Channel %1").arg(cur_chan);
267 
268  if (!ChannelUtil::FindChannel(m_sourceID, freqid))
269  {
270  int chanid = ChannelUtil::CreateChanID(m_sourceID, freqid);
271 
272  QString callsign = QString("%1-%2")
273  .arg(ChannelUtil::GetUnknownCallsign()).arg(chanid);
274 
275  bool ok = ChannelUtil::CreateChannel(
276  0 /* mplexid */,
277  m_sourceID,
278  chanid,
279  callsign,
280  "" /* service name */,
281  freqid /* channum */,
282  0 /* service id */,
283  0 /* ATSC major channel */,
284  0 /* ATSC minor channel */,
285  false /* use on air guide */,
286  kChannelVisible /* visible */,
287  freqid);
288 
289  msg = (ok) ?
290  QObject::tr("Added Channel %1").arg(cur_chan) :
291  QObject::tr("Failed to add channel %1").arg(cur_chan);
292  }
293  else
294  {
295  // nothing to do here, XMLTV has better info
296  }
297 
299 
300  // tell UI we are done with these channels
301  if (m_scanning)
302  {
304  m_waitingForTables = false;
306  m_dvbt2Tried = true;
307  }
308 }
309 
321 bool ChannelScanSM::ScanExistingTransports(uint sourceid, bool follow_nit)
322 {
323  if (m_scanning)
324  return false;
325 
326  m_scanTransports.clear();
327  m_nextIt = m_scanTransports.end();
328 
329  std::vector<uint> multiplexes = SourceUtil::GetMplexIDs(sourceid);
330 
331  if (multiplexes.empty())
332  {
333  LOG(VB_CHANSCAN, LOG_ERR, LOC + "Unable to find any transports for " +
334  QString("sourceid %1").arg(sourceid));
335 
336  return false;
337  }
338 
339  LOG(VB_CHANSCAN, LOG_INFO, LOC +
340  QString("Found %1 transports for ").arg(multiplexes.size()) +
341  QString("sourceid %1").arg(sourceid));
342 
343  for (uint multiplex : multiplexes)
344  AddToList(multiplex);
345 
346  m_extendScanList = follow_nit;
347  m_waitingForTables = false;
349  if (!m_scanTransports.empty())
350  {
351  m_nextIt = m_scanTransports.begin();
352  m_scanning = true;
353  }
354  else
355  {
356  LOG(VB_CHANSCAN, LOG_ERR, LOC +
357  "Unable to find add any transports for " +
358  QString("sourceid %1").arg(sourceid));
359 
360  return false;
361  }
362 
363  return m_scanning;
364 }
365 
366 void ChannelScanSM::LogLines(const QString& string)
367 {
368  if (VERBOSE_LEVEL_CHECK(VB_CHANSCAN, LOG_DEBUG))
369  {
370  QStringList lines = string.split('\n');
371  for (const QString& line : qAsConst(lines))
372  LOG(VB_CHANSCAN, LOG_DEBUG, line);
373  }
374 }
375 
377 {
378  QMutexLocker locker(&m_lock);
379 
380  LOG(VB_CHANSCAN, LOG_INFO, LOC +
381  QString("Got a Program Association Table for %1")
382  .arg((*m_current).m_friendlyName));
383  LogLines(pat->toString());
384 
385  // Add pmts to list, so we can do MPEG scan properly.
387  for (uint i = 0; i < pat->ProgramCount(); ++i)
388  {
389  sd->AddListeningPID(pat->ProgramPID(i));
390  }
391 }
392 
394 {
395  QMutexLocker locker(&m_lock);
396 
397  LOG(VB_CHANSCAN, LOG_INFO, LOC +
398  QString("Got a Conditional Access Table for %1")
399  .arg((*m_current).m_friendlyName));
400  LogLines(cat->toString());
401 }
402 
403 void ChannelScanSM::HandlePMT(uint /*program_num*/, const ProgramMapTable *pmt)
404 {
405  QMutexLocker locker(&m_lock);
406 
407  LOG(VB_CHANSCAN, LOG_INFO, LOC + QString("Got a Program Map Table for %1 program %2 (0x%3)")
408  .arg((*m_current).m_friendlyName).arg(pmt->ProgramNumber())
409  .arg(pmt->ProgramNumber(),4,16,QChar('0')));
410  LogLines(pmt->toString());
411 
413  pmt->IsEncrypted(GetDTVChannel()->GetSIStandard()))
415 
416  UpdateChannelInfo(true);
417 }
418 
420 {
421  QMutexLocker locker(&m_lock);
422 
423  LOG(VB_CHANSCAN, LOG_INFO, LOC +
424  QString("Got a Virtual Channel Table for %1")
425  .arg((*m_current).m_friendlyName));
426  LogLines(vct->toString());
427 
428  for (uint i = 0; !m_currentTestingDecryption && i < vct->ChannelCount(); ++i)
429  {
430  if (vct->IsAccessControlled(i))
431  {
433  }
434  }
435 
436  UpdateChannelInfo(true);
437 }
438 
440 {
441  QMutexLocker locker(&m_lock);
442 
443  LOG(VB_CHANSCAN, LOG_INFO, LOC + QString("Got the Master Guide for %1")
444  .arg((*m_current).m_friendlyName));
445  LogLines(mgt->toString());
446 
447  UpdateChannelInfo(true);
448 }
449 
458 {
459  QMutexLocker locker(&m_lock);
460 
461  LOG(VB_CHANSCAN, LOG_INFO, LOC +
462  QString("Got a Service Description Table for %1 section %2/%3")
463  .arg((*m_current).m_friendlyName)
464  .arg(sdt->Section()).arg(sdt->LastSection()));
465  LogLines(sdt->toString());
466 
467  // If this is Astra 28.2 add start listening for Freesat BAT and SDTo
468  if (!m_setOtherTables && (
471  {
473  SetFreesatAdditionalSI(true);
474  m_setOtherTables = true;
475  // The whole BAT & SDTo group comes round in 10s
476  m_otherTableTimeout = 10s;
477  // Delay processing the SDT until we've seen BATs and SDTos
478  m_otherTableTime = std::chrono::milliseconds(m_timer.elapsed()) + m_otherTableTimeout;
479 
480  LOG(VB_CHANSCAN, LOG_INFO, LOC +
481  QString("SDT has OriginalNetworkID %1, look for "
482  "additional Freesat SI").arg(sdt->OriginalNetworkID()));
483  }
484 
485  if (!m_timer.hasExpired(m_otherTableTime.count()))
486  {
487  // Set the version for the SDT so we see it again.
489  SetVersionSDT(sdt->TSID(), -1, 0);
490  }
491 
492  uint id = sdt->OriginalNetworkID() << 16 | sdt->TSID();
493  m_tsScanned.insert(id);
494 
495  for (uint i = 0; !m_currentTestingDecryption && i < sdt->ServiceCount(); ++i)
496  {
497  if (sdt->IsEncrypted(i))
498  {
500  }
501  }
502 
503  UpdateChannelInfo(true);
504 }
505 
507 {
508  QMutexLocker locker(&m_lock);
509 
510  LOG(VB_CHANSCAN, LOG_INFO, LOC +
511  QString("Got a Network Information Table id %1 for %2 section %3/%4")
512  .arg(nit->NetworkID()).arg((*m_current).m_friendlyName)
513  .arg(nit->Section()).arg(nit->LastSection()));
514  LogLines(nit->toString());
515 
516  UpdateChannelInfo(true);
517 }
518 
520 {
521  QMutexLocker locker(&m_lock);
522 
523  LOG(VB_CHANSCAN, LOG_INFO, LOC +
524  QString("Got a Bouquet Association Table id %1 for %2 section %3/%4")
525  .arg(bat->BouquetID()).arg((*m_current).m_friendlyName)
526  .arg(bat->Section()).arg(bat->LastSection()));
527  LogLines(bat->toString());
528 
529  m_otherTableTime = std::chrono::milliseconds(m_timer.elapsed()) + m_otherTableTimeout;
530 
531  for (uint i = 0; i < bat->TransportStreamCount(); ++i)
532  {
533  uint tsid = bat->TSID(i);
534  uint netid = bat->OriginalNetworkID(i);
535  desc_list_t parsed =
538  // Look for default authority
539  const unsigned char *def_auth =
541  const unsigned char *serv_list =
543 
544  if (def_auth && serv_list)
545  {
546  DefaultAuthorityDescriptor authority(def_auth);
547  ServiceListDescriptor services(serv_list);
548  if (!authority.IsValid() || !services.IsValid())
549  continue;
550 #if 0
551  LOG(VB_CHANSCAN, LOG_DEBUG, LOC +
552  QString("Found default authority '%1' in BAT for services in nid %2 tid %3")
553  .arg(authority.DefaultAuthority())
554  .arg(netid).arg(tsid));
555 #endif
556  for (uint j = 0; j < services.ServiceCount(); ++j)
557  {
558  // If the default authority is given in the SDT this
559  // overrides any definition in the BAT (or in the NIT)
560  LOG(VB_CHANSCAN, LOG_DEBUG, LOC +
561  QString("Found default authority '%1' in BAT for service nid %2 tid %3 sid %4")
562  .arg(authority.DefaultAuthority())
563  .arg(netid).arg(tsid).arg(services.ServiceID(j)));
564  uint64_t index = ((uint64_t)netid << 32) | (tsid << 16) |
565  services.ServiceID(j);
566  if (! m_defAuthorities.contains(index))
567  m_defAuthorities[index] = authority.DefaultAuthority();
568  }
569  }
570  }
571  UpdateChannelInfo(true);
572 }
573 
575 {
576  QMutexLocker locker(&m_lock);
577 
578  LOG(VB_CHANSCAN, LOG_INFO, LOC +
579  QString("Got a Service Description Table (other) for Transport ID %1 section %2/%3")
580  .arg(tsid).arg(sdt->Section()).arg(sdt->LastSection()));
581  LogLines(sdt->toString());
582 
583  m_otherTableTime = std::chrono::milliseconds(m_timer.elapsed()) + m_otherTableTimeout;
584 
585  uint netid = sdt->OriginalNetworkID();
586 
587  for (uint i = 0; i < sdt->ServiceCount(); ++i)
588  {
589  uint serviceId = sdt->ServiceID(i);
590  desc_list_t parsed =
592  sdt->ServiceDescriptorsLength(i));
593  // Look for default authority
594  const unsigned char *def_auth =
596  if (def_auth)
597  {
598  DefaultAuthorityDescriptor authority(def_auth);
599  if (!authority.IsValid())
600  continue;
601 #if 0
602  LOG(VB_CHANSCAN, LOG_DEBUG, LOC +
603  QString("Found default authority '%1' in SDTo for service nid %2 tid %3 sid %4")
604  .arg(authority.DefaultAuthority())
605  .arg(netid).arg(tsid).arg(serviceId));
606 #endif
607  m_defAuthorities[((uint64_t)netid << 32) | (tsid << 16) | serviceId] =
608  authority.DefaultAuthority();
609  }
610  }
611 }
612 
613 void ChannelScanSM::HandleEncryptionStatus(uint pnum, bool encrypted)
614 {
615  QMutexLocker locker(&m_lock);
616 
618 
621 
622  UpdateChannelInfo(true);
623 }
624 
626 {
627  if (!m_currentInfo || m_currentInfo->m_pmts.empty())
628  {
629  LOG(VB_GENERAL, LOG_ERR, LOC + "Can't monitor decryption -- no pmts");
631  return false;
632  }
633 
634  do
635  {
636  uint pnum = 0;
637  QMap<uint, uint>::const_iterator it = m_currentEncryptionStatus.cbegin();
638 #if 0
639  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("%1/%2 checked")
640  .arg(currentEncryptionStatusChecked.size())
641  .arg(currentEncryptionStatus.size()));
642 #endif
643  while (it != m_currentEncryptionStatus.cend())
644  {
645  if (!m_currentEncryptionStatusChecked[it.key()])
646  {
647  pnum = it.key();
648  break;
649  }
650  ++it;
651  }
652 
653  if (!pnum)
654  break;
655 
657 
658  if (!m_testDecryption)
659  {
661  continue;
662  }
663 
664  const ProgramMapTable *pmt = nullptr;
665  for (uint i = 0; !pmt && (i < m_currentInfo->m_pmts.size()); ++i)
666  {
667  pmt = (m_currentInfo->m_pmts[i]->ProgramNumber() == pnum) ?
668  m_currentInfo->m_pmts[i] : nullptr;
669  }
670 
671  if (pmt)
672  {
673  QString cur_chan;
674  QString cur_chan_tr;
675  GetCurrentTransportInfo(cur_chan, cur_chan_tr);
676 
677  QString msg_tr =
678  QObject::tr("Program %1 Testing Decryption")
679  .arg(pnum);
680  QString msg =
681  QString("%1 -- Testing decryption of program %2")
682  .arg(cur_chan).arg(pnum);
683 
685  LOG(VB_CHANSCAN, LOG_INFO, LOC + msg);
686 
687 #ifdef USING_DVB
688  if (GetDVBChannel())
689  GetDVBChannel()->SetPMT(pmt);
690 #endif // USING_DVB
691 
694 
696  m_timer.start();
697  return true;
698  }
699 
700  LOG(VB_GENERAL, LOG_INFO, LOC +
701  QString("Can't monitor decryption of program %1 -- no pmt")
702  .arg(pnum));
703 
704  } while (true);
705 
707  return false;
708 }
709 
711 {
714 
715  const DTVChannel *chan = GetDTVChannel();
716 
717  if (!chan)
718  return type;
719 
720  std::vector<DTVTunerType> tts = chan->GetTunerTypes();
721 
722  for (auto & tt : tts)
723  {
724  if (tt == type)
725  return type;
726  }
727 
728  if (!tts.empty())
729  return tts[0];
730 
731  return type;
732 }
733 
735 {
736  LOG(VB_CHANSCAN, LOG_DEBUG, LOC + QString("%1 NIT nid:%2 fr:%3 section:%4/%5 ts count:%6 ")
737  .arg(__func__).arg(nit->NetworkID()).arg(nit_frequency).arg(nit->Section()).arg(nit->LastSection())
738  .arg(nit->TransportStreamCount()));
739 
740  for (uint i = 0; i < nit->TransportStreamCount(); ++i)
741  {
742  uint32_t tsid = nit->TSID(i);
743  uint32_t netid = nit->OriginalNetworkID(i);
744  uint32_t id = netid << 16 | tsid;
745 
746  if (m_tsScanned.contains(id) || m_extendTransports.contains(id))
747  continue;
748 
749  const desc_list_t& list =
752 
753  for (const auto * const item : list)
754  {
755  uint64_t frequency = 0;
756  const MPEGDescriptor desc(item);
757  uint tag = desc.DescriptorTag();
758 // QString tagString = desc.DescriptorTagString();
759 
761  switch (tag)
762  {
764  {
766  if (cd.IsValid())
767  frequency = cd.FrequencyHz();
769  break;
770  }
772  {
773  switch (desc.DescriptorTagExtension())
774  {
776  {
778  continue; // T2 descriptor not yet used
779  }
780  default:
781  continue; // Next descriptor
782  }
783  }
785  {
786  const SatelliteDeliverySystemDescriptor cd(desc);
787  if (cd.IsValid())
788  frequency = cd.FrequencykHz();
790  break;
791  }
793  {
795  continue; // S2 descriptor not yet used
796  }
798  {
799  const CableDeliverySystemDescriptor cd(desc);
800  if (cd.IsValid())
801  frequency = cd.FrequencyHz();
803  break;
804  }
805  default:
806  continue; // Next descriptor
807  }
808 
809  // Have now a delivery system descriptor
810  tt = GuessDTVTunerType(tt);
811  DTVMultiplex tuning;
812  if (tuning.FillFromDeliverySystemDesc(tt, desc))
813  {
814  LOG(VB_CHANSCAN, LOG_DEBUG, QString("NIT onid:%1 add ts(%2):%3 %4")
815  .arg(netid).arg(i).arg(tsid).arg(tuning.toString()));
816  m_extendTransports[id] = tuning;
817  }
818  else
819  {
820  LOG(VB_CHANSCAN, LOG_DEBUG, QString("NIT onid:%1 cannot add ts(%2):%3 fr:%4")
821  .arg(netid).arg(i).arg(tsid).arg(frequency));
822  }
823 
824  // Next TS in loop
825  break;
826  }
827  }
828 }
829 
830 bool ChannelScanSM::UpdateChannelInfo(bool wait_until_complete)
831 {
832  QMutexLocker locker(&m_mutex);
833 
834  if (m_current == m_scanTransports.end())
835  return true;
836 
837  if (wait_until_complete && !m_waitingForTables)
838  return true;
839 
840  if (wait_until_complete && m_currentTestingDecryption)
841  return false;
842 
844  if (!dtv_sm)
845  return false;
846 
847  const ScanStreamData *sd = dtv_sm->GetScanStreamData();
848 
849  if (!m_currentInfo)
851 
852  bool transport_tune_complete = true;
853 
854  // MPEG
855 
856  // Grab PAT tables
857  pat_vec_t pattmp = sd->GetCachedPATs();
858  QMap<uint,bool> tsid_checked;
859  for (auto & pat : pattmp)
860  {
861  uint tsid = pat->TransportStreamID();
862  if (tsid_checked[tsid])
863  continue;
864  tsid_checked[tsid] = true;
865  if (m_currentInfo->m_pats.contains(tsid))
866  continue;
867 
868  if (!wait_until_complete || sd->HasCachedAllPAT(tsid))
869  {
870  m_currentInfo->m_pats[tsid] = sd->GetCachedPATs(tsid);
871  if (!m_currentInfo->m_pmts.empty())
872  {
874  m_currentInfo->m_pmts.clear();
875  }
876  }
877  else
878  transport_tune_complete = false;
879  }
880  transport_tune_complete &= !pattmp.empty();
881  sd->ReturnCachedPATTables(pattmp);
882 
883  // Grab PMT tables
884  if ((!wait_until_complete || sd->HasCachedAllPMTs()) &&
885  m_currentInfo->m_pmts.empty())
887 
888  // ATSC
889  if (!m_currentInfo->m_mgt && sd->HasCachedMGT())
891 
892  if ((!wait_until_complete || sd->HasCachedAllCVCTs()) &&
893  m_currentInfo->m_cvcts.empty())
894  {
896  }
897 
898  if ((!wait_until_complete || sd->HasCachedAllTVCTs()) &&
899  m_currentInfo->m_tvcts.empty())
900  {
902  }
903 
904  // DVB
905  if ((!wait_until_complete || sd->HasCachedAllNIT()) &&
906  (m_currentInfo->m_nits.empty() ||
907  m_timer.hasExpired(m_otherTableTime.count())))
908  {
910  }
911 
912  sdt_vec_t sdttmp = sd->GetCachedSDTs();
913  tsid_checked.clear();
914  for (auto & sdt : sdttmp)
915  {
916  uint tsid = sdt->TSID();
917  if (tsid_checked[tsid])
918  continue;
919  tsid_checked[tsid] = true;
920  if (m_currentInfo->m_sdts.contains(tsid))
921  continue;
922 
923  if (!wait_until_complete || sd->HasCachedAllSDT(tsid))
924  m_currentInfo->m_sdts[tsid] = sd->GetCachedSDTSections(tsid);
925  }
926  sd->ReturnCachedSDTTables(sdttmp);
927 
928  if ((!wait_until_complete || sd->HasCachedAllBATs()) &&
929  (m_currentInfo->m_bats.empty() ||
930  m_timer.hasExpired(m_otherTableTime.count())))
931  {
933  }
934 
935  // Check if transport tuning is complete
936  if (transport_tune_complete)
937  {
938  transport_tune_complete &= !m_currentInfo->m_pmts.empty();
939 
940  if (!(sd->HasCachedMGT() || sd->HasCachedAnyNIT()))
941  {
942  transport_tune_complete = false;
943  }
944 
945  if (sd->HasCachedMGT() || sd->HasCachedAnyVCTs())
946  {
947  transport_tune_complete &= sd->HasCachedMGT();
948  transport_tune_complete &=
949  (!m_currentInfo->m_tvcts.empty() || !m_currentInfo->m_cvcts.empty());
950  }
951  else if (sd->HasCachedAnyNIT() || sd->HasCachedAnySDTs())
952  {
953  transport_tune_complete &= !m_currentInfo->m_nits.empty();
954  transport_tune_complete &= !m_currentInfo->m_sdts.empty();
955  }
956  if (sd->HasCachedAnyBATs())
957  {
958  transport_tune_complete &= !m_currentInfo->m_bats.empty();
959  }
960  if (transport_tune_complete)
961  {
962  uint tsid = dtv_sm->GetTransportID();
963  LOG(VB_CHANSCAN, LOG_INFO, LOC +
964  QString("\nTable status after transport tune complete:") +
965  QString("\nsd->HasCachedAnyNIT(): %1").arg(sd->HasCachedAnyNIT()) +
966  QString("\nsd->HasCachedAnySDTs(): %1").arg(sd->HasCachedAnySDTs()) +
967  QString("\nsd->HasCachedAnyBATs(): %1").arg(sd->HasCachedAnyBATs()) +
968  QString("\nsd->HasCachedAllPMTs(): %1").arg(sd->HasCachedAllPMTs()) +
969  QString("\nsd->HasCachedAllNIT(): %1").arg(sd->HasCachedAllNIT()) +
970  QString("\nsd->HasCachedAllSDT(%1): %2").arg(tsid,5).arg(sd->HasCachedAllSDT(tsid)) +
971  QString("\nsd->HasCachedAllBATs(): %1").arg(sd->HasCachedAllBATs()) +
972  QString("\nsd->HasCachedMGT(): %1").arg(sd->HasCachedMGT()) +
973  QString("\nsd->HasCachedAnyVCTs(): %1").arg(sd->HasCachedAnyVCTs()) +
974  QString("\nsd->HasCachedAllCVCTs(): %1").arg(sd->HasCachedAllCVCTs()) +
975  QString("\nsd->HasCachedAllTVCTs(): %1").arg(sd->HasCachedAllTVCTs()) +
976  QString("\ncurrentInfo->m_pmts.empty(): %1").arg(m_currentInfo->m_pmts.empty()) +
977  QString("\ncurrentInfo->m_nits.empty(): %1").arg(m_currentInfo->m_nits.empty()) +
978  QString("\ncurrentInfo->m_sdts.empty(): %1").arg(m_currentInfo->m_sdts.empty()) +
979  QString("\ncurrentInfo->m_bats.empty(): %1").arg(m_currentInfo->m_bats.empty()) +
980  QString("\ncurrentInfo->m_cvtcs.empty(): %1").arg(m_currentInfo->m_cvcts.empty()) +
981  QString("\ncurrentInfo->m_tvtcs.empty(): %1").arg(m_currentInfo->m_tvcts.empty()));
982  }
983  }
984  if (!wait_until_complete)
985  transport_tune_complete = true;
986  if (transport_tune_complete)
987  {
988  LOG(VB_CHANSCAN, LOG_INFO, LOC +
989  QString("transport_tune_complete: wait_until_complete %1").arg(wait_until_complete));
990  }
991 
992  if (transport_tune_complete && !m_currentEncryptionStatus.empty())
994  {
995  //GetDTVSignalMonitor()->GetStreamData()->StopTestingDecryption();
996 
998  return false;
999 
1000  QMap<uint, uint>::const_iterator it = m_currentEncryptionStatus.cbegin();
1001  for (; it != m_currentEncryptionStatus.cend(); ++it)
1002  {
1003  m_currentInfo->m_programEncryptionStatus[it.key()] = *it;
1004 
1005  if (m_testDecryption)
1006  {
1007  QString msg_tr1 = QObject::tr("Program %1").arg(it.key());
1008  QString msg_tr2 = QObject::tr("Unknown decryption status");
1009  if (kEncEncrypted == *it)
1010  msg_tr2 = QObject::tr("Encrypted");
1011  else if (kEncDecrypted == *it)
1012  msg_tr2 = QObject::tr("Decrypted");
1013  QString msg_tr =QString("%1 %2").arg(msg_tr1, msg_tr2);
1015  }
1016 
1017  QString msg = QString("Program %1").arg(it.key());
1018  if (kEncEncrypted == *it)
1019  msg = msg + " -- Encrypted";
1020  else if (kEncDecrypted == *it)
1021  msg = msg + " -- Decrypted";
1022  else if (kEncUnknown == *it)
1023  msg = msg + " -- Unknown decryption status";
1024 
1025  LOG(VB_CHANSCAN, LOG_INFO, LOC + msg);
1026  }
1027  }
1028 
1029  // Append transports from the NIT to the scan list
1030  if (transport_tune_complete && m_extendScanList &&
1031  !m_currentInfo->m_nits.empty())
1032  {
1033  // Update transport with delivery system descriptors from the NIT
1034  auto it = m_currentInfo->m_nits.begin();
1035  while (it != m_currentInfo->m_nits.end())
1036  {
1037  UpdateScanTransports((*m_current).m_tuning.m_frequency, *it);
1038  ++it;
1039  }
1040  }
1041 
1042  // Start scanning next transport if we are done with this one..
1043  if (transport_tune_complete)
1044  {
1045  QString cchan;
1046  QString cchan_tr;
1047  uint cchan_cnt = GetCurrentTransportInfo(cchan, cchan_tr);
1048  m_channelsFound += cchan_cnt;
1049  QString chan_tr = QObject::tr("%1 -- Timed out").arg(cchan_tr);
1050  QString chan = QString( "%1 -- Timed out").arg(cchan);
1051  QString msg_tr = "";
1052  QString msg = "";
1053 
1054  if (!m_currentInfo->IsEmpty())
1055  {
1056  TransportScanItem &item = *m_current;
1059  item.m_networkID = dtv_sm->GetNetworkID();
1060  item.m_transportID = dtv_sm->GetTransportID();
1061 
1063  {
1065  {
1067  }
1068  }
1070  {
1072  }
1074  {
1075  if (m_dvbt2Tried)
1077  else
1079  }
1080 
1081  LOG(VB_CHANSCAN, LOG_INFO, LOC +
1082  QString("Adding %1 offset:%2 ss:%3")
1083  .arg(item.m_tuning.toString()).arg(m_current.offset())
1084  .arg(item.m_signalStrength));
1085 
1086  LOG(VB_CHANSCAN, LOG_DEBUG, LOC +
1087  QString("%1(%2) m_inputName: %3 ").arg(__FUNCTION__).arg(__LINE__).arg(m_inputName) +
1088  QString("tunerType:%1 %2 ").arg(m_scanDTVTunerType).arg(m_scanDTVTunerType.toString()) +
1089  QString("m_modSys:%1 %2 ").arg(item.m_tuning.m_modSys).arg(item.m_tuning.m_modSys.toString()) +
1090  QString("m_dvbt2Tried:%1").arg(m_dvbt2Tried));
1091 
1093  m_currentInfo = nullptr;
1094  }
1095  else
1096  {
1097  delete m_currentInfo;
1098  m_currentInfo = nullptr;
1099  }
1100 
1102  if (HasTimedOut())
1103  {
1104  msg_tr = (cchan_cnt) ?
1105  QObject::tr("%1 possible channels").arg(cchan_cnt) :
1106  QObject::tr("no channels");
1107  msg_tr = QString("%1, %2").arg(chan_tr, msg_tr);
1108  msg = (cchan_cnt) ?
1109  QString("%1 possible channels").arg(cchan_cnt) :
1110  QString("no channels");
1111  msg = QString("%1, %2").arg(chan_tr, msg);
1112  }
1113  else if ((m_current != m_scanTransports.end()) &&
1114  m_timer.hasExpired((*m_current).m_timeoutTune.count()) &&
1115  sm && !sm->HasSignalLock())
1116  {
1117  msg_tr = QObject::tr("%1, no signal").arg(chan_tr);
1118  msg = QString("%1, no signal").arg(chan);
1119  }
1120  else
1121  {
1122  msg_tr = QObject::tr("%1 -- Found %2 probable channels")
1123  .arg(cchan_tr).arg(cchan_cnt);
1124 
1125  msg = QString("%1 -- Found %2 probable channels")
1126  .arg(cchan).arg(cchan_cnt);
1127  }
1128 
1130  LOG(VB_CHANSCAN, LOG_INFO, LOC + msg);
1131 
1132  m_currentEncryptionStatus.clear();
1134 
1135  m_setOtherTables = false;
1136  m_otherTableTime = 0ms;
1137 
1138  if (m_scanning)
1139  {
1142  m_waitingForTables = false;
1144  m_dvbt2Tried = true;
1145  }
1146  else
1147  {
1150  }
1151 
1152  return true;
1153  }
1154 
1155  return false;
1156 }
1157 
1158 #define PCM_INFO_INIT(SISTD) \
1159  ChannelInsertInfo &info = pnum_to_dbchan[pnum]; \
1160  info.m_dbMplexId = mplexid; info.m_sourceId = m_sourceID; \
1161  info.m_serviceId = pnum; info.m_freqId = freqidStr; \
1162  info.m_siStandard = SISTD;
1163 
1164 static void update_info(ChannelInsertInfo &info,
1165  const VirtualChannelTable *vct, uint i)
1166 {
1167  if (vct->ModulationMode(i) == 0x01 /* NTSC Modulation */ ||
1168  vct->ServiceType(i) == 0x01 /* Analog TV */)
1169  {
1170  info.m_siStandard = "ntsc";
1171  info.m_format = "ntsc";
1172  }
1173 
1174  info.m_callSign = vct->ShortChannelName(i);
1175 
1176  info.m_serviceName = vct->GetExtendedChannelName(i);
1177  if (info.m_serviceName.isEmpty())
1178  info.m_serviceName = vct->ShortChannelName(i);
1179 
1180  info.m_chanNum.clear();
1181 
1182  info.m_serviceId = vct->ProgramNumber(i);
1183  info.m_atscMajorChannel = vct->MajorChannel(i);
1184  info.m_atscMinorChannel = vct->MinorChannel(i);
1185 
1186  info.m_useOnAirGuide = !vct->IsHidden(i) || !vct->IsHiddenInGuide(i);
1187 
1188  info.m_hidden = vct->IsHidden(i);
1189  info.m_hiddenInGuide = vct->IsHiddenInGuide(i);
1190 
1191  info.m_vctTsId = vct->TransportStreamID();
1192  info.m_vctChanTsId = vct->ChannelTransportStreamID(i);
1193  info.m_isEncrypted |= vct->IsAccessControlled(i);
1194  info.m_isDataService = vct->ServiceType(i) == 0x04;
1195  info.m_isAudioService = vct->ServiceType(i) == 0x03;
1196 
1197  info.m_inVct = true;
1198 }
1199 
1200 static void update_info(ChannelInsertInfo &info,
1201  const ServiceDescriptionTable *sdt, uint i,
1202  const QMap<uint64_t, QString> &defAuthorities)
1203 {
1204  // HACK beg -- special exception for these networks
1205  // this enables useonairguide by default for all matching channels
1206  // (dbver == "1067")
1207  bool force_guide_present = (
1208  // Telenor (NO)
1210 #if 0 // #9592#comment:23 - meanwhile my provider changed his signaling
1211  // Kabelplus (AT) formerly Kabelsignal, registered to NDS, see #9592
1212  (sdt->OriginalNetworkID() == 222) ||
1213 #endif
1214  // ERT (GR) from the private temporary allocation, see #9592:comment:17
1215  (sdt->OriginalNetworkID() == 65330) ||
1216  // Digitenne (NL) see #13427
1218  );
1219  // HACK end -- special exception for these networks
1220 
1221  // Figure out best service name and callsign...
1222  ServiceDescriptor *desc = sdt->GetServiceDescriptor(i);
1223  QString callsign;
1224  QString service_name;
1225  if (desc)
1226  {
1227  callsign = desc->ServiceShortName();
1228  if (callsign.trimmed().isEmpty())
1229  {
1230  callsign = QString("%1-%2-%3")
1231  .arg(ChannelUtil::GetUnknownCallsign()).arg(sdt->TSID())
1232  .arg(sdt->ServiceID(i));
1233  }
1234 
1235  service_name = desc->ServiceName();
1236  if (service_name.trimmed().isEmpty())
1237  service_name.clear();
1238 
1239  info.m_serviceType = desc->ServiceType();
1240  info.m_isDataService =
1241  (desc && !desc->IsDTV() && !desc->IsDigitalAudio());
1242  info.m_isAudioService = (desc && desc->IsDigitalAudio());
1243  delete desc;
1244  }
1245  else
1246  {
1247  LOG(VB_CHANSCAN, LOG_INFO, "ChannelScanSM: " +
1248  QString("No ServiceDescriptor for onid %1 tid %2 sid %3")
1249  .arg(sdt->OriginalNetworkID()).arg(sdt->TSID()).arg(sdt->ServiceID(i)));
1250  }
1251 
1252  if (info.m_callSign.isEmpty())
1253  info.m_callSign = callsign;
1254  if (info.m_serviceName.isEmpty())
1255  info.m_serviceName = service_name;
1256 
1257  info.m_useOnAirGuide =
1258  sdt->HasEITPresentFollowing(i) ||
1259  sdt->HasEITSchedule(i) ||
1260  force_guide_present;
1261 
1262  info.m_hidden = false;
1263  info.m_hiddenInGuide = false;
1264  info.m_serviceId = sdt->ServiceID(i);
1265  info.m_sdtTsId = sdt->TSID();
1266  info.m_origNetId = sdt->OriginalNetworkID();
1267  info.m_inSdt = true;
1268 
1269  desc_list_t parsed =
1271  sdt->ServiceDescriptorsLength(i));
1272  // Look for default authority
1273  const unsigned char *def_auth =
1275  if (def_auth)
1276  {
1277  DefaultAuthorityDescriptor authority(def_auth);
1278  if (authority.IsValid())
1279  {
1280 #if 0
1281  LOG(VB_CHANSCAN, LOG_DEBUG,
1282  QString("ChannelScanSM: Found default authority '%1' in SDT for service onid %2 tid %3 sid %4")
1283  .arg(authority.DefaultAuthority())
1284  .arg(info.m_origNetId).arg(info.m_sdtTsId).arg(info.m_serviceId));
1285 #endif
1286  info.m_defaultAuthority = authority.DefaultAuthority();
1287  return;
1288  }
1289  }
1290 
1291  // If no authority in the SDT then use the one found in the BAT or the SDTo
1292  uint64_t index = (uint64_t)info.m_origNetId << 32 |
1293  info.m_sdtTsId << 16 | info.m_serviceId;
1294  if (defAuthorities.contains(index))
1295  info.m_defaultAuthority = defAuthorities[index];
1296 
1297  // Is this service relocated from somewhere else?
1299  if (srdesc)
1300  {
1301  info.m_oldOrigNetId = srdesc->OldOriginalNetworkID();
1302  info.m_oldTsId = srdesc->OldTransportID();
1303  info.m_oldServiceId = srdesc->OldServiceID();
1304 
1305  LOG(VB_CHANSCAN, LOG_DEBUG, "ChannelScanSM: " +
1306  QString("Service '%1' onid:%2 tid:%3 sid:%4 ")
1307  .arg(info.m_serviceName)
1308  .arg(info.m_origNetId)
1309  .arg(info.m_sdtTsId)
1310  .arg(info.m_serviceId) +
1311  QString(" relocated from onid:%1 tid:%2 sid:%3")
1312  .arg(info.m_oldOrigNetId)
1313  .arg(info.m_oldTsId)
1314  .arg(info.m_oldServiceId));
1315 
1316  delete srdesc;
1317  }
1318 
1319 }
1320 
1322  QString &cur_chan, QString &cur_chan_tr) const
1323 {
1324  if (m_current.iter() == m_scanTransports.end())
1325  {
1326  cur_chan.clear();
1327  cur_chan_tr.clear();
1328  return 0;
1329  }
1330 
1331  uint max_chan_cnt = 0;
1332 
1333  QMap<uint,ChannelInsertInfo> list = GetChannelList(m_current, m_currentInfo);
1334  {
1335  for (const auto & info : qAsConst(list))
1336  {
1337  max_chan_cnt +=
1338  (info.m_inPat || info.m_inPmt ||
1339  info.m_inSdt || info.m_inVct) ? 1 : 0;
1340  }
1341  }
1342 
1343  QString offset_str_tr = m_current.offset() ?
1344  QObject::tr(" offset %2").arg(m_current.offset()) : "";
1345  cur_chan_tr = QString("%1%2")
1346  .arg((*m_current).m_friendlyName, offset_str_tr);
1347 
1348  QString offset_str = m_current.offset() ?
1349  QString(" offset %2").arg(m_current.offset()) : "";
1350  cur_chan = QString("%1%2")
1351  .arg((*m_current).m_friendlyName, offset_str);
1352 
1353  return max_chan_cnt;
1354 }
1355 
1356 QMap<uint,ChannelInsertInfo>
1358  ScannedChannelInfo *scan_info) const
1359 {
1360  QMap<uint,ChannelInsertInfo> pnum_to_dbchan;
1361 
1362  uint mplexid = (*trans_info).m_mplexid;
1363  int freqid = (*trans_info).m_friendlyNum;
1364  QString freqidStr = (freqid) ? QString::number(freqid) : QString("");
1365  QString iptv_channel = (*trans_info).m_iptvChannel;
1366 
1367  // channels.conf
1368  const DTVChannelInfoList &echan = (*trans_info).m_expectedChannels;
1369  for (const auto & chan : echan)
1370  {
1371  uint pnum = chan.m_serviceid;
1372  PCM_INFO_INIT("mpeg");
1373  info.m_serviceName = chan.m_name;
1374  info.m_inChannelsConf = true;
1375  }
1376 
1377  // PATs
1378  for (const auto& pat_list : qAsConst(scan_info->m_pats))
1379  {
1380  for (const auto *pat : pat_list)
1381  {
1382  bool could_be_opencable = false;
1383  for (uint i = 0; i < pat->ProgramCount(); ++i)
1384  {
1385  if ((pat->ProgramNumber(i) == 0) &&
1386  (pat->ProgramPID(i) == PID::SCTE_PSIP_PID))
1387  {
1388  could_be_opencable = true;
1389  }
1390  }
1391 
1392  for (uint i = 0; i < pat->ProgramCount(); ++i)
1393  {
1394  uint pnum = pat->ProgramNumber(i);
1395  if (pnum)
1396  {
1397  PCM_INFO_INIT("mpeg");
1398  info.m_patTsId = pat->TransportStreamID();
1399  info.m_couldBeOpencable = could_be_opencable;
1400  info.m_inPat = true;
1401  }
1402  }
1403  }
1404  }
1405 
1406  // PMTs
1407  for (const auto *pmt : scan_info->m_pmts)
1408  {
1409  uint pnum = pmt->ProgramNumber();
1410  PCM_INFO_INIT("mpeg");
1411  for (uint i = 0; i < pmt->StreamCount(); ++i)
1412  {
1413  info.m_couldBeOpencable |=
1414  (StreamID::OpenCableVideo == pmt->StreamType(i));
1415  }
1416 
1418  pmt->ProgramInfo(), pmt->ProgramInfoLength(),
1420 
1421  for (auto & desc : descs)
1422  {
1423  RegistrationDescriptor reg(desc);
1424  if (!reg.IsValid())
1425  continue;
1426  if (reg.FormatIdentifierString() == "CUEI" ||
1427  reg.FormatIdentifierString() == "SCTE")
1428  info.m_couldBeOpencable = true;
1429  }
1430 
1431  info.m_isEncrypted |= pmt->IsEncrypted(GetDTVChannel()->GetSIStandard());
1432  info.m_inPmt = true;
1433  }
1434 
1435  // Cable VCTs
1436  for (const auto *cvct : scan_info->m_cvcts)
1437  {
1438  for (uint i = 0; i < cvct->ChannelCount(); ++i)
1439  {
1440  uint pnum = cvct->ProgramNumber(i);
1441  PCM_INFO_INIT("atsc");
1442  update_info(info, cvct, i);
1443 
1444  // One-part channel number, as defined in the ATSC Standard:
1445  // Program and System Information Protocol for Terrestrial Broadcast and Cable
1446  // Doc. A65/2013 7 August 2013 page 35
1447  if ((info.m_atscMajorChannel & 0x3F0) == 0x3F0)
1448  {
1449  info.m_chanNum = QString::number(((info.m_atscMajorChannel & 0x00F) << 10) + info.m_atscMinorChannel);
1450  }
1451  }
1452  }
1453 
1454  // Terrestrial VCTs
1455  for (const auto *tvct : scan_info->m_tvcts)
1456  {
1457  for (uint i = 0; i < tvct->ChannelCount(); ++i)
1458  {
1459  uint pnum = tvct->ProgramNumber(i);
1460  PCM_INFO_INIT("atsc");
1461  update_info(info, tvct, i);
1462  }
1463  }
1464 
1465  // SDTs
1466  QString siStandard = (scan_info->m_mgt == nullptr) ? "dvb" : "atsc";
1467  for (const auto& sdt_list : qAsConst(scan_info->m_sdts))
1468  {
1469  for (const auto *sdt_it : sdt_list)
1470  {
1471  for (uint i = 0; i < sdt_it->ServiceCount(); ++i)
1472  {
1473  uint pnum = sdt_it->ServiceID(i);
1474  PCM_INFO_INIT(siStandard);
1475  update_info(info, sdt_it, i, m_defAuthorities);
1476  }
1477  }
1478  }
1479 
1480  // NIT
1481  QMap<qlonglong, uint> ukChanNums;
1482  QMap<qlonglong, uint> scnChanNums;
1483  QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
1484  for (dbchan_it = pnum_to_dbchan.begin();
1485  dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1486  {
1487  ChannelInsertInfo &info = *dbchan_it;
1488 
1489  // NIT
1490  for (const auto *item : scan_info->m_nits)
1491  {
1492  for (uint i = 0; i < item->TransportStreamCount(); ++i)
1493  {
1494  const NetworkInformationTable *nit = item;
1495  if ((nit->TSID(i) == info.m_sdtTsId) &&
1496  (nit->OriginalNetworkID(i) == info.m_origNetId))
1497  {
1498  info.m_netId = nit->NetworkID();
1499  info.m_inNit = true;
1500  }
1501  else
1502  {
1503  continue;
1504  }
1505 
1506  // Descriptors in the transport stream loop of this transport in the NIT
1507  const desc_list_t &list =
1509  nit->TransportDescriptorsLength(i));
1510 
1511  // Presence of T2 delivery system descriptor indicates DVB-T2 delivery system
1512  // DVB BlueBook A038 (Feb 2019) page 104, paragraph 6.4.6.3
1513  {
1514  const unsigned char *desc =
1517 
1518  if (desc)
1519  {
1520  T2DeliverySystemDescriptor t2tdsd(desc);
1521  if (t2tdsd.IsValid())
1522  {
1523  (*trans_info).m_tuning.m_modSys = DTVModulationSystem::kModulationSystem_DVBT2;
1524  }
1525  }
1526  }
1527 
1528  // Logical channel numbers
1529  {
1530  const unsigned char *desc =
1533 
1534  if (desc)
1535  {
1536  DVBLogicalChannelDescriptor uklist(desc);
1537  if (!uklist.IsValid())
1538  continue;
1539  for (uint j = 0; j < uklist.ChannelCount(); ++j)
1540  {
1541  ukChanNums[((qlonglong)info.m_origNetId<<32) |
1542  uklist.ServiceID(j)] =
1543  uklist.ChannelNumber(j);
1544  }
1545  }
1546  }
1547 
1548  // HD Simulcast logical channel numbers
1549  {
1550  const unsigned char *desc =
1553 
1554  if (desc)
1555  {
1556  DVBSimulcastChannelDescriptor scnlist(desc);
1557  if (!scnlist.IsValid())
1558  continue;
1559  for (uint j = 0; j < scnlist.ChannelCount(); ++j)
1560  {
1561  scnChanNums[((qlonglong)info.m_origNetId<<32) |
1562  scnlist.ServiceID(j)] =
1563  scnlist.ChannelNumber(j);
1564  }
1565  }
1566  }
1567  }
1568  }
1569  }
1570 
1571  // BAT
1572 
1573  // Channel numbers for Freesat and Sky on Astra 28.2E
1574  //
1575  // Get the Logical Channel Number (LCN) information from the BAT.
1576  // The first filter is on the bouquet ID.
1577  // Then collect all LCN for the selected region and
1578  // for the common (undefined) region with id 0xFFFF.
1579  // The LCN of the selected region has priority; if
1580  // a service is not defined there then the value of the LCN
1581  // table of the common region is used.
1582  // This works because the BAT of each transport contains
1583  // the LCN of all transports and services for all bouquets.
1584  //
1585  // For reference, this website has the Freesat and Sky channel numbers
1586  // for each bouquet and region:
1587  // https://www.satellite-calculations.com/DVB/28.2E/28E_FreeSat_ChannelNumber.php
1588  // https://www.satellite-calculations.com/DVB/28.2E/28E_Sky_ChannelNumber.php
1589  //
1590 
1591  // Lookup table from LCN to service ID
1592  QMap<uint,qlonglong> lcn_sid;
1593 
1594  for (const auto *bat : scan_info->m_bats)
1595  {
1596  // Only the bouquet selected by user
1597  if (bat->BouquetID() != m_bouquetId)
1598  continue;
1599 
1600  for (uint t = 0; t < bat->TransportStreamCount(); ++t)
1601  {
1602  uint netid = bat->OriginalNetworkID(t);
1603 
1604  // No network check to allow scanning on all Sky satellites
1605 #if 0
1606  if (!(netid == OriginalNetworkID::SES2 ||
1607  netid == OriginalNetworkID::BBC ||
1608  netid == OriginalNetworkID::SKYNZ ))
1609  continue;
1610 #endif
1611  desc_list_t parsed =
1612  MPEGDescriptor::Parse(bat->TransportDescriptors(t),
1613  bat->TransportDescriptorsLength(t));
1614 
1615  uint priv_dsid = 0;
1616  for (const auto *item : parsed)
1617  {
1618  if (item[0] == DescriptorID::private_data_specifier)
1619  {
1621  if (pd.IsValid())
1622  priv_dsid = pd.PrivateDataSpecifier();
1623  }
1624 
1625  // Freesat logical channels
1626  if (priv_dsid == PrivateDataSpecifierID::FSAT &&
1628  {
1629  FreesatLCNDescriptor ld(item);
1630  if (ld.IsValid())
1631  {
1632  for (uint i = 0; i<ld.ServiceCount(); i++)
1633  {
1634  uint service_id = ld.ServiceID(i);
1635  for (uint j=0; j<ld.LCNCount(i); j++)
1636  {
1637  uint region_id = ld.RegionID(i,j);
1638  uint lcn = ld.LogicalChannelNumber(i,j);
1639  if (region_id == m_regionId)
1640  {
1641  lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1642  }
1643  else if (region_id == kRegionUndefined)
1644  {
1645  if (lcn_sid.value(lcn,0) == 0)
1646  lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1647  }
1648  }
1649  }
1650  }
1651  }
1652 
1653  // Sky logical channels
1654  if (priv_dsid == PrivateDataSpecifierID::BSB1 &&
1656  {
1657  SkyLCNDescriptor ld(item);
1658  if (ld.IsValid())
1659  {
1660  uint region_id = ld.RegionID();
1661  for (uint i = 0; i<ld.ServiceCount(); i++)
1662  {
1663  uint service_id = ld.ServiceID(i);
1664  uint lcn = ld.LogicalChannelNumber(i);
1665  if (region_id == m_regionId)
1666  {
1667  lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1668  }
1669  else if (region_id == kRegionUndefined)
1670  {
1671  if (lcn_sid.value(lcn,0) == 0)
1672  lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1673  }
1674 #if 0
1675  LOG(VB_CHANSCAN, LOG_INFO, LOC +
1676  QString("LCN bid:%1 tid:%2 rid:%3 sid:%4 lcn:%5")
1677  .arg(bat->BouquetID()).arg(bat->TSID(t)).arg(region_id).arg(service_id).arg(lcn));
1678 #endif
1679  }
1680  }
1681  }
1682  }
1683  }
1684  }
1685 
1686  // Create the reverse table from service id to LCN.
1687  // If the service has more than one logical
1688  // channel number the lowest number is used.
1689  QMap<qlonglong, uint> sid_lcn;
1690  QMap<uint, qlonglong>::const_iterator r = lcn_sid.constEnd();
1691  while (r != lcn_sid.constBegin())
1692  {
1693  --r;
1694  qlonglong sid = r.value();
1695  uint lcn = r.key();
1696  sid_lcn[sid] = lcn;
1697  }
1698 
1699  // ------------------------------------------------------------------------
1700 
1701  // Get IPTV channel numbers
1702  for (dbchan_it = pnum_to_dbchan.begin();
1703  dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1704  {
1705  ChannelInsertInfo &info = *dbchan_it;
1706 
1707  if (!info.m_chanNum.isEmpty())
1708  continue;
1709 
1710  if (!iptv_channel.isEmpty())
1711  {
1712  info.m_chanNum = iptv_channel;
1713  if (info.m_serviceId)
1714  info.m_chanNum += "-" + QString::number(info.m_serviceId);
1715  }
1716  }
1717 
1718  // Get DVB Logical Channel Numbers
1719  for (dbchan_it = pnum_to_dbchan.begin();
1720  dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1721  {
1722  ChannelInsertInfo &info = *dbchan_it;
1723 
1724  if (!info.m_chanNum.isEmpty())
1725  continue;
1726 
1727  // DVB HD Simulcast channel numbers
1728  //
1729  // The HD simulcast channel number table gives the correct channel number
1730  // when HD and SD versions of the same channel are simultaneously broadcast
1731  // and the receiver is capable of receiving the HD signal.
1732  // The latter is assumed correct for a MythTV system.
1733  //
1734  if (info.m_chanNum.isEmpty())
1735  {
1736  qlonglong key = ((qlonglong)info.m_origNetId<<32) | info.m_serviceId;
1737  QMap<qlonglong, uint>::const_iterator it = scnChanNums.constFind(key);
1738 
1739  if (it != scnChanNums.constEnd())
1740  {
1741  info.m_chanNum = QString::number(*it + m_lcnOffset);
1742  }
1743  }
1744 
1745  // DVB Logical Channel Numbers (a.k.a. UK channel numbers)
1746  if (info.m_chanNum.isEmpty())
1747  {
1748  qlonglong key = ((qlonglong)info.m_origNetId<<32) | info.m_serviceId;
1749  QMap<qlonglong, uint>::const_iterator it = ukChanNums.constFind(key);
1750 
1751  if (it != ukChanNums.constEnd())
1752  {
1753  info.m_chanNum = QString::number(*it + m_lcnOffset);
1754  }
1755  }
1756 
1757  // Freesat and Sky channel numbers
1758  if (info.m_chanNum.isEmpty())
1759  {
1760  qlonglong key = ((qlonglong)info.m_origNetId<<32) | info.m_serviceId;
1761  QMap<qlonglong, uint>::const_iterator it = sid_lcn.constFind(key);
1762 
1763  if (it != sid_lcn.constEnd())
1764  {
1765  info.m_chanNum = QString::number(*it + m_lcnOffset);
1766  }
1767  }
1768 
1769  LOG(VB_CHANSCAN, LOG_INFO, LOC +
1770  QString("GetChannelList: service %1 (0x%2) chan_num '%3' callsign '%4'")
1771  .arg(info.m_serviceId).arg(info.m_serviceId,4,16,QChar('0'))
1772  .arg(info.m_chanNum, info.m_callSign));
1773  }
1774 
1775  // Get QAM/SCTE/MPEG channel numbers
1776  for (dbchan_it = pnum_to_dbchan.begin();
1777  dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1778  {
1779  ChannelInsertInfo &info = *dbchan_it;
1780 
1781  if (!info.m_chanNum.isEmpty())
1782  continue;
1783 
1784  if ((info.m_siStandard == "mpeg") ||
1785  (info.m_siStandard == "scte") ||
1786  (info.m_siStandard == "opencable"))
1787  {
1788  if (info.m_freqId.isEmpty())
1789  {
1790  info.m_chanNum = QString("%1-%2")
1791  .arg(info.m_sourceId)
1792  .arg(info.m_serviceId);
1793  }
1794  else
1795  {
1796  info.m_chanNum = QString("%1-%2")
1797  .arg(info.m_freqId)
1798  .arg(info.m_serviceId);
1799  }
1800  }
1801  }
1802 
1803  // Check for decryption success
1804  for (dbchan_it = pnum_to_dbchan.begin();
1805  dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1806  {
1807  uint pnum = dbchan_it.key();
1808  ChannelInsertInfo &info = *dbchan_it;
1809  info.m_decryptionStatus = scan_info->m_programEncryptionStatus[pnum];
1810  }
1811 
1812  return pnum_to_dbchan;
1813 }
1814 
1816 {
1817  ScanDTVTransportList list;
1818 
1819  uint cardid = m_channel->GetInputID();
1820 
1822  tuner_type = GuessDTVTunerType(tuner_type);
1823 
1824  for (const auto & it : qAsConst(m_channelList))
1825  {
1826  QMap<uint,ChannelInsertInfo> pnum_to_dbchan =
1827  GetChannelList(it.first, it.second);
1828 
1829  ScanDTVTransport item((*it.first).m_tuning, tuner_type, cardid);
1830  item.m_iptvTuning = (*(it.first)).m_iptvTuning;
1831  item.m_signalStrength = (*(it.first)).m_signalStrength;
1832  item.m_networkID = (*(it.first)).m_networkID;
1833  item.m_transportID = (*(it.first)).m_transportID;
1834 
1835  QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
1836  for (dbchan_it = pnum_to_dbchan.begin();
1837  dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1838  {
1839  item.m_channels.push_back(*dbchan_it);
1840  }
1841 
1842  if (!item.m_channels.empty())
1843  {
1844  if (addFullTS)
1845  {
1846  /* If addFullTS, then add a 'MPTS' channel
1847  which can be used to record the entire MPTS from
1848  the transport. */
1849  dbchan_it = pnum_to_dbchan.begin();
1850  ChannelInsertInfo info = *dbchan_it;
1851 
1852  // Use transport stream ID as (fake) service ID
1853  // to use in callsign and as channel number
1854  info.m_serviceId = info.m_sdtTsId ? info.m_sdtTsId : info.m_patTsId;
1855 
1856  if (tuner_type == DTVTunerType::kTunerTypeASI)
1857  {
1858  info.m_callSign = QString("MPTS_%1")
1859  .arg(CardUtil::GetDisplayName(cardid));
1860  }
1861  else if (info.m_siStandard == "mpeg" ||
1862  info.m_siStandard == "scte" ||
1863  info.m_siStandard == "opencable")
1864  {
1865  info.m_callSign = QString("MPTS_%1").arg(info.m_freqId);
1866  }
1867  else if (info.m_atscMajorChannel > 0)
1868  {
1869  if (info.m_atscMajorChannel < 0x3F0)
1870  {
1871  info.m_callSign = QString("MPTS_%1").arg(info.m_atscMajorChannel);
1872  }
1873  else
1874  {
1875  info.m_callSign = QString("MPTS_%1").arg(info.m_freqId);
1876  }
1877  }
1878  else if (info.m_serviceId > 0)
1879  {
1880  info.m_callSign = QString("MPTS_%1").arg(info.m_serviceId);
1881  }
1882  else if (!info.m_chanNum.isEmpty())
1883  {
1884  info.m_callSign = QString("MPTS_%1").arg(info.m_chanNum);
1885  }
1886  else
1887  {
1888  info.m_callSign = "MPTS_UNKNOWN";
1889  }
1890 
1891  info.m_serviceName = info.m_callSign;
1892  info.m_atscMinorChannel = 0;
1893  info.m_format = "MPTS";
1894  info.m_useOnAirGuide = false;
1895  info.m_isEncrypted = false;
1896  item.m_channels.push_back(info);
1897  }
1898 
1899  list.push_back(item);
1900  }
1901  }
1902 
1903  return list;
1904 }
1905 
1907 {
1908  return dynamic_cast<DTVSignalMonitor*>(m_signalMonitor);
1909 }
1910 
1912 {
1913 #ifdef USING_DVB
1914  return dynamic_cast<DVBSignalMonitor*>(m_signalMonitor);
1915 #else
1916  return nullptr;
1917 #endif
1918 }
1919 
1921 {
1922  return dynamic_cast<DTVChannel*>(m_channel);
1923 }
1924 
1926 {
1927  return dynamic_cast<const DTVChannel*>(m_channel);
1928 }
1929 
1931 {
1932 #ifdef USING_HDHOMERUN
1933  return dynamic_cast<HDHRChannel*>(m_channel);
1934 #else
1935  return nullptr;
1936 #endif
1937 }
1938 
1940 {
1941 #ifdef USING_DVB
1942  return dynamic_cast<DVBChannel*>(m_channel);
1943 #else
1944  return nullptr;
1945 #endif
1946 }
1947 
1949 {
1950 #ifdef USING_DVB
1951  return dynamic_cast<const DVBChannel*>(m_channel);
1952 #else
1953  return nullptr;
1954 #endif
1955 }
1956 
1958 {
1959 #ifdef USING_V4L2
1960  return dynamic_cast<V4LChannel*>(m_channel);
1961 #else
1962  return nullptr;
1963 #endif
1964 }
1965 
1970 {
1971  while (m_scannerThread)
1972  {
1973  m_threadExit = true;
1974  if (m_scannerThread->wait(1s))
1975  {
1976  delete m_scannerThread;
1977  m_scannerThread = nullptr;
1978  }
1979  }
1980  m_threadExit = false;
1981  m_scannerThread = new MThread("Scanner", this);
1983 }
1984 
1989 {
1990  LOG(VB_CHANSCAN, LOG_INFO, LOC + "run -- begin");
1991 
1992  while (!m_threadExit)
1993  {
1994  if (m_scanning)
1995  HandleActiveScan();
1996 
1997  usleep(10 * 1000);
1998  }
1999 
2000  LOG(VB_CHANSCAN, LOG_INFO, LOC + "run -- end");
2001 }
2002 
2003 // See if we have timed out
2005 {
2007  m_timer.hasExpired(kDecryptionTimeout))
2008  {
2010  return true;
2011  }
2012 
2013  if (!m_waitingForTables)
2014  return true;
2015 
2016 #ifdef USING_DVB
2017  // If the rotor is still moving, reset the timer and keep waiting
2019  if (sigmon)
2020  {
2021  const DiSEqCDevRotor *rotor = GetDVBChannel()->GetRotor();
2022  if (rotor)
2023  {
2024  bool was_moving = false;
2025  bool is_moving = false;
2026  sigmon->GetRotorStatus(was_moving, is_moving);
2027  if (was_moving && !is_moving)
2028  {
2029  m_timer.restart();
2030  return false;
2031  }
2032  }
2033  }
2034 #endif // USING_DVB
2035 
2036  // have the tables have timed out?
2037  if (m_timer.hasExpired(m_channelTimeout.count()))
2038  {
2039  // the channelTimeout alone is only valid if we have seen no tables..
2040  const ScanStreamData *sd = nullptr;
2041  if (GetDTVSignalMonitor())
2043 
2044  if (!sd)
2045  return true;
2046 
2047  if (sd->HasCachedAnyNIT() || sd->HasCachedAnySDTs())
2048  return m_timer.hasExpired(kDVBTableTimeout.count());
2049  if (sd->HasCachedMGT() || sd->HasCachedAnyVCTs())
2050  return m_timer.hasExpired(kATSCTableTimeout.count());
2051  if (sd->HasCachedAnyPAT() || sd->HasCachedAnyPMTs())
2052  return m_timer.hasExpired(kMPEGTableTimeout.count());
2053 
2054  return true;
2055  }
2056 
2057  // ok the tables haven't timed out, but have we hit the signal timeout?
2059  if (m_timer.hasExpired((*m_current).m_timeoutTune.count()) &&
2060  sm && !sm->HasSignalLock())
2061  {
2062  const ScanStreamData *sd = nullptr;
2063  if (GetDTVSignalMonitor())
2065 
2066  if (!sd)
2067  return true;
2068 
2069  // Just is case we temporarily lose the signal after we've seen
2070  // tables...
2071  if (!sd->HasCachedAnyPAT() && !sd->HasCachedAnyPMTs() &&
2072  !sd->HasCachedMGT() && !sd->HasCachedAnyVCTs() &&
2073  !sd->HasCachedAnyNIT() && !sd->HasCachedAnySDTs())
2074  {
2075  return true;
2076  }
2077  }
2078 
2079  return false;
2080 }
2081 
2086 {
2087  QMutexLocker locker(&m_lock);
2088 
2089  bool do_post_insertion = m_waitingForTables;
2090 
2091  if (!HasTimedOut())
2092  return;
2093 
2094  if (0 == m_nextIt.offset() && m_nextIt == m_scanTransports.begin())
2095  {
2096  m_channelList.clear();
2097  m_channelsFound = 0;
2098  m_dvbt2Tried = true;
2099  }
2100 
2102  {
2103  // If we failed to get a lock with DVB-T try DVB-T2.
2104  m_dvbt2Tried = true;
2106  return;
2107  }
2108 
2109  if (0 == m_nextIt.offset() && m_nextIt != m_scanTransports.begin())
2110  {
2111  // Add channel to scanned list and potentially check decryption
2112  if (do_post_insertion && !UpdateChannelInfo(false))
2113  return;
2114 
2115  // Stop signal monitor for previous transport
2116  locker.unlock();
2117  m_signalMonitor->Stop();
2118  locker.relock();
2119  }
2120 
2121  m_current = m_nextIt; // Increment current
2122  m_dvbt2Tried = false;
2123 
2124  if (m_current != m_scanTransports.end())
2125  {
2127 
2128  // Increment nextIt
2129  m_nextIt = m_current;
2130  ++m_nextIt;
2131  }
2132  else if (!m_extendTransports.isEmpty())
2133  {
2134  --m_current;
2135  QMap<uint32_t,DTVMultiplex>::iterator it = m_extendTransports.begin();
2136  while (it != m_extendTransports.end())
2137  {
2138  if (!m_tsScanned.contains(it.key()))
2139  {
2140  QString name = QString("TransportID %1").arg(it.key() & 0xffff);
2141  TransportScanItem item(m_sourceID, name, *it, m_signalTimeout);
2142  LOG(VB_CHANSCAN, LOG_INFO, LOC + "Adding " + name + ' ' + item.m_tuning.toString());
2143  m_scanTransports.push_back(item);
2144  m_tsScanned.insert(it.key());
2145  }
2146  ++it;
2147  }
2148  m_extendTransports.clear();
2149  m_nextIt = m_current;
2150  ++m_nextIt;
2151  }
2152  else
2153  {
2155  m_scanning = false;
2157  }
2158 }
2159 
2161 {
2162  const TransportScanItem &item = *transport;
2163 
2164 #ifdef USING_DVB
2166  if (monitor)
2167  {
2168  // always wait for rotor to finish
2170  monitor->SetRotorTarget(1.0F);
2171  }
2172 #endif // USING_DVB
2173 
2174  DTVChannel *channel = GetDTVChannel();
2175  if (!channel)
2176  return false;
2177 
2178  if (item.m_mplexid > 0 && transport.offset() == 0)
2179  return channel->TuneMultiplex(item.m_mplexid, m_inputName);
2180 
2181  if (item.m_tuning.m_sistandard == "MPEG")
2182  return channel->Tune(item.m_iptvTuning, true);
2183 
2184  const uint64_t freq = item.freq_offset(transport.offset());
2185  DTVMultiplex tuning = item.m_tuning;
2186  tuning.m_frequency = freq;
2187 
2189  {
2191  }
2193  {
2194  if (m_dvbt2Tried)
2196  else
2198  }
2199 
2200  return channel->Tune(tuning);
2201 }
2202 
2204 {
2205  QString offset_str = (transport.offset()) ?
2206  QObject::tr(" offset %2").arg(transport.offset()) : "";
2207  QString cur_chan = QString("%1%2")
2208  .arg((*m_current).m_friendlyName, offset_str);
2209  QString tune_msg_str =
2210  QObject::tr("ScanTransport Tuning to %1 mplexid(%2)")
2211  .arg(cur_chan).arg((*m_current).m_mplexid);
2212 
2213  const TransportScanItem &item = *transport;
2214 
2215  if (transport.offset() &&
2216  (item.freq_offset(transport.offset()) == item.freq_offset(0)))
2217  {
2218  m_waitingForTables = false;
2219  return; // nothing to do
2220  }
2221 
2222  if (m_channelsFound)
2223  {
2224  QString progress = QObject::tr("Found %n", "", m_channelsFound);
2226  }
2227 
2229  LOG(VB_CHANSCAN, LOG_INFO, LOC + tune_msg_str);
2230 
2231  if (!Tune(transport))
2232  { // If we did not tune successfully, bail with message
2234  LOG(VB_CHANSCAN, LOG_ERR, LOC +
2235  QString("Failed to tune %1 mplexid(%2) at offset %3")
2236  .arg(item.m_friendlyName).arg(item.m_mplexid)
2237  .arg(transport.offset()));
2238  return;
2239  }
2240 
2241  // If we have a DTV Signal Monitor, perform table scanner reset
2242  if (GetDTVSignalMonitor() && GetDTVSignalMonitor()->GetScanStreamData())
2243  {
2245  GetDTVSignalMonitor()->SetChannel(-1,-1);
2246  GetDTVSignalMonitor()->SetDVBService(0, 0, -1);
2247  }
2248 
2249  // Start signal monitor for this channel
2250  if (m_signalMonitor)
2252 
2253  m_timer.start();
2254  m_waitingForTables = (item.m_tuning.m_sistandard != "analog");
2255 }
2256 
2262 {
2263  LOG(VB_CHANSCAN, LOG_INFO, LOC + "StopScanner");
2264 
2265  while (m_scannerThread)
2266  {
2267  m_threadExit = true;
2268  if (m_scannerThread->wait(1s))
2269  {
2270  delete m_scannerThread;
2271  m_scannerThread = nullptr;
2272  }
2273  }
2274 
2275  if (m_signalMonitor)
2276  m_signalMonitor->Stop();
2277 }
2278 
2284  int SourceID,
2285  const QString &std,
2286  const QString &modulation,
2287  const QString &country,
2288  const QString &table_start,
2289  const QString &table_end)
2290 {
2291  LOG(VB_CHANSCAN, LOG_DEBUG, LOC +
2292  QString("%1:%2 ").arg(__FUNCTION__).arg(__LINE__) +
2293  QString("SourceID:%1 ").arg(SourceID) +
2294  QString("std:%1 ").arg(std) +
2295  QString("modulation:%1 ").arg(modulation) +
2296  QString("country:%1 ").arg(country) +
2297  QString("table_start:%1 ").arg(table_start) +
2298  QString("table_end:%1 ").arg(table_end));
2299 
2300  QString name("");
2301  if (m_scanning)
2302  return false;
2303 
2304  m_scanTransports.clear();
2305  m_nextIt = m_scanTransports.end();
2306 
2307  freq_table_list_t tables =
2308  get_matching_freq_tables(std, modulation, country);
2309 
2310  if (tables.empty())
2311  {
2312  QString msg = QString("No freq table for (%1, %2, %3) found")
2313  .arg(std, modulation, country);
2315  }
2316  LOG(VB_CHANSCAN, LOG_INFO, LOC +
2317  QString("Looked up freq table (%1, %2, %3) w/%4 entries")
2318  .arg(std, modulation, country, QString::number(tables.size())));
2319 
2320  QString start = table_start;
2321  const QString& end = table_end;
2322  // NOLINTNEXTLINE(modernize-loop-convert)
2323  for (auto it = tables.begin(); it != tables.end(); ++it)
2324  {
2325  const FrequencyTable &ft = **it;
2326  int name_num = ft.m_nameOffset;
2327  QString strNameFormat = ft.m_nameFormat;
2328  uint freq = ft.m_frequencyStart;
2329  while (freq <= ft.m_frequencyEnd)
2330  {
2331  name = strNameFormat;
2332  if (strNameFormat.indexOf("%") >= 0)
2333  name = strNameFormat.arg(name_num);
2334 
2335  if (start.isEmpty() || name == start)
2336  {
2337  start.clear();
2338 
2339  TransportScanItem item(SourceID, std, name, name_num,
2340  freq, ft, m_signalTimeout);
2341  m_scanTransports.push_back(item);
2342 
2343  LOG(VB_CHANSCAN, LOG_INFO, LOC + "ScanTransports " +
2344  item.toString());
2345  }
2346 
2347  ++name_num;
2348  freq += ft.m_frequencyStep;
2349 
2350  if (!end.isEmpty() && name == end)
2351  break;
2352  }
2353  if (!end.isEmpty() && name == end)
2354  break;
2355  }
2356 
2357  while (!tables.empty())
2358  {
2359  delete tables.back();
2360  tables.pop_back();
2361  }
2362 
2363  m_extendScanList = true;
2364  m_timer.start();
2365  m_waitingForTables = false;
2366 
2367  m_nextIt = m_scanTransports.begin();
2368  m_transportsScanned = 0;
2369  m_scanning = true;
2370 
2371  return true;
2372 }
2373 
2375  const QString &std,
2376  const QString &cardtype,
2377  const DTVChannelList &channels)
2378 {
2379  m_scanTransports.clear();
2380  m_nextIt = m_scanTransports.end();
2381 
2382  DTVTunerType tunertype;
2383  tunertype.Parse(cardtype);
2384 
2385  auto it = channels.cbegin();
2386  for (uint i = 0; it != channels.cend(); ++it, ++i)
2387  {
2388  DTVTransport tmp = *it;
2389  tmp.m_sistandard = std;
2390  TransportScanItem item(sourceid, QString::number(i),
2391  tunertype, tmp, m_signalTimeout);
2392 
2393  m_scanTransports.push_back(item);
2394 
2395  LOG(VB_CHANSCAN, LOG_INFO, LOC + "ScanForChannels " + item.toString());
2396  }
2397 
2398  if (m_scanTransports.empty())
2399  {
2400  LOG(VB_GENERAL, LOG_ERR, LOC + "ScanForChannels() no transports");
2401  return false;
2402  }
2403 
2404  m_timer.start();
2405  m_waitingForTables = false;
2406 
2407  m_nextIt = m_scanTransports.begin();
2408  m_transportsScanned = 0;
2409  m_scanning = true;
2410 
2411  return true;
2412 }
2413 
2415  const fbox_chan_map_t &iptv_channels)
2416 {
2417  m_scanTransports.clear();
2418  m_nextIt = m_scanTransports.end();
2419 
2420  fbox_chan_map_t::const_iterator Ichan = iptv_channels.begin();
2421  for (uint idx = 0; Ichan != iptv_channels.end(); ++Ichan, ++idx)
2422  {
2423  TransportScanItem item(sourceid, QString::number(idx),
2424  Ichan.value().m_tuning, Ichan.key(),
2425  m_signalTimeout);
2426 
2427  m_scanTransports.push_back(item);
2428 
2429  LOG(VB_CHANSCAN, LOG_INFO, LOC + "ScanIPTVChannels " + item.toString());
2430  }
2431 
2432  if (m_scanTransports.empty())
2433  {
2434  LOG(VB_GENERAL, LOG_ERR, LOC + "ScanIPTVChannels() no transports");
2435  return false;
2436  }
2437 
2438  m_timer.start();
2439  m_waitingForTables = false;
2440 
2441  m_nextIt = m_scanTransports.begin();
2442  m_transportsScanned = 0;
2443  m_scanning = true;
2444 
2445  return true;
2446 }
2447 
2448 
2454  int sourceid, const QMap<QString,QString> &startChan)
2455 {
2456  if (startChan.find("std") == startChan.end() ||
2457  startChan.find("type") == startChan.end())
2458  {
2459  return false;
2460  }
2461 
2462  QString std = *startChan.find("std");
2463  QString si_std = (std.toLower() != "atsc") ? "dvb" : "atsc";
2464  bool ok = false;
2465 
2466  if (m_scanning)
2467  return false;
2468 
2469  m_scanTransports.clear();
2470  m_nextIt = m_scanTransports.end();
2471 
2472  DTVMultiplex tuning;
2473 
2475  ok = type.Parse(startChan["type"]);
2476 
2477  if (ok)
2478  {
2479  ok = tuning.ParseTuningParams(
2480  type,
2481  startChan["frequency"], startChan["inversion"],
2482  startChan["symbolrate"], startChan["fec"],
2483  startChan["polarity"],
2484  startChan["coderate_hp"], startChan["coderate_lp"],
2485  startChan["constellation"], startChan["trans_mode"],
2486  startChan["guard_interval"], startChan["hierarchy"],
2487  startChan["modulation"], startChan["bandwidth"],
2488  startChan["mod_sys"], startChan["rolloff"]);
2489  }
2490 
2491  if (ok)
2492  {
2493  tuning.m_sistandard = si_std;
2494  TransportScanItem item(
2495  sourceid, QObject::tr("Frequency %1").arg(startChan["frequency"]),
2496  tuning, m_signalTimeout);
2497  m_scanTransports.push_back(item);
2498  }
2499 
2500  if (!ok)
2501  return false;
2502 
2503  m_extendScanList = true;
2504 
2505  m_timer.start();
2506  m_waitingForTables = false;
2507 
2508  m_nextIt = m_scanTransports.begin();
2509  m_transportsScanned = 0;
2510  m_scanning = true;
2511 
2512  return true;
2513 }
2514 
2516 {
2517  MSqlQuery query(MSqlQuery::InitCon());
2518  query.prepare(
2519  "SELECT sourceid, sistandard, transportid, frequency, modulation, mod_sys "
2520  "FROM dtv_multiplex "
2521  "WHERE mplexid = :MPLEXID");
2522  query.bindValue(":MPLEXID", mplexid);
2523  if (!query.exec())
2524  {
2525  MythDB::DBError("ChannelScanSM::AddToList()", query);
2526  return false;
2527  }
2528 
2529  if (!query.next())
2530  {
2531  LOG(VB_GENERAL, LOG_ERR, LOC + "AddToList() " +
2532  QString("Failed to locate mplexid(%1) in DB").arg(mplexid));
2533  return false;
2534  }
2535 
2536  uint sourceid = query.value(0).toUInt();
2537  QString sistandard = query.value(1).toString();
2538  uint tsid = query.value(2).toUInt();
2539  uint frequency = query.value(3).toUInt();
2540  QString modulation = query.value(4).toString();
2541  QString mod_sys = query.value(5).toString();
2542  DTVModulationSystem delsys;
2543  delsys.Parse(mod_sys);
2545  QString fn = (tsid) ? QString("Transport ID %1").arg(tsid) :
2546  QString("Multiplex #%1").arg(mplexid);
2547 
2548  if (modulation == "8vsb")
2549  {
2550  QString chan = QString("%1 Hz").arg(frequency);
2551  int findFrequency = (query.value(3).toInt() / 1000) - 1750;
2552  for (const auto & list : gChanLists[0].list)
2553  {
2554  if ((list.freq <= findFrequency + 200) &&
2555  (list.freq >= findFrequency - 200))
2556  {
2557  chan = QString("%1").arg(list.name);
2558  }
2559  }
2560  fn = QObject::tr("ATSC Channel %1").arg(chan);
2562  }
2563 
2564  tt = GuessDTVTunerType(tt);
2565 
2566  TransportScanItem item(sourceid, sistandard, fn, mplexid, m_signalTimeout);
2567 
2568  LOG(VB_CHANSCAN, LOG_DEBUG, LOC +
2569  QString("tunertype:%1 %2 sourceid:%3 sistandard:%4 fn:'%5' mplexid:%6")
2570  .arg(tt).arg(tt.toString()).arg(sourceid).arg(sistandard, fn).arg(mplexid));
2571 
2572  if (item.m_tuning.FillFromDB(tt, mplexid))
2573  {
2574  LOG(VB_CHANSCAN, LOG_INFO, LOC + "Adding " + fn);
2575  m_scanTransports.push_back(item);
2576  return true;
2577  }
2578 
2579  LOG(VB_CHANSCAN, LOG_INFO, LOC + "Not adding incomplete transport " + fn);
2580  return false;
2581 }
2582 
2583 bool ChannelScanSM::ScanTransport(uint mplexid, bool follow_nit)
2584 {
2585  m_scanTransports.clear();
2586  m_nextIt = m_scanTransports.end();
2587 
2588  AddToList(mplexid);
2589 
2590  m_timer.start();
2591  m_waitingForTables = false;
2592 
2593  m_extendScanList = follow_nit;
2594  m_transportsScanned = 0;
2595  if (!m_scanTransports.empty())
2596  {
2597  m_nextIt = m_scanTransports.begin();
2598  m_scanning = true;
2599  return true;
2600  }
2601 
2602  return false;
2603 }
2604 
2605 bool ChannelScanSM::ScanCurrentTransport(const QString &sistandard)
2606 {
2607  m_scanTransports.clear();
2608  m_nextIt = m_scanTransports.end();
2609 
2610  m_signalTimeout = 30s;
2611  QString name;
2612  TransportScanItem item(m_sourceID, sistandard, name, 0, m_signalTimeout);
2613  m_scanTransports.push_back(item);
2614 
2615  m_timer.start();
2616  m_waitingForTables = false;
2617  m_extendScanList = false;
2618  m_transportsScanned = 0;
2619  m_nextIt = m_scanTransports.begin();
2620  m_scanning = true;
2621  return true;
2622 }
2623 
2628  const DTVChannelInfoList &channels,
2629  uint mpeg_program_num,
2630  QString &service_name,
2631  QString &callsign,
2632  QString &common_status_info)
2633 {
2634  if (channels.empty())
2635  return true;
2636 
2637  bool found = false;
2638  for (const auto & channel : channels)
2639  {
2640  LOG(VB_GENERAL, LOG_DEBUG, LOC +
2641  QString("comparing %1 %2 against %3 %4")
2642  .arg(channel.m_serviceid).arg(channel.m_name)
2643  .arg(mpeg_program_num).arg(common_status_info));
2644 
2645  if (channel.m_serviceid == mpeg_program_num)
2646  {
2647  found = true;
2648  if (!channel.m_name.isEmpty())
2649  {
2650  service_name = channel.m_name;
2651  callsign = channel.m_name;
2652  }
2653  }
2654  }
2655 
2656  if (found)
2657  {
2658  common_status_info += QString(" %1 %2")
2659  .arg(QObject::tr("as"), service_name);
2660  }
2661  else
2662  {
2664  QObject::tr("Skipping %1, not in imported channel map")
2665  .arg(common_status_info));
2666  }
2667 
2668  return found;
2669 }
ServiceRelocatedDescriptor
Definition: dvbdescriptors.h:1440
NetworkInformationTable::TransportDescriptorsLength
uint TransportDescriptorsLength(uint i) const
trans_desc_length 12 4.4+p
Definition: dvbtables.h:85
ChannelInsertInfo::m_isEncrypted
bool m_isEncrypted
Definition: channelinfo.h:247
DTVMultiplex::m_frequency
uint64_t m_frequency
Definition: dtvmultiplex.h:94
DTVChannel::GetTunerTypes
virtual std::vector< DTVTunerType > GetTunerTypes(void) const
Returns a vector of supported tuning types.
Definition: dtvchannel.cpp:78
ScannedChannelInfo::m_mgt
const MasterGuideTable * m_mgt
Definition: channelscan_sm.cpp:111
TransportScanItem::m_tuning
DTVMultiplex m_tuning
Definition: frequencytables.h:184
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:208
pat_vec_t
std::vector< const ProgramAssociationTable * > pat_vec_t
Definition: mpegstreamdata.h:30
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:124
ProgramAssociationTable::ProgramPID
uint ProgramPID(uint i) const
Definition: mpegtables.h:646
VirtualChannelTable
This table contains information about the channels transmitted on this multiplex.
Definition: atsctables.h:189
kEncUnknown
@ kEncUnknown
Definition: mpegstreamdata.h:56
DTVMultiplex
Definition: dtvmultiplex.h:24
DTVSignalMonitor::AddFlags
void AddFlags(uint64_t _flags) override
Definition: dtvsignalmonitor.cpp:140
MPEGStreamData::GetCachedPATs
pat_vec_t GetCachedPATs(uint tsid) const
Definition: mpegstreamdata.cpp:1345
transport_scan_items_it_t::offset
uint offset() const
Definition: frequencytables.h:254
DVBStreamData::GetCachedBATs
bat_vec_t GetCachedBATs(bool current=true) const
Definition: dvbstreamdata.cpp:843
kEncEncrypted
@ kEncEncrypted
Definition: mpegstreamdata.h:58
DescriptorID::service_list
@ service_list
Definition: mpegdescriptors.h:73
MThread::start
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:286
DVBStreamData::GetCachedSDTs
sdt_vec_t GetCachedSDTs(bool current=true) const
Definition: dvbstreamdata.cpp:910
ChannelInsertInfo::m_oldOrigNetId
uint m_oldOrigNetId
Definition: channelinfo.h:255
ChannelScanSM::HandleSDT
void HandleSDT(uint tsid, const ServiceDescriptionTable *sdt) override
Definition: channelscan_sm.cpp:457
ChannelScanSM::ChannelScanSM
ChannelScanSM(ScanMonitor *_scan_monitor, const QString &_cardtype, ChannelBase *_channel, int _sourceID, std::chrono::milliseconds signal_timeout, std::chrono::milliseconds channel_timeout, QString _inputname, bool test_decryption)
Definition: channelscan_sm.cpp:144
VirtualChannelTable::IsAccessControlled
bool IsAccessControlled(uint i) const
Definition: atsctables.h:276
CardUtil::GetDisplayName
static QString GetDisplayName(uint inputid)
Definition: cardutil.cpp:1724
ChannelInsertInfo::m_useOnAirGuide
bool m_useOnAirGuide
Definition: channelinfo.h:223
MPEGDescriptor::DescriptorTag
uint DescriptorTag(void) const
Definition: mpegdescriptors.h:345
DTVTunerType::kTunerTypeDVBC
static const int kTunerTypeDVBC
Definition: dtvconfparserhelpers.h:95
ChannelInsertInfo::m_hiddenInGuide
bool m_hiddenInGuide
Definition: channelinfo.h:225
ScannedChannelInfo::m_sdts
sdt_map_t m_sdts
Definition: channelscan_sm.cpp:117
DVBStreamData::HasCachedAnySDTs
bool HasCachedAnySDTs(bool current=true) const
Definition: dvbstreamdata.cpp:764
NetworkInformationTable::TSID
uint TSID(uint i) const
transport_stream_id 16 0.0+p
Definition: dvbtables.h:79
FrequencyTable
Definition: frequencytables.h:38
ChannelInsertInfo::m_chanNum
QString m_chanNum
Definition: channelinfo.h:218
DTVSignalMonitor::SetDVBService
void SetDVBService(uint network_id, uint transport_id, int service_id)
Definition: dtvsignalmonitor.cpp:229
DVBChannel::GetRotor
const DiSEqCDevRotor * GetRotor(void) const
Returns rotor object if it exists, nullptr otherwise.
Definition: dvbchannel.cpp:1157
ChannelScanSM::HandleSDTo
void HandleSDTo(uint tsid, const ServiceDescriptionTable *sdt) override
Definition: channelscan_sm.cpp:574
DiSEqCDevRotor
Rotor class.
Definition: diseqc.h:302
ChannelInsertInfo::m_atscMajorChannel
uint m_atscMajorChannel
Definition: channelinfo.h:221
ChannelScanSM::m_tsScanned
QSet< uint32_t > m_tsScanned
Definition: channelscan_sm.h:241
DVBStreamData::HasCachedAllBATs
bool HasCachedAllBATs(bool current=true) const
Definition: dvbstreamdata.cpp:691
mythdb.h
ChannelScanSM::m_scannerThread
MThread * m_scannerThread
Definition: channelscan_sm.h:261
cvct_vec_t
std::vector< const CableVirtualChannelTable * > cvct_vec_t
Definition: atscstreamdata.h:16
ChannelInsertInfo::m_inNit
bool m_inNit
Definition: channelinfo.h:245
freq_table_list_t
std::vector< const FrequencyTable * > freq_table_list_t
Definition: frequencytables.h:25
FreesatLCNDescriptor
Freesat Logical Channel Number descriptor.
Definition: dvbdescriptors.h:2624
ScanStreamData::Reset
void Reset(void) override
Definition: scanstreamdata.cpp:58
LOC
#define LOC
Definition: channelscan_sm.cpp:87
DescriptorID::s2_satellite_delivery_system
@ s2_satellite_delivery_system
Definition: mpegdescriptors.h:132
ChannelScanSM::m_lock
QMutex m_lock
The big lock.
Definition: channelscan_sm.h:231
ScanDTVTransport::m_transportID
uint m_transportID
Definition: dtvmultiplex.h:140
NetworkInformationTable::NetworkID
uint NetworkID(void) const
network_id 16 3.0 0x0000
Definition: dvbtables.h:59
ChannelInsertInfo::m_freqId
QString m_freqId
Definition: channelinfo.h:227
ATSCStreamData::HasCachedAllCVCTs
bool HasCachedAllCVCTs(bool current=true) const
Definition: atscstreamdata.cpp:722
ScannedChannelInfo::m_pmts
pmt_vec_t m_pmts
Definition: channelscan_sm.cpp:107
DTVSignalMonitor::GetScanStreamData
ScanStreamData * GetScanStreamData()
Returns the scan stream data if it exists.
Definition: dtvsignalmonitor.cpp:544
ChannelScanSM::kMPEGTableTimeout
static const std::chrono::milliseconds kMPEGTableTimeout
No logic here, lets just wait at least 15 seconds.
Definition: channelscan_sm.h:203
MThread::wait
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:303
ChannelInsertInfo::m_isDataService
bool m_isDataService
Definition: channelinfo.h:248
DTVTunerType::kTunerTypeDVBS1
static const int kTunerTypeDVBS1
Definition: dtvconfparserhelpers.h:93
ChannelInsertInfo::m_origNetId
uint m_origNetId
Definition: channelinfo.h:238
DescriptorID::extension
@ extension
Definition: mpegdescriptors.h:138
ATSCStreamData::HasCachedMGT
bool HasCachedMGT(bool current=true) const
Definition: atscstreamdata.cpp:626
BouquetAssociationTable::BouquetID
uint BouquetID() const
Definition: dvbtables.h:205
NetworkInformationTable::TransportDescriptors
const unsigned char * TransportDescriptors(uint i) const
for(j=0;j<N;j++) x 6.0+p { descriptor() }
Definition: dvbtables.h:89
ChannelScanSM::m_current
transport_scan_items_it_t m_current
Definition: channelscan_sm.h:244
DTVMultiplex::FillFromDeliverySystemDesc
bool FillFromDeliverySystemDesc(DTVTunerType type, const MPEGDescriptor &desc)
Definition: dtvmultiplex.cpp:465
BouquetAssociationTable::TransportDescriptors
const unsigned char * TransportDescriptors(uint i) const
for(j=0;j<N;j++) x 6.0+p { descriptor() }
Definition: dvbtables.h:241
pat_map_t
QMap< uint, pat_vec_t > pat_map_t
Definition: mpegstreamdata.h:31
ATSCStreamData::GetCachedCVCTs
cvct_vec_t GetCachedCVCTs(bool current=true) const
Definition: atscstreamdata.cpp:840
FrequencyTable::m_nameFormat
QString m_nameFormat
Definition: frequencytables.h:98
tvct_vec_t
std::vector< const TerrestrialVirtualChannelTable * > tvct_vec_t
Definition: atscstreamdata.h:15
hardwareprofile.devicelist.cat
def cat(file_name)
Definition: devicelist.py:95
freq
static const std::array< const uint32_t, 4 > freq
Definition: element.cpp:45
SourceUtil::GetMplexIDs
static std::vector< uint > GetMplexIDs(uint sourceid)
Definition: sourceutil.cpp:145
PrivateDescriptorID::dvb_simulcast_channel_descriptor
@ dvb_simulcast_channel_descriptor
Definition: mpegdescriptors.h:207
BouquetAssociationTable::TransportDescriptorsLength
uint TransportDescriptorsLength(uint i) const
Definition: dvbtables.h:237
ProgramMapTable
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:692
channelscan_sm.h
progress
bool progress
Definition: mythtv/programs/mythcommflag/main.cpp:71
ChannelScanSM::m_scanning
bool m_scanning
Definition: channelscan_sm.h:234
frequencies.h
ScanMonitor::ScanPercentComplete
void ScanPercentComplete(int pct)
Definition: scanmonitor.cpp:103
DVBSignalMonitor
Definition: dvbsignalmonitor.h:17
SignalMonitor::kDTVSigMon_WaitForMGT
static const uint64_t kDTVSigMon_WaitForMGT
Definition: signalmonitor.h:185
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:197
DVBSignalMonitor::SetRotorTarget
void SetRotorTarget(float target) override
Sets rotor target pos from 0.0 to 1.0.
Definition: dvbsignalmonitor.cpp:137
mythdbcon.h
ServiceDescriptionTable::ServiceID
uint ServiceID(uint i) const
service_id 16 0.0+p
Definition: dvbtables.h:150
ServiceDescriptor::IsDTV
bool IsDTV(void) const
Definition: dvbdescriptors.h:2077
ChannelScanSM::GetHDHRChannel
HDHRChannel * GetHDHRChannel(void)
Definition: channelscan_sm.cpp:1930
ChannelScanSM::m_currentTestingDecryption
bool m_currentTestingDecryption
Definition: channelscan_sm.h:246
ChannelInsertInfo::m_defaultAuthority
QString m_defaultAuthority
Definition: channelinfo.h:231
CableDeliverySystemDescriptor
Definition: dvbdescriptors.h:739
scanwizardconfig.h
DTVSignalMonitor::GetStreamData
MPEGStreamData * GetStreamData()
Returns the MPEG stream data if it exists.
Definition: dtvsignalmonitor.h:59
SignalMonitor::GetSignalStrength
int GetSignalStrength(void)
Definition: signalmonitor.h:75
ScannedChannelInfo::m_bats
bat_vec_t m_bats
Definition: channelscan_sm.cpp:118
VirtualChannelTable::ShortChannelName
QString ShortChannelName(uint i) const
Definition: atsctables.h:225
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
ChannelScanSM::m_scanTransports
transport_scan_items_t m_scanTransports
Definition: channelscan_sm.h:243
ChannelScanSM::SetAnalog
void SetAnalog(bool is_analog)
Definition: channelscan_sm.cpp:246
ChannelInsertInfo::m_hidden
bool m_hidden
Definition: channelinfo.h:224
ProgramMapTable::ProgramNumber
uint ProgramNumber(void) const
Definition: mpegtables.h:729
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
ChannelScanSM::m_nitId
uint m_nitId
Definition: channelscan_sm.h:224
SourceID
Definition: videosource.cpp:2874
ScanDTVTransport::m_networkID
uint m_networkID
Definition: dtvmultiplex.h:139
OriginalNetworkID::TELENOR
@ TELENOR
Definition: mpegdescriptors.h:294
ChannelScanSM::m_otherTableTimeout
std::chrono::milliseconds m_otherTableTimeout
Definition: channelscan_sm.h:213
TransportScanItem::m_iptvTuning
IPTVTuningData m_iptvTuning
Definition: frequencytables.h:185
DVBLogicalChannelDescriptor
DVB Logical Channel Descriptor.
Definition: dvbdescriptors.h:2566
ChannelScanSM::m_dvbt2Tried
bool m_dvbt2Tried
Definition: channelscan_sm.h:250
TransportScanItem::m_signalStrength
int m_signalStrength
Definition: frequencytables.h:192
ChannelScanSM::Tune
bool Tune(transport_scan_items_it_t transport)
Definition: channelscan_sm.cpp:2160
ChannelScanSM::run
void run(void) override
This runs the event loop for ChannelScanSM until 'threadExit' is true.
Definition: channelscan_sm.cpp:1988
RegistrationDescriptor
Definition: mpegdescriptors.h:429
CableDeliverySystemDescriptor::FrequencyHz
unsigned long long FrequencyHz(void) const
Definition: dvbdescriptors.h:754
ChannelScanSM::m_signalTimeout
std::chrono::milliseconds m_signalTimeout
Definition: channelscan_sm.h:211
ProgramAssociationTable::ProgramCount
uint ProgramCount(void) const
Definition: mpegtables.h:636
ChannelInsertInfo::m_isAudioService
bool m_isAudioService
Definition: channelinfo.h:249
bat_vec_t
std::vector< const BouquetAssociationTable * > bat_vec_t
Definition: dvbstreamdata.h:23
DTVChannel::Tune
virtual bool Tune(const DTVMultiplex &tuning)=0
This performs the actual frequency tuning and in some cases input switching.
ScannedChannelInfo
Definition: channelscan_sm.cpp:91
DVBChannel::SetPMT
void SetPMT(const ProgramMapTable *pmt)
Tells the Conditional Access Module which streams we wish to decode.
Definition: dvbchannel.cpp:725
VirtualChannelTable::ProgramNumber
uint ProgramNumber(uint i) const
Definition: atsctables.h:266
ScanStreamData
Definition: scanstreamdata.h:10
ProgramMapTable::IsEncrypted
bool IsEncrypted(const QString &sistandard) const
Returns true iff PMT contains CA descriptor for a vid/aud stream.
Definition: mpegtables.cpp:551
VirtualChannelTable::IsHiddenInGuide
bool IsHiddenInGuide(uint i) const
Definition: atsctables.h:287
PCM_INFO_INIT
#define PCM_INFO_INIT(SISTD)
Definition: channelscan_sm.cpp:1158
VirtualChannelTable::toString
QString toString(void) const override
Definition: atsctables.cpp:200
ChannelUtil::CreateChannel
static bool CreateChannel(uint db_mplexid, uint db_sourceid, uint new_channel_id, const QString &callsign, const QString &service_name, const QString &chan_num, uint service_id, uint atsc_major_channel, uint atsc_minor_channel, bool use_on_air_guide, ChannelVisibleType visible, const QString &freqid, const QString &icon=QString(), QString format="Default", const QString &xmltvid=QString(), const QString &default_authority=QString(), uint service_type=0)
Definition: channelutil.cpp:1481
ChannelUtil::GetUnknownCallsign
static QString GetUnknownCallsign(void)
Definition: channelutil.cpp:1304
PID::SCTE_PSIP_PID
@ SCTE_PSIP_PID
Definition: mpegtables.h:237
ChannelScanSM::m_sourceID
int m_sourceID
Definition: channelscan_sm.h:210
sdt_map_t
QMap< uint, sdt_vec_t > sdt_map_t
Definition: dvbstreamdata.h:19
BouquetAssociationTable::TSID
uint TSID(uint i) const
Definition: dvbtables.h:231
ATSCStreamData::HasCachedAllTVCTs
bool HasCachedAllTVCTs(bool current=true) const
Definition: atscstreamdata.cpp:691
ChannelScanSM::m_bouquetId
uint m_bouquetId
Definition: channelscan_sm.h:222
ScannedChannelInfo::ScannedChannelInfo
ScannedChannelInfo()=default
ChannelScanSM::m_scanMonitor
ScanMonitor * m_scanMonitor
Definition: channelscan_sm.h:207
DVBSimulcastChannelDescriptor::ChannelNumber
uint ChannelNumber(uint i) const
Definition: dvbdescriptors.h:2608
RegistrationDescriptor::FormatIdentifierString
QString FormatIdentifierString(void) const
Definition: mpegdescriptors.h:443
PSIPTable::Section
uint Section(void) const
Definition: mpegtables.h:548
FreesatLCNDescriptor::LCNCount
uint LCNCount(int i) const
Definition: dvbdescriptors.h:2665
DTVMultiplex::FillFromDB
virtual bool FillFromDB(DTVTunerType type, uint mplexid)
Definition: dtvmultiplex.cpp:417
dvbchannel.h
true
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:91
TerrestrialDeliverySystemDescriptor
Definition: dvbdescriptors.h:927
ChannelScanSM::StopScanner
void StopScanner(void)
Stops the ChannelScanSM event loop and the signal monitor, blocking until both exit.
Definition: channelscan_sm.cpp:2261
DescriptorID::cable_delivery_system
@ cable_delivery_system
Definition: mpegdescriptors.h:76
DVBSignalMonitor::GetRotorStatus
void GetRotorStatus(bool &was_moving, bool &is_moving) override
Definition: dvbsignalmonitor.cpp:143
ChannelScanSM::m_otherTableTime
std::chrono::milliseconds m_otherTableTime
Definition: channelscan_sm.h:214
HDHRChannel
Definition: hdhrchannel.h:20
VirtualChannelTable::IsHidden
bool IsHidden(uint i) const
Definition: atsctables.h:281
DescriptorID::t2_delivery_system
@ t2_delivery_system
Definition: mpegdescriptors.h:144
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
ChannelScanSM::m_extendScanList
bool m_extendScanList
Definition: channelscan_sm.h:218
OriginalNetworkID::BBC
@ BBC
Definition: mpegdescriptors.h:293
PrivateDataSpecifierID::BSB1
@ BSB1
Definition: mpegdescriptors.h:270
DTVModulationSystem::kModulationSystem_UNDEFINED
@ kModulationSystem_UNDEFINED
Definition: dtvconfparserhelpers.h:656
ChannelInsertInfo::m_atscMinorChannel
uint m_atscMinorChannel
Definition: channelinfo.h:222
ChannelScanSM::ScanTransports
bool ScanTransports(int SourceID, const QString &std, const QString &mod, const QString &country, const QString &table_start=QString(), const QString &table_end=QString())
Generates a list of frequencies to scan and adds it to the scanTransport list, and then sets the scan...
Definition: channelscan_sm.cpp:2283
MPEGStreamData::ReturnCachedPATTables
virtual void ReturnCachedPATTables(pat_vec_t &pats) const
Definition: mpegstreamdata.cpp:1475
ChannelInsertInfo
Definition: channelinfo.h:133
DTVTunerType
Definition: dtvconfparserhelpers.h:76
VirtualChannelTable::ChannelTransportStreamID
uint ChannelTransportStreamID(uint i) const
Definition: atsctables.h:261
MPEGDescriptor::FindExtension
static const unsigned char * FindExtension(const desc_list_t &parsed, uint desc_tag)
Definition: mpegdescriptors.cpp:86
ChannelScanSM::GetV4LChannel
V4LChannel * GetV4LChannel(void)
Definition: channelscan_sm.cpp:1957
DescriptorID::terrestrial_delivery_system
@ terrestrial_delivery_system
Definition: mpegdescriptors.h:99
FrequencyTable::m_frequencyStep
uint m_frequencyStep
Definition: frequencytables.h:102
MPEGStreamData::HasCachedAllPMTs
bool HasCachedAllPMTs(void) const
Definition: mpegstreamdata.cpp:1303
pmt_vec_t
std::vector< const ProgramMapTable * > pmt_vec_t
Definition: channelscan_sm.h:63
ChannelScanSM::m_mutex
QMutex m_mutex
Definition: channelscan_sm.h:264
MPEGDescriptor::IsValid
bool IsValid(void) const
Definition: mpegdescriptors.h:342
ChannelScanSM::kDVBTableTimeout
static const std::chrono::milliseconds kDVBTableTimeout
SDT's should be sent every 2 seconds and NIT's every 10 seconds, so lets wait at least 30 seconds,...
Definition: channelscan_sm.h:201
VirtualChannelTable::MajorChannel
uint MajorChannel(uint i) const
Definition: atsctables.h:244
ChannelScanSM::m_setOtherTables
bool m_setOtherTables
Definition: channelscan_sm.h:215
OriginalNetworkID::SES2
@ SES2
Definition: mpegdescriptors.h:292
ChannelScanSM::StartScanner
void StartScanner(void)
Starts the ChannelScanSM event loop.
Definition: channelscan_sm.cpp:1969
DVBStreamData::HasCachedAllSDT
bool HasCachedAllSDT(uint tsid, bool current=true) const
Definition: dvbstreamdata.cpp:707
DTVMultiplex::m_iptvTuning
IPTVTuningData m_iptvTuning
Definition: dtvmultiplex.h:112
sourceutil.h
ServiceDescriptor::ServiceName
QString ServiceName(void) const
Definition: dvbdescriptors.h:2067
DTVChannelList
std::vector< DTVTransport > DTVChannelList
Definition: dtvconfparser.h:68
ServiceDescriptionTable::ServiceCount
uint ServiceCount() const
Number of services.
Definition: dvbtables.h:145
DVBStreamData::GetCachedNIT
nit_const_ptr_t GetCachedNIT(uint section_num, bool current=true) const
Definition: dvbstreamdata.cpp:790
ChannelScanSM::m_timer
QElapsedTimer m_timer
Definition: channelscan_sm.h:237
ChannelScanSM::HandleActiveScan
void HandleActiveScan(void)
Handles the TRANSPORT_LIST ChannelScanSM mode.
Definition: channelscan_sm.cpp:2085
ChannelScanSM::HandleNIT
void HandleNIT(const NetworkInformationTable *nit) override
Definition: channelscan_sm.cpp:506
dvbsignalmonitor.h
ServiceDescriptionTable::GetServiceDescriptor
ServiceDescriptor * GetServiceDescriptor(uint i) const
Definition: dvbtables.cpp:164
mythlogging.h
SignalMonitor::kDVBSigMon_WaitForPos
static const uint64_t kDVBSigMon_WaitForPos
Wait for rotor to complete turning the antenna.
Definition: signalmonitor.h:202
ChannelBase
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:31
MPEGStreamData::HasCachedAnyPAT
bool HasCachedAnyPAT(uint tsid) const
Definition: mpegstreamdata.cpp:1220
sdt_vec_t
std::vector< const ServiceDescriptionTable * > sdt_vec_t
Definition: dvbstreamdata.h:17
MPEGDescriptor::Parse
static desc_list_t Parse(const unsigned char *data, uint len)
Definition: mpegdescriptors.cpp:15
TransportScanItem
Class used for doing a list of frequencies / transports.
Definition: frequencytables.h:127
ServiceDescriptionTable::toString
QString toString(void) const override
Definition: dvbtables.cpp:127
ChannelScanSM::m_analogSignalHandler
AnalogSignalHandler * m_analogSignalHandler
Definition: channelscan_sm.h:258
ProgramMapTable::toString
QString toString(void) const override
Definition: mpegtables.cpp:879
transport_scan_items_it_t::iter
std::list< TransportScanItem >::iterator iter()
Definition: frequencytables.h:252
DVBLogicalChannelDescriptor::ChannelCount
uint ChannelCount(void) const
Definition: dvbdescriptors.h:2575
AnalogSignalHandler
Definition: channelscan_sm.h:70
ServiceDescriptionTable::OriginalNetworkID
uint OriginalNetworkID() const
original_network_id 16 8.0
Definition: dvbtables.h:141
ChannelUtil::FindChannel
static uint FindChannel(uint sourceid, const QString &freqid)
Definition: channelutil.cpp:1382
ChannelScanSM::m_extendTransports
QMap< uint32_t, DTVMultiplex > m_extendTransports
Definition: channelscan_sm.h:242
DTVTunerType::kTunerTypeUnknown
static const int kTunerTypeUnknown
Definition: dtvconfparserhelpers.h:103
hardwareprofile.i18n.t
t
Definition: i18n.py:36
MPEGDescriptor
Definition: mpegdescriptors.h:302
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
scanstreamdata.h
DTVChannelInfoList
std::vector< DTVChannelInfo > DTVChannelInfoList
Definition: dtvconfparser.h:58
PrivateDataSpecifierID::FSAT
@ FSAT
Definition: mpegdescriptors.h:279
v4lchannel.h
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:200
ScannedChannelInfo::m_tvcts
tvct_vec_t m_tvcts
Definition: channelscan_sm.cpp:113
SignalMonitor::kDTVSigMon_WaitForNIT
static const uint64_t kDTVSigMon_WaitForNIT
Definition: signalmonitor.h:187
DescriptorID::default_authority
@ default_authority
Definition: mpegdescriptors.h:126
ChannelScanSM::HandlePAT
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: channelscan_sm.cpp:376
ChannelScanSM::HandleEncryptionStatus
void HandleEncryptionStatus(uint pnum, bool encrypted) override
Definition: channelscan_sm.cpp:613
teardown_frequency_tables
bool teardown_frequency_tables(void)
Definition: frequencytables.cpp:214
SignalMonitor::kDTVSigMon_WaitForSDT
static const uint64_t kDTVSigMon_WaitForSDT
Definition: signalmonitor.h:188
DVBLogicalChannelDescriptor::ChannelNumber
uint ChannelNumber(uint i) const
Definition: dvbdescriptors.h:2580
desc_list_t
std::vector< const unsigned char * > desc_list_t
Definition: mpegdescriptors.h:18
BouquetAssociationTable::OriginalNetworkID
uint OriginalNetworkID(uint i) const
Definition: dvbtables.h:233
DVBStreamData::HasCachedAllNIT
bool HasCachedAllNIT(bool current=true) const
Definition: dvbstreamdata.cpp:625
ChannelScanSM::m_channelsFound
uint m_channelsFound
Definition: channelscan_sm.h:254
DTVSignalMonitor::GetDVBStreamData
DVBStreamData * GetDVBStreamData()
Returns the DVB stream data if it exists.
Definition: dtvsignalmonitor.cpp:539
MPEGDescriptor::ParseOnlyInclude
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
Definition: mpegdescriptors.cpp:57
ServiceDescriptionTable
This table tells the decoder on which PIDs to find A/V data.
Definition: dvbtables.h:110
DTVTunerType::toString
QString toString() const
Definition: dtvconfparserhelpers.h:154
ScannedChannelInfo::m_cvcts
cvct_vec_t m_cvcts
Definition: channelscan_sm.cpp:112
MPEGStreamData::GetCachedPMTs
pmt_vec_t GetCachedPMTs(void) const
Definition: mpegstreamdata.cpp:1430
ScannedChannelInfo::IsEmpty
bool IsEmpty() const
Definition: channelscan_sm.cpp:96
T2DeliverySystemDescriptor
Definition: dvbdescriptors.h:1112
SkyLCNDescriptor
Sky Logical Channel Number descriptor.
Definition: dvbdescriptors.h:2782
ProgramAssociationTable::toString
QString toString(void) const override
Definition: mpegtables.cpp:814
ChannelScanSM::HandleBAT
void HandleBAT(const BouquetAssociationTable *bat) override
Definition: channelscan_sm.cpp:519
dvbtables.h
PrivateDataSpecifierDescriptor::PrivateDataSpecifier
uint32_t PrivateDataSpecifier(void) const
Definition: dvbdescriptors.h:1912
DVBSimulcastChannelDescriptor
DVB HD Simulcast Logical Channel Descriptor.
Definition: dvbdescriptors.h:2594
ChannelScanSM::UpdateChannelInfo
bool UpdateChannelInfo(bool wait_until_complete)
Definition: channelscan_sm.cpp:830
kDecryptionTimeout
#define kDecryptionTimeout
Definition: channelscan_sm.cpp:89
FreesatLCNDescriptor::ServiceID
uint ServiceID(int i) const
Definition: dvbdescriptors.h:2659
ChannelUtil::CreateChanID
static int CreateChanID(uint sourceid, const QString &chan_num)
Creates a unique channel ID for database use.
Definition: channelutil.cpp:1445
DTVMultiplex::m_modSys
DTVModulationSystem m_modSys
Definition: dtvmultiplex.h:106
MPEGDescriptor::DescriptorTagExtension
uint DescriptorTagExtension(void) const
Definition: mpegdescriptors.h:347
ChannelScanSM::UpdateScanTransports
void UpdateScanTransports(uint frequency, const NetworkInformationTable *nit)
Definition: channelscan_sm.cpp:734
ChannelScanSM::m_nextIt
transport_scan_items_it_t m_nextIt
Definition: channelscan_sm.h:245
MPEGStreamData::ResetDecryptionMonitoringState
void ResetDecryptionMonitoringState(void)
Definition: mpegstreamdata.cpp:1835
ChannelScanSM::m_waitingForTables
bool m_waitingForTables
Definition: channelscan_sm.h:236
DTVMultiplex::toString
QString toString() const
Definition: dtvmultiplex.cpp:34
DVBStreamData::HasCachedAnyBATs
bool HasCachedAnyBATs(bool current=true) const
Definition: dvbstreamdata.cpp:685
transport_scan_items_it_t
Definition: frequencytables.h:195
ChannelScanSM
Scanning class for cards that support a SignalMonitor class.
Definition: channelscan_sm.h:85
PrivateDescriptorID::dvb_logical_channel_descriptor
@ dvb_logical_channel_descriptor
Definition: mpegdescriptors.h:206
ChannelInsertInfo::m_vctTsId
uint m_vctTsId
Definition: channelinfo.h:235
NetworkInformationTable::OriginalNetworkID
uint OriginalNetworkID(uint i) const
original_network_id 16 2.0+p
Definition: dvbtables.h:81
ChannelScanSM::GetCurrentTransportInfo
uint GetCurrentTransportInfo(QString &chan, QString &chan_tr) const
Definition: channelscan_sm.cpp:1321
uint
unsigned int uint
Definition: compat.h:140
kEncDecrypted
@ kEncDecrypted
Definition: mpegstreamdata.h:57
ScanDTVTransportList
std::vector< ScanDTVTransport > ScanDTVTransportList
Definition: dtvmultiplex.h:143
ChannelScanSM::m_scanDTVTunerType
DTVTunerType m_scanDTVTunerType
Definition: channelscan_sm.h:228
ChannelScanSM::HandlePMT
void HandlePMT(uint program_num, const ProgramMapTable *pmt) override
Definition: channelscan_sm.cpp:403
DTVSignalMonitor::GetNetworkID
uint GetNetworkID(void) const
Definition: dtvsignalmonitor.h:39
ProgramAssociationTable
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:615
TransportScanItem::m_friendlyName
QString m_friendlyName
Definition: frequencytables.h:175
DTVSignalMonitor::GetTransportID
uint GetTransportID(void) const
Definition: dtvsignalmonitor.h:38
ChannelScanSM::GetDVBSignalMonitor
DVBSignalMonitor * GetDVBSignalMonitor(void)
Definition: channelscan_sm.cpp:1911
ChannelScanSM::loc
static QString loc(const ChannelScanSM *siscan)
Definition: channelscan_sm.cpp:80
PSIPTable::LastSection
uint LastSection(void) const
Definition: mpegtables.h:551
PrivateDescriptorID::freesat_lcn_table
@ freesat_lcn_table
Definition: mpegdescriptors.h:232
ScanMonitor::ScanAppendTextToLog
void ScanAppendTextToLog(const QString &status)
Definition: scanmonitor.cpp:109
ServiceDescriptor::ServiceType
uint ServiceType(void) const
Definition: dvbdescriptors.h:2053
SignalMonitor
Signal monitoring base class.
Definition: signalmonitor.h:34
SatelliteDeliverySystemDescriptor::FrequencykHz
unsigned long long FrequencykHz(void) const
Definition: dvbdescriptors.h:834
ATSCStreamData::GetCachedTVCTs
tvct_vec_t GetCachedTVCTs(bool current=true) const
Definition: atscstreamdata.cpp:821
NetworkInformationTable::toString
QString toString(void) const override
Definition: dvbtables.cpp:30
ScanDTVTransport::m_signalStrength
int m_signalStrength
Definition: dtvmultiplex.h:141
ChannelScanSM::m_transportsScanned
int m_transportsScanned
Definition: channelscan_sm.h:240
ChannelInsertInfo::m_callSign
QString m_callSign
Definition: channelinfo.h:216
ChannelScanSM::HandleMGT
void HandleMGT(const MasterGuideTable *mgt) override
Definition: channelscan_sm.cpp:439
ChannelInsertInfo::m_format
QString m_format
Definition: channelinfo.h:229
get_matching_freq_tables
freq_table_list_t get_matching_freq_tables(const QString &format, const QString &modulation, const QString &country)
Definition: frequencytables.cpp:246
PrivateDescriptorID::sky_lcn_table
@ sky_lcn_table
Definition: mpegdescriptors.h:229
PrivateDataSpecifierDescriptor
Definition: dvbdescriptors.h:1900
FrequencyTable::m_frequencyEnd
uint64_t m_frequencyEnd
Definition: frequencytables.h:101
ServiceListDescriptor::ServiceCount
uint ServiceCount(void) const
Definition: dvbdescriptors.h:2125
channelutil.h
SkyLCNDescriptor::ServiceID
uint ServiceID(int i) const
Definition: dvbdescriptors.h:2811
ChannelScanSM::m_threadExit
volatile bool m_threadExit
Definition: channelscan_sm.h:235
DTVTunerType::kTunerTypeDVBS2
static const int kTunerTypeDVBS2
Definition: dtvconfparserhelpers.h:94
ChannelInsertInfo::m_decryptionStatus
int m_decryptionStatus
Definition: channelinfo.h:252
ChannelScanSM::ScanIPTVChannels
bool ScanIPTVChannels(uint sourceid, const fbox_chan_map_t &iptv_channels)
Definition: channelscan_sm.cpp:2414
ServiceListDescriptor::ServiceID
uint ServiceID(uint i) const
Definition: dvbdescriptors.h:2127
ChannelScanSM::GetDTVSignalMonitor
DTVSignalMonitor * GetDTVSignalMonitor(void)
Definition: channelscan_sm.cpp:1906
ServiceDescriptionTable::IsEncrypted
bool IsEncrypted(uint i) const
free_CA_mode 1 3.3+p
Definition: dvbtables.h:160
DTVModulationSystem::toString
QString toString() const
Definition: dtvconfparserhelpers.h:719
MasterGuideTable
This table tells the decoder on which PIDs to find other tables, and their sizes and each table's cur...
Definition: atsctables.h:74
TransportScanItem::m_mplexid
uint m_mplexid
Definition: frequencytables.h:173
gChanLists
const CHANLISTS_vec gChanLists
Definition: frequencies.cpp:2230
FreesatLCNDescriptor::RegionID
uint RegionID(int i, int j) const
Definition: dvbdescriptors.h:2671
ChannelScanSM::GuessDTVTunerType
DTVTunerType GuessDTVTunerType(DTVTunerType type) const
Definition: channelscan_sm.cpp:710
TransportScanItem::freq_offset
uint64_t freq_offset(uint i) const
Definition: frequencytables.cpp:157
ChannelInsertInfo::m_serviceName
QString m_serviceName
Definition: channelinfo.h:217
DVBChannel
Provides interface to the tuning hardware when using DVB drivers.
Definition: dvbchannel.h:30
ChannelScanSM::m_channelTimeout
std::chrono::milliseconds m_channelTimeout
Definition: channelscan_sm.h:212
ChannelScanSM::AddToList
bool AddToList(uint mplexid)
Definition: channelscan_sm.cpp:2515
MPEGStreamData::ReturnCachedPMTTables
virtual void ReturnCachedPMTTables(pmt_vec_t &pmts) const
Definition: mpegstreamdata.cpp:1505
ChannelScanSM::GetDVBChannel
DVBChannel * GetDVBChannel(void)
Definition: channelscan_sm.cpp:1939
BouquetAssociationTable::TransportStreamCount
uint TransportStreamCount(void) const
Definition: dvbtables.h:226
BouquetAssociationTable
Tells what channels can be found on each transponder for one bouquet (a bunch of channels from one pr...
Definition: dvbtables.h:189
ServiceDescriptionTable::HasEITPresentFollowing
bool HasEITPresentFollowing(uint i) const
Definition: dvbtables.h:155
MasterGuideTable::toString
QString toString(void) const override
Definition: atsctables.cpp:69
DTVSignalMonitor::SetChannel
void SetChannel(int major, int minor)
Definition: dtvsignalmonitor.cpp:196
VERBOSE_LEVEL_CHECK
#define VERBOSE_LEVEL_CHECK(_MASK_, _LEVEL_)
Definition: mythlogging.h:14
ChannelScanSM::m_currentInfo
ScannedChannelInfo * m_currentInfo
Definition: channelscan_sm.h:255
SkyLCNDescriptor::LogicalChannelNumber
uint LogicalChannelNumber(int i) const
Definition: dvbdescriptors.h:2820
DTVChannel::TuneMultiplex
virtual bool TuneMultiplex(uint mplexid, const QString &inputname)
To be used by the channel scanner and possibly the EIT scanner.
Definition: dtvchannel.cpp:394
ChannelScanSM::HandleVCT
void HandleVCT(uint tsid, const VirtualChannelTable *vct) override
Definition: channelscan_sm.cpp:419
kChannelVisible
@ kChannelVisible
Definition: channelinfo.h:23
nit_vec_t
std::vector< const NetworkInformationTable * > nit_vec_t
Definition: dvbstreamdata.h:12
SignalMonitor::AddListener
void AddListener(SignalMonitorListener *listener)
Definition: signalmonitor.cpp:387
ChannelInsertInfo::m_sdtTsId
uint m_sdtTsId
Definition: channelinfo.h:237
OriginalNetworkID::NOZEMA
@ NOZEMA
Definition: mpegdescriptors.h:298
ChannelInsertInfo::m_netId
uint m_netId
Definition: channelinfo.h:239
DescriptorID::registration
@ registration
Definition: mpegdescriptors.h:29
ServiceDescriptor::ServiceShortName
QString ServiceShortName(void) const
Definition: dvbdescriptors.h:2072
DTVModulationSystem
Definition: dtvconfparserhelpers.h:644
cardutil.h
DVBLogicalChannelDescriptor::ServiceID
uint ServiceID(uint i) const
Definition: dvbdescriptors.h:2577
ChannelScanSM::m_defAuthorities
QMap< uint64_t, QString > m_defAuthorities
Definition: channelscan_sm.h:249
kRegionUndefined
static const uint kRegionUndefined
Definition: channelscan_sm.cpp:78
BouquetAssociationTable::toString
QString toString(void) const override
Definition: dvbtables.cpp:215
SignalMonitor::RemoveListener
void RemoveListener(SignalMonitorListener *listener)
Definition: signalmonitor.cpp:398
VirtualChannelTable::ServiceType
uint ServiceType(uint i) const
Definition: atsctables.h:293
ScanMonitor::ScanComplete
void ScanComplete(void)
Definition: scanmonitor.cpp:98
ChannelScanSM::kATSCTableTimeout
static const std::chrono::milliseconds kATSCTableTimeout
No logic here, lets just wait at least 10 seconds.
Definition: channelscan_sm.h:202
ChannelScanSM::m_signalMonitor
SignalMonitor * m_signalMonitor
Definition: channelscan_sm.h:209
ChannelScanSM::m_channelList
ChannelList m_channelList
Found Channel Info.
Definition: channelscan_sm.h:253
ScannedChannelInfo::m_pats
pat_map_t m_pats
Definition: channelscan_sm.cpp:106
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:893
std
Definition: mythchrono.h:23
ServiceDescriptor
Definition: dvbdescriptors.h:2043
DTVSignalMonitor::SetStreamData
virtual void SetStreamData(MPEGStreamData *data)
Sets the MPEG stream data for DTVSignalMonitor to use, and connects the table signals to the monitor.
Definition: dtvsignalmonitor.cpp:258
ChannelScanSM::m_channel
ChannelBase * m_channel
Definition: channelscan_sm.h:208
TerrestrialDeliverySystemDescriptor::FrequencyHz
uint64_t FrequencyHz(void) const
Definition: dvbdescriptors.h:943
ChannelInsertInfo::m_serviceId
uint m_serviceId
Definition: channelinfo.h:219
DVBSimulcastChannelDescriptor::ChannelCount
uint ChannelCount(void) const
Definition: dvbdescriptors.h:2603
ChannelScanSM::ScanCurrentTransport
bool ScanCurrentTransport(const QString &sistandard)
Definition: channelscan_sm.cpp:2605
ChannelInsertInfo::m_inSdt
bool m_inSdt
Definition: channelinfo.h:246
TransportScanItem::m_networkID
uint m_networkID
Definition: frequencytables.h:190
ServiceDescriptionTable::GetServiceRelocatedDescriptor
ServiceRelocatedDescriptor * GetServiceRelocatedDescriptor(uint i) const
Definition: dvbtables.cpp:179
ConditionalAccessTable
The CAT is used to transmit additional ConditionalAccessDescriptor instances, in addition to the ones...
Definition: mpegtables.h:855
DTVTunerType::Parse
bool Parse(const QString &_value)
Definition: dtvconfparserhelpers.h:131
ServiceDescriptionTable::ServiceDescriptorsLength
uint ServiceDescriptorsLength(uint i) const
desc_loop_length 12 3.4+p
Definition: dvbtables.h:162
DTVMultiplex::m_sistandard
QString m_sistandard
Definition: dtvmultiplex.h:111
MThread
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:48
ChannelInsertInfo::m_sourceId
uint m_sourceId
Definition: channelinfo.h:214
mthread.h
DTVMultiplex::ParseTuningParams
bool ParseTuningParams(DTVTunerType type, const QString &frequency, const QString &inversion, const QString &symbolrate, const QString &fec, const QString &polarity, const QString &hp_code_rate, const QString &lp_code_rate, const QString &ofdm_modulation, const QString &trans_mode, const QString &guard_interval, const QString &hierarchy, const QString &modulation, const QString &bandwidth, const QString &mod_sys, const QString &rolloff)
Definition: dtvmultiplex.cpp:356
DTVSignalMonitor
This class is intended to detect the presence of needed tables.
Definition: dtvsignalmonitor.h:14
ChannelBase::GetInputID
virtual int GetInputID(void) const
Definition: channelbase.h:67
SkyLCNDescriptor::ServiceCount
uint ServiceCount(void) const
Definition: dvbdescriptors.h:2808
MPEGStreamData::HasCachedAnyPMTs
bool HasCachedAnyPMTs(void) const
Definition: mpegstreamdata.cpp:1326
ScannedChannelInfo::m_programEncryptionStatus
QMap< uint, uint > m_programEncryptionStatus
Definition: channelscan_sm.cpp:108
SignalMonitor::Start
virtual void Start()
Start signal monitoring thread.
Definition: signalmonitor.cpp:290
ChannelScanSM::TestNextProgramEncryption
bool TestNextProgramEncryption(void)
Definition: channelscan_sm.cpp:625
SatelliteDeliverySystemDescriptor
Definition: dvbdescriptors.h:818
ChannelScanSM::HandleAllGood
void HandleAllGood(void)
Definition: channelscan_sm.cpp:254
FrequencyTable::m_nameOffset
int m_nameOffset
Definition: frequencytables.h:99
DTVTransport
Definition: dtvconfparser.h:60
DTVTunerType::kTunerTypeASI
static const int kTunerTypeASI
Definition: dtvconfparserhelpers.h:100
atsctables.h
ScannedChannelInfo::m_nits
nit_vec_t m_nits
Definition: channelscan_sm.cpp:116
MPEGStreamData::HasCachedAllPAT
bool HasCachedAllPAT(uint tsid) const
Definition: mpegstreamdata.cpp:1201
CardUtil::ConvertToTunerType
static DTVTunerType ConvertToTunerType(DTVModulationSystem delsys)
Definition: cardutil.cpp:756
DTVTunerType::kTunerTypeATSC
static const int kTunerTypeATSC
Definition: dtvconfparserhelpers.h:98
MPEGStreamData::AddListeningPID
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
Definition: mpegstreamdata.h:119
ChannelScanSM::LogLines
static void LogLines(const QString &string)
Definition: channelscan_sm.cpp:366
OriginalNetworkID::SKYNZ
@ SKYNZ
Definition: mpegdescriptors.h:296
StreamID::OpenCableVideo
@ OpenCableVideo
Always MPEG-2??
Definition: mpegtables.h:120
DTVChannel
Class providing a generic interface to digital tuning hardware.
Definition: dtvchannel.h:33
ServiceDescriptionTable::HasEITSchedule
bool HasEITSchedule(uint i) const
Definition: dvbtables.h:153
ChannelInsertInfo::m_serviceType
uint m_serviceType
Definition: channelinfo.h:220
ChannelScanSM::HandleCAT
void HandleCAT(const ConditionalAccessTable *cat) override
Definition: channelscan_sm.cpp:393
DefaultAuthorityDescriptor
Definition: dvbdescriptors.h:2921
SignalMonitor::HasSignalLock
bool HasSignalLock(void) const
Returns true iff scriptStatus.IsGood() and signalLock.IsGood() return true.
Definition: signalmonitor.h:79
update_info
static void update_info(ChannelInsertInfo &info, const VirtualChannelTable *vct, uint i)
Definition: channelscan_sm.cpp:1164
TransportScanItem::m_transportID
uint m_transportID
Definition: frequencytables.h:191
DTVModulationSystem::kModulationSystem_DVBT2
@ kModulationSystem_DVBT2
Definition: dtvconfparserhelpers.h:672
DTVTunerType::kTunerTypeDVBT
static const int kTunerTypeDVBT
Definition: dtvconfparserhelpers.h:96
DVBStreamData::HasCachedAnyNIT
bool HasCachedAnyNIT(bool current=true) const
Definition: dvbstreamdata.cpp:614
ATSCStreamData::HasCachedAnyVCTs
bool HasCachedAnyVCTs(bool current=true) const
Definition: atscstreamdata.h:82
SkyLCNDescriptor::RegionID
uint RegionID(void) const
Definition: dvbdescriptors.h:2802
ChannelScanSM::ScanTransportsStartingOn
bool ScanTransportsStartingOn(int sourceid, const QMap< QString, QString > &startChan)
Generates a list of frequencies to scan and adds it to the scanTransport list, and then sets the scan...
Definition: channelscan_sm.cpp:2453
NetworkInformationTable::TransportStreamCount
uint TransportStreamCount(void) const
Definition: dvbtables.h:75
SignalMonitor::Stop
virtual void Stop()
Stop signal monitoring thread.
Definition: signalmonitor.cpp:306
VirtualChannelTable::ModulationMode
uint ModulationMode(uint i) const
Definition: atsctables.h:254
ChannelScanSM::m_lcnOffset
uint m_lcnOffset
Definition: channelscan_sm.h:225
ChannelScanSM::m_inputName
QString m_inputName
Definition: channelscan_sm.h:216
MPEGDescriptor::Find
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
Definition: mpegdescriptors.cpp:78
ChannelScanSM::GetChannelList
chan_info_map_t GetChannelList(transport_scan_items_it_t trans_info, ScannedChannelInfo *scan_info) const
Definition: channelscan_sm.cpp:1357
ScanMonitor::ScanUpdateStatusText
void ScanUpdateStatusText(const QString &status)
Definition: scanmonitor.cpp:114
hdhrchannel.h
ChannelScanSM::GetDTVChannel
DTVChannel * GetDTVChannel(void)
Definition: channelscan_sm.cpp:1920
DTVTunerType::kTunerTypeDVBT2
static const int kTunerTypeDVBT2
Definition: dtvconfparserhelpers.h:97
ChannelInsertInfo::m_vctChanTsId
uint m_vctChanTsId
Definition: channelinfo.h:236
ChannelScanSM::ScanTransport
bool ScanTransport(uint mplexid, bool follow_nit)
Definition: channelscan_sm.cpp:2583
ChannelScanSM::m_testDecryption
bool m_testDecryption
Definition: channelscan_sm.h:217
VirtualChannelTable::ChannelCount
uint ChannelCount() const
Definition: atsctables.h:221
V4LChannel
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
Definition: v4lchannel.h:30
ChannelScanSM::ScanExistingTransports
bool ScanExistingTransports(uint sourceid, bool follow_nit)
If we are not already scanning a frequency table, this creates a new frequency table from database an...
Definition: channelscan_sm.cpp:321
DescriptorID::satellite_delivery_system
@ satellite_delivery_system
Definition: mpegdescriptors.h:75
VirtualChannelTable::TransportStreamID
uint TransportStreamID() const
Definition: atsctables.h:218
ChannelInsertInfo::m_patTsId
uint m_patTsId
Definition: channelinfo.h:234
ServiceListDescriptor
Definition: dvbdescriptors.h:2111
fbox_chan_map_t
QMap< QString, IPTVChannelInfo > fbox_chan_map_t
Definition: iptvchannelfetcher.h:62
ChannelScanSM::~ChannelScanSM
~ChannelScanSM() override
Definition: channelscan_sm.cpp:217
DVBStreamData::ReturnCachedSDTTables
void ReturnCachedSDTTables(sdt_vec_t &sdts) const
Definition: dvbstreamdata.cpp:929
TransportScanItem::toString
QString toString() const
Definition: frequencytables.cpp:164
ChannelInsertInfo::m_oldTsId
uint m_oldTsId
Definition: channelinfo.h:256
ChannelInsertInfo::m_oldServiceId
uint m_oldServiceId
Definition: channelinfo.h:257
dtvsignalmonitor.h
MPEGStreamData::TestDecryption
void TestDecryption(const ProgramMapTable *pmt)
Definition: mpegstreamdata.cpp:1807
ChannelInsertInfo::m_inVct
bool m_inVct
Definition: channelinfo.h:244
FrequencyTable::m_frequencyStart
uint64_t m_frequencyStart
Definition: frequencytables.h:100
ChannelScanSM::m_currentEncryptionStatus
QMap< uint, uint > m_currentEncryptionStatus
Definition: channelscan_sm.h:247
FreesatLCNDescriptor::LogicalChannelNumber
uint LogicalChannelNumber(int i, int j) const
Definition: dvbdescriptors.h:2668
ChannelScanSM::CheckImportedList
bool CheckImportedList(const DTVChannelInfoList &channels, uint mpeg_program_num, QString &service_name, QString &callsign, QString &common_status_info)
If we are scanning a dvb-utils import verify channel is in list.
Definition: channelscan_sm.cpp:2627
ServiceDescriptionTable::ServiceDescriptors
const unsigned char * ServiceDescriptors(uint i) const
for (j=0;j<N;j++) x 5.0+p { descriptor() }
Definition: dvbtables.h:166
ATSCStreamData::GetCachedMGT
const MasterGuideTable * GetCachedMGT(bool current=true) const
Definition: atscstreamdata.cpp:773
ChannelListItem
QPair< transport_scan_items_it_t, ScannedChannelInfo * > ChannelListItem
Definition: channelscan_sm.h:66
DTVModulationSystem::kModulationSystem_DVBT
@ kModulationSystem_DVBT
Definition: dtvconfparserhelpers.h:659
ChannelScanSM::m_currentEncryptionStatusChecked
QMap< uint, bool > m_currentEncryptionStatusChecked
Definition: channelscan_sm.h:248
ServiceDescriptor::IsDigitalAudio
bool IsDigitalAudio(void) const
Definition: dvbdescriptors.h:2079
ChannelInsertInfo::m_siStandard
QString m_siStandard
Definition: channelinfo.h:240
ScanMonitor
Definition: scanmonitor.h:44
transport_scan_items_it_t::nextTransport
transport_scan_items_it_t nextTransport() const
Definition: frequencytables.h:255
ServiceDescriptionTable::TSID
uint TSID() const
transport_stream_id 16 3.0 0x0000
Definition: dvbtables.h:138
VirtualChannelTable::MinorChannel
uint MinorChannel(uint i) const
Definition: atsctables.h:249
ChannelScanSM::UpdateScanPercentCompleted
void UpdateScanPercentCompleted(void)
Definition: channelscan_sm.h:267
SignalMonitor::kDTVSigMon_WaitForVCT
static const uint64_t kDTVSigMon_WaitForVCT
Definition: signalmonitor.h:186
DescriptorID::private_data_specifier
@ private_data_specifier
Definition: mpegdescriptors.h:104
ChannelScanSM::HasTimedOut
bool HasTimedOut(void)
Definition: channelscan_sm.cpp:2004
ChannelScanSM::ScanForChannels
bool ScanForChannels(uint sourceid, const QString &std, const QString &cardtype, const DTVChannelList &channels)
Definition: channelscan_sm.cpp:2374
ChannelScanSM::m_regionId
uint m_regionId
Definition: channelscan_sm.h:223
DVBSimulcastChannelDescriptor::ServiceID
uint ServiceID(uint i) const
Definition: dvbdescriptors.h:2605
ScanDTVTransport
Definition: dtvmultiplex.h:115
ScanDTVTransport::m_channels
ChannelInsertInfoList m_channels
Definition: dtvmultiplex.h:138
DTVModulationSystem::kModulationSystem_DVBC_ANNEX_A
@ kModulationSystem_DVBC_ANNEX_A
Definition: dtvconfparserhelpers.h:657
FreesatLCNDescriptor::ServiceCount
uint ServiceCount(void) const
Definition: dvbdescriptors.h:2656
DefaultAuthorityDescriptor::DefaultAuthority
QString DefaultAuthority(void) const
Definition: dvbdescriptors.h:2930
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837
DTVModulationSystem::Parse
bool Parse(const QString &_value)
Definition: dtvconfparserhelpers.h:716
ChannelScanSM::GetSignalMonitor
SignalMonitor * GetSignalMonitor(void)
Definition: channelscan_sm.h:128
DVBStreamData::GetCachedSDTSections
sdt_vec_t GetCachedSDTSections(uint tsid, bool current=true) const
Definition: dvbstreamdata.cpp:881
NetworkInformationTable
This table tells the decoder on which PIDs to find other tables.
Definition: dvbtables.h:30
VirtualChannelTable::GetExtendedChannelName
QString GetExtendedChannelName(uint idx) const
Definition: atsctables.cpp:506
ScanMonitor::ScanUpdateStatusTitleText
void ScanUpdateStatusTitleText(const QString &status)
Definition: scanmonitor.cpp:123