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