MythTV  master
channelbase.cpp
Go to the documentation of this file.
1 // Std C headers
2 #include <cstdlib>
3 #include <cerrno>
4 
5 // POSIX headers
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 
11 // C++ headers
12 #include <iostream>
13 #include <algorithm>
14 
15 // Qt headers
16 #include <QCoreApplication>
17 
18 // MythTV headers
19 #include "libmythbase/compat.h"
20 #include "libmythbase/exitcodes.h"
23 
24 #ifdef USING_OSX_FIREWIRE
25 #include "darwinfirewiredevice.h"
26 #endif
27 #ifdef USING_LINUX_FIREWIRE
28 #include "linuxfirewiredevice.h"
29 #endif
30 #include "firewirechannel.h"
31 #include "cetonchannel.h"
32 #include "dummychannel.h"
33 #include "tvremoteutil.h"
34 #include "channelbase.h"
35 #include "channelutil.h"
36 #include "frequencies.h"
37 #include "hdhrchannel.h"
38 #include "iptvchannel.h"
39 #include "asichannel.h"
40 #include "dtvchannel.h"
41 #include "dvbchannel.h"
42 #include "v4lchannel.h"
43 #include "ExternalChannel.h"
44 #include "sourceutil.h"
45 #include "cardutil.h"
46 #include "inputinfo.h"
47 #include "satipchannel.h"
48 
49 #define LOC QString("ChannelBase[%1]: ").arg(m_inputId)
50 
51 ChannelBase::ChannelBase(TVRec *parent) : m_pParent(parent)
52 {
53  if (m_pParent)
54  {
56  }
57 }
58 
60 {
61  QMutexLocker locker(&m_systemLock);
62  if (m_system)
63  KillScript();
64 }
65 
66 bool ChannelBase::Init(QString &startchannel, bool setchan)
67 {
68  bool ok = false;
69 
70  if (!setchan)
71  ok = IsTunable(startchannel);
72  else
73  ok = SetChannelByString(startchannel);
74 
75  if (ok)
76  return true;
77 
78  // Try to find a valid channel if given start channel fails.
79  QString msg1 = QString("Setting start channel '%1' failed ").arg(startchannel);
80  QString msg2 = "and no suitable channel found.";
81  bool msg_error = true;
82 
83  // Attempt to find the requested startchannel
84  for (auto & channel : m_channels)
85  {
86  if (channel.m_chanNum == startchannel &&
87  IsTunable(startchannel))
88  {
89  LOG(VB_CHANNEL, LOG_INFO, LOC +
90  QString("Found startchannel '%1'").arg(startchannel));
91  return true;
92  }
93  }
94 
95  uint mplexid_restriction = 0;
96  uint chanid_restriction = 0;
97 
98  if (!m_channels.empty() &&
99  IsInputAvailable(mplexid_restriction, chanid_restriction))
100  {
102  m_channels, m_channels[0].m_chanId,
103  mplexid_restriction, chanid_restriction, CHANNEL_DIRECTION_UP);
104 
105  auto cit = find(m_channels.begin(), m_channels.end(), chanid);
106 
107  if ((chanid != 0U) && (cit != m_channels.end()))
108  {
109  if (!setchan)
110  {
111  ok = IsTunable((mplexid_restriction || chanid_restriction)
112  ? (*cit).m_chanNum : startchannel);
113  }
114  else
115  ok = SetChannelByString((*cit).m_chanNum);
116 
117  if (ok)
118  {
119  startchannel = (*cit).m_chanNum;
120  msg2 = QString("selected '%1' instead.").arg(startchannel);
121  msg_error = false;
122  }
123  }
124  }
125 
126  LOG(VB_GENERAL, ((msg_error) ? LOG_ERR : LOG_WARNING), LOC + msg1 + msg2);
127 
128  return ok;
129 }
130 
131 bool ChannelBase::IsTunable(const QString &channum) const
132 {
133  QString loc = LOC + QString("IsTunable(%1)").arg(channum);
134 
135  if (!m_inputId)
136  {
137  LOG(VB_GENERAL, LOG_ERR, loc + " " +
138  QString("Requested non-existant input"));
139 
140  return false;
141  }
142 
143  uint mplexid_restriction = 0;
144  uint chanid_restriction = 0;
145  if (!IsInputAvailable(mplexid_restriction, chanid_restriction))
146  {
147  LOG(VB_GENERAL, LOG_ERR, loc + " " +
148  QString("Requested channel is on input '%1' "
149  "which is in a busy input group")
150  .arg(m_inputId));
151 
152  return false;
153  }
154 
155  // Fetch tuning data from the database.
156  QString tvformat;
157  QString modulation;
158  QString freqtable;
159  QString freqid;
160  QString dtv_si_std;
161  int finetune = 0;
162  uint64_t frequency = 0;
163  int mpeg_prog_num = 0;
164  uint atsc_major = 0;
165  uint atsc_minor = 0;
166  uint mplexid = 0;
167  uint chanid = 0;
168  uint tsid = 0;
169  uint netid = 0;
170  bool commfree = false;
171 
172  if (!ChannelUtil::GetChannelData(m_sourceId, chanid, channum,
173  tvformat, modulation, freqtable, freqid,
174  finetune, frequency, dtv_si_std,
175  mpeg_prog_num, atsc_major, atsc_minor,
176  tsid, netid, mplexid, commfree))
177  {
178  LOG(VB_GENERAL, LOG_ERR, loc + " " +
179  QString("Failed to find channel in DB on input '%1' ")
180  .arg(m_inputId));
181 
182  return false;
183  }
184 
185  if ((mplexid_restriction && (mplexid != mplexid_restriction)) ||
186  (!mplexid_restriction &&
187  chanid_restriction && (chanid != chanid_restriction)))
188  {
189  LOG(VB_GENERAL, LOG_ERR, loc + " " +
190  QString("Channel is valid, but tuner is busy "
191  "on different multiplex/channel (%1 != %2) / (%3 != %4)")
192  .arg(mplexid).arg(mplexid_restriction)
193  .arg(chanid).arg(chanid_restriction));
194 
195  return false;
196  }
197 
198  return true;
199 }
200 
202 {
203  if (!chanid)
204  {
205  if (!m_inputId)
206  return 0;
207 
209  }
210 
211  uint mplexid_restriction = 0;
212  uint chanid_restriction = 0;
213  (void)IsInputAvailable(mplexid_restriction, chanid_restriction);
214 
216  m_channels, chanid, mplexid_restriction, chanid_restriction,
217  direction);
218 }
219 
220 uint ChannelBase::GetNextChannel(const QString &channum, ChannelChangeDirection direction) const
221 {
222  if (!m_inputId)
223  return 0;
224 
225  uint chanid = ChannelUtil::GetChanID(m_sourceId, channum);
226  return GetNextChannel(chanid, direction);
227 }
228 
230  uint &mplexid_restriction, uint &chanid_restriction) const
231 {
232  if (!m_inputId)
233  {
234  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("no m_inputId"));
235  return false;
236  }
237 
238  InputInfo info;
239 
240  mplexid_restriction = 0;
241  chanid_restriction = 0;
242 
243  std::vector<uint> inputids = CardUtil::GetConflictingInputs(m_inputId);
244  for (uint inputid : inputids)
245  {
246  if (RemoteIsBusy(inputid, info))
247  {
248  LOG(VB_CHANNEL, LOG_DEBUG, LOC +
249  QString("Input %1 is busy on %2/%3")
250  .arg(info.m_inputId)
251  .arg(info.m_chanId).arg(info.m_mplexId));
252  if (info.m_sourceId != m_sourceId)
253  {
254  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("Input is busy"));
255  return false;
256  }
257  mplexid_restriction = info.m_mplexId;
258  chanid_restriction = info.m_chanId;
259  }
260  }
261 
262  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("Input is free on %1/%2")
263  .arg(mplexid_restriction).arg(chanid_restriction));
264  return true;
265 }
266 
269 {
270  if (!m_system)
271  return true;
272 
273  m_system->Term(true);
274 
275  delete m_system;
276  m_system = nullptr;
277  return true;
278 }
279 
281 void ChannelBase::HandleScript(const QString &freqid)
282 {
283  QMutexLocker locker(&m_systemLock);
284 
285  bool ok = true;
286  m_systemStatus = 0; // unknown
287 
288  if (!m_inputId)
289  {
290  m_systemStatus = 2; // failed
291  HandleScriptEnd(true);
292  return;
293  }
294 
295  if (m_externalChanger.isEmpty())
296  {
297  m_systemStatus = 3; // success
298  HandleScriptEnd(true);
299  return;
300  }
301 
302  if (freqid.isEmpty())
303  {
304  LOG(VB_GENERAL, LOG_WARNING, LOC +
305  "A channel changer is set, but the freqid field is empty."
306  "\n\t\t\tWe will return success to ease setup pains, "
307  "but no script is will actually run.");
308  m_systemStatus = 3; // success
309  HandleScriptEnd(true);
310  return;
311  }
312 
313  // It's possible we simply never reaped the process, check status first.
314  if (m_system)
315  GetScriptStatus(true);
316 
317  // If it's still running, try killing it. GetScriptStatus() may
318  // update m_system. (cppcheck-suppress duplicateCondition)
319  if (m_system)
320  ok = KillScript();
321 
322  // The GetScriptStatus() call above can reset m_systemStatus with
323  // the exit status of the last channel change script invocation, so
324  // we must set it to pending here.
325  m_systemStatus = 1; // pending
326 
327  if (!ok)
328  {
329  LOG(VB_GENERAL, LOG_ERR, LOC +
330  "Can not execute channel changer, previous call to script "
331  "is still running.");
332  m_systemStatus = 2; // failed
333  HandleScriptEnd(ok);
334  }
335  else
336  {
337  if (m_externalChanger.toLower() == "internal")
338  {
339  ok = ChangeInternalChannel(freqid, m_inputId);
340  if (!ok)
341  {
342  LOG(VB_GENERAL, LOG_ERR, LOC + "Can not execute internal channel "
343  "changer.");
344  m_systemStatus = 2; // failed
345  }
346  else
347  m_systemStatus = 3; // success
348 
349  HandleScriptEnd(ok);
350  }
351  else
352  {
354  if (!ok)
355  {
356  LOG(VB_GENERAL, LOG_ERR, LOC + "Can not execute channel changer.");
357  m_systemStatus = 2; // failed
358  HandleScriptEnd(ok);
359  }
360  }
361  }
362 }
363 
364 bool ChannelBase::ChangeInternalChannel([[maybe_unused]] const QString &freqid,
365  [[maybe_unused]] uint inputid) const
366 {
367 #ifdef USING_FIREWIRE
368  FirewireDevice *device = nullptr;
369  QString fwnode = CardUtil::GetFirewireChangerNode(inputid);
370  uint64_t guid = string_to_guid(fwnode);
371  QString fwmodel = CardUtil::GetFirewireChangerModel(inputid);
372 
373  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Internal channel change to %1 "
374  "on inputid %2, GUID %3 (%4)").arg(freqid).arg(inputid)
375  .arg(fwnode, fwmodel));
376 
377 #ifdef USING_LINUX_FIREWIRE
378  device = new LinuxFirewireDevice(
379  guid, 0, 100, true);
380 #endif // USING_LINUX_FIREWIRE
381 
382 #ifdef USING_OSX_FIREWIRE
383  device = new DarwinFirewireDevice(guid, 0, 100);
384 #endif // USING_OSX_FIREWIRE
385 
386  if (!device)
387  return false;
388 
389  if (!device->OpenPort())
390  return false;
391 
392  if (!device->SetChannel(fwmodel, 0, freqid.toUInt()))
393  {
394  device->ClosePort();
395  delete device;
396  device = nullptr;
397  return false;
398  }
399 
400  device->ClosePort();
401  delete device;
402  device = nullptr;
403  return true;
404 #else
405  return false;
406 #endif
407 }
408 
410 bool ChannelBase::ChangeExternalChannel(const QString &changer,
411  const QString &freqid)
412 {
413  if (m_system)
414  return false;
415 
416  if (changer.isEmpty() || freqid.isEmpty())
417  return false;
418 
419  QString command = QString("%1 %2").arg(changer, freqid);
420  LOG(VB_CHANNEL, LOG_INFO, LOC +
421  QString("Running command: %1").arg(command));
422 
424  m_system->Run();
425 
426  return true;
427 }
428 
430 {
431  if (!m_system)
432  return m_systemStatus;
433 
434  if (!holding_lock)
435  m_systemLock.lock();
436 
440  {
441  delete m_system;
442  m_system = nullptr;
443 
445  }
446 
447  LOG(VB_CHANNEL, LOG_DEBUG, LOC + QString("GetScriptStatus() %1")
448  .arg(m_systemStatus));
449 
450  uint ret = 0;
451  switch(m_systemStatus)
452  {
453  case GENERIC_EXIT_OK:
454  ret = 3; // success
455  break;
457  case GENERIC_EXIT_START:
458  ret = 1; // pending
459  break;
460  default:
461  ret = 2; // fail
462  break;
463  }
464 
465  LOG(VB_CHANNEL, LOG_DEBUG, LOC + QString("GetScriptStatus() %1 -> %2")
466  .arg(m_systemStatus). arg(ret));
467 
468  m_systemStatus = ret;
469 
470  if (!holding_lock)
471  m_systemLock.unlock();
472 
473  return ret;
474 }
475 
478 {
479  if (ok)
480  {
481  LOG(VB_CHANNEL, LOG_INFO, LOC + "Channel change script succeeded.");
482  if (m_inputId)
483  {
484  // Set this as the future start channel for this source
486  }
487  }
488  else
489  {
490  LOG(VB_GENERAL, LOG_ERR, LOC + "Channel change script failed.");
491  }
492 }
493 
494 int ChannelBase::GetChanID(void) const
495 {
496  if (!m_inputId)
497  return -1;
498 
499  int found = 0;
500  int visible = -1;
501  int id = -1;
502  MSqlQuery query(MSqlQuery::InitCon());
503 
504  query.prepare("SELECT chanid,visible FROM channel "
505  "WHERE deleted IS NULL AND "
506  " channum = :CHANNUM AND "
507  " sourceid = :SOURCEID");
508  query.bindValueNoNull(":CHANNUM", m_curChannelName);
509  query.bindValue(":SOURCEID", m_sourceId);
510 
511  if (!query.exec() || !query.isActive())
512  {
513  MythDB::DBError("fetching chanid", query);
514  return -1;
515  }
516 
517  while (query.next())
518  {
519  if (query.value(1).toInt() > 0)
520  {
521  ++found;
522  visible = query.value(0).toInt();
523  }
524  else
525  id = query.value(0).toInt();
526  }
527 
528  if (!found)
529  {
530  LOG(VB_GENERAL, LOG_INFO,
531  QString("No visible channel ids for %1 on sourceid %2")
532  .arg(m_curChannelName).arg(m_sourceId));
533  }
534 
535  if (found > 1)
536  {
537  LOG(VB_GENERAL, LOG_WARNING,
538  QString("Found multiple visible channel ids for %1 on sourceid %2")
539  .arg(m_curChannelName).arg(m_sourceId));
540  }
541 
542  return (visible >= 0 ? visible : id);
543 }
544 
549 {
550  if (!m_inputId)
551  {
552  if (m_pParent)
554  else
556  }
557 
558  if (!m_inputId)
559  {
560  LOG(VB_GENERAL, LOG_ERR,
561  "InitializeInput(): Programmer error, no parent.");
562  return false;
563  }
564 
565  MSqlQuery query(MSqlQuery::InitCon());
566  query.prepare(
567  "SELECT sourceid, inputname, "
568  " startchan, externalcommand, "
569  " tunechan "
570  "FROM capturecard "
571  "WHERE cardid = :INPUTID");
572  query.bindValue(":INPUTID", m_inputId);
573 
574  if (!query.exec() || !query.isActive())
575  {
576  MythDB::DBError("ChannelBase::InitializeInput", query);
577  return false;
578  }
579  if (!query.size())
580  {
581  LOG(VB_GENERAL, LOG_ERR, LOC +
582  QString("No capturecard record in database for input %1")
583  .arg(m_inputId));
584  return false;
585  }
586 
587  query.next();
588 
589  m_sourceId = query.value(0).toUInt();
590  m_name = query.value(1).toString();
591  m_startChanNum = query.value(2).toString();
592  m_externalChanger = query.value(3).toString();
593  m_tuneToChannel = query.value(4).toString();
594 
595  if (0 == m_sourceId)
596  {
597  LOG(VB_GENERAL, LOG_ERR, LOC +
598  QString("No video source defined for input %1")
599  .arg(m_inputId));
600  return false;
601  }
602 
604  QString order = gCoreContext->GetSetting("ChannelOrdering", "channum");
606 
608  !m_externalChanger.isEmpty())
609  {
610  LOG(VB_GENERAL, LOG_WARNING, LOC + "External Channel changer is "
611  "set, but this device does not support it.");
612  m_externalChanger.clear();
613  }
614 
615  // print it
616  LOG(VB_CHANNEL, LOG_INFO, LOC +
617  QString("Input #%1: '%2' schan(%3) sourceid(%4)")
618  .arg(m_inputId).arg(m_name, m_startChanNum)
619  .arg(m_sourceId));
620 
621  return true;
622 }
623 
628  const QString &oldChanNum,
629  const QString &newChanNum)
630 {
631  bool skip = (m_name.isEmpty() ||
632  m_startChanNum.isEmpty() ||
633  m_startChanNum != oldChanNum ||
634  m_sourceId != sourceid);
635  if (!skip)
636  m_startChanNum = newChanNum;
637 
638  if (GetSourceID() == sourceid && oldChanNum == m_curChannelName)
639  m_curChannelName = newChanNum;
640 
642 }
643 
648 {
649  MSqlQuery query(MSqlQuery::InitCon());
650 
651  if (m_name.isEmpty() || m_startChanNum.isEmpty())
652  return;
653 
654  query.prepare(
655  "UPDATE capturecard "
656  "SET startchan = :STARTCHAN "
657  "WHERE cardid = :CARDINPUTID");
658  query.bindValue(":STARTCHAN", m_startChanNum);
659  query.bindValue(":CARDINPUTID", m_inputId);
660 
661  if (!query.exec() || !query.isActive())
662  MythDB::DBError("StoreInputChannels", query);
663 }
664 
665 bool ChannelBase::CheckChannel(const QString &channum) const
666 {
667  MSqlQuery query(MSqlQuery::InitCon());
668  if (!query.isConnected())
669  return false;
670 
671  query.prepare(
672  "SELECT channel.chanid "
673  "FROM channel, capturecard "
674  "WHERE channel.deleted IS NULL AND "
675  " channel.channum = :CHANNUM AND "
676  " channel.sourceid = capturecard.sourceid AND "
677  " capturecard.cardid = :INPUTID AND "
678  " capturecard.hostname = :HOSTNAME");
679  query.bindValue(":CHANNUM", channum);
680  query.bindValue(":INPUTID", m_inputId);
681  query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
682 
683  if (!query.exec() || !query.isActive())
684  {
685  MythDB::DBError("checkchannel", query);
686  }
687  else if (query.size() > 0)
688  return true;
689 
690  LOG(VB_CHANNEL, LOG_ERR, LOC +
691  QString("Failed to find channel(%1) on input (%2).")
692  .arg(channum).arg(m_inputId));
693  return false;
694 }
695 
697  TVRec *tvrec,
698  const GeneralDBOptions &genOpt,
699  const DVBDBOptions &dvbOpt,
700  [[maybe_unused]] const FireWireDBOptions &fwOpt,
701  const QString &startchannel,
702  bool enter_power_save_mode,
703  QString &rbFileExt,
704  bool setchan)
705 {
706  rbFileExt = "ts";
707 
708  ChannelBase *channel = nullptr;
709  if (genOpt.m_inputType == "DVB")
710  {
711 #ifdef USING_DVB
712  channel = new DVBChannel(genOpt.m_videoDev, tvrec);
713  auto *dvbchannel = dynamic_cast<DVBChannel*>(channel);
714  if (dvbchannel != nullptr)
715  dvbchannel->SetSlowTuning(dvbOpt.m_dvbTuningDelay);
716 #endif
717  }
718  else if (genOpt.m_inputType == "FIREWIRE")
719  {
720 #ifdef USING_FIREWIRE
721  channel = new FirewireChannel(tvrec, genOpt.m_videoDev, fwOpt);
722 #endif
723  }
724 #ifdef USING_HDHOMERUN
725  else if (genOpt.m_inputType == "HDHOMERUN")
726  {
727  channel = new HDHRChannel(tvrec, genOpt.m_videoDev);
728  }
729 #endif
730 #ifdef USING_SATIP
731  else if (genOpt.m_inputType == "SATIP")
732  {
733  channel = new SatIPChannel(tvrec, genOpt.m_videoDev);
734  }
735 #endif
736  else if ((genOpt.m_inputType == "IMPORT") ||
737  (genOpt.m_inputType == "DEMO") ||
738  (genOpt.m_inputType == "MPEG" &&
739  genOpt.m_videoDev.startsWith("file:", Qt::CaseInsensitive)))
740  {
741  channel = new DummyChannel(tvrec);
742  rbFileExt = "mpg";
743  }
744 #if defined(USING_IPTV) || defined(USING_VBOX)
745  else if ((genOpt.m_inputType == "FREEBOX") || // IPTV
746  (genOpt.m_inputType == "VBOX"))
747  {
748  channel = new IPTVChannel(tvrec, genOpt.m_videoDev);
749  }
750 #endif
751 #ifdef USING_ASI
752  else if (genOpt.m_inputType == "ASI")
753  {
754  channel = new ASIChannel(tvrec, genOpt.m_videoDev);
755  }
756 #endif
757 #ifdef USING_CETON
758  else if (genOpt.m_inputType == "CETON")
759  {
760  channel = new CetonChannel(tvrec, genOpt.m_videoDev);
761  }
762 #endif
763  else if (genOpt.m_inputType == "V4L2ENC")
764  {
765 #ifdef USING_V4L2
766  channel = new V4LChannel(tvrec, genOpt.m_videoDev);
767 #endif
768  if (genOpt.m_inputType == "MPEG")
769  rbFileExt = "mpg";
770  }
771  else if (CardUtil::IsV4L(genOpt.m_inputType))
772  {
773 #ifdef USING_V4L2
774  channel = new V4LChannel(tvrec, genOpt.m_videoDev);
775 #endif
776  if (genOpt.m_inputType != "HDPVR")
777  {
778  if (genOpt.m_inputType != "MPEG")
779  rbFileExt = "nuv";
780  else
781  rbFileExt = "mpg";
782  }
783  }
784  else if (genOpt.m_inputType == "EXTERNAL")
785  {
786  channel = new ExternalChannel(tvrec, genOpt.m_videoDev);
787  }
788 
789  if (!channel)
790  {
791  QString msg = QString(
792  "%1 card configured on video device %2, \n"
793  "but MythTV was not compiled with %3 support. \n"
794  "\n"
795  "Recompile MythTV with %4 support or remove the card \n"
796  "from the configuration and restart MythTV.")
797  .arg(genOpt.m_inputType, genOpt.m_videoDev,
798  genOpt.m_inputType, genOpt.m_inputType);
799  LOG(VB_GENERAL, LOG_ERR, "ChannelBase: CreateChannel() Error: \n" +
800  msg + "\n");
801  return nullptr;
802  }
803 
804  if (!channel->Open())
805  {
806  LOG(VB_GENERAL, LOG_ERR, "ChannelBase: CreateChannel() Error: " +
807  QString("Failed to open device %1").arg(genOpt.m_videoDev));
808  delete channel;
809  return nullptr;
810  }
811 
812  QString channum = startchannel;
813  channel->Init(channum, setchan);
814 
815  if (enter_power_save_mode)
816  {
817  if (channel &&
818  ((genOpt.m_inputType == "DVB" && dvbOpt.m_dvbOnDemand) ||
819  genOpt.m_inputType == "HDHOMERUN" ||
820  genOpt.m_inputType == "EXTERNAL" ||
821  CardUtil::IsV4L(genOpt.m_inputType)))
822  {
823  channel->Close();
824  }
825  else if (setchan)
826  {
827  auto *dtvchannel = dynamic_cast<DTVChannel*>(channel);
828  if (dtvchannel)
829  dtvchannel->EnterPowerSavingMode();
830  }
831  }
832 
833  return channel;
834 }
835 
837 {
839  return false;
840 
841  if (!m_inputId)
842  {
843  LOG(VB_GENERAL, LOG_ERR, LOC +
844  QString("IsExternalChannelChangeInUse: "
845  "non-existant input"));
846  return false;
847  }
848 
849  return !m_externalChanger.isEmpty();
850 }
851 
853 {
854  return m_pParent ? m_pParent->GetMajorId() : m_inputId;
855 }
GeneralDBOptions
Definition: tv_rec.h:65
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:813
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
ChannelBase::Close
virtual void Close(void)=0
Closes the channel changing hardware to use.
linuxfirewiredevice.h
dtvchannel.h
ChannelBase::Init
virtual bool Init(QString &startchannel, bool setchan)
Definition: channelbase.cpp:66
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:214
MSqlQuery::bindValueNoNull
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
Definition: mythdbcon.cpp:903
InputInfo::m_chanId
uint m_chanId
chanid restriction if applicable
Definition: inputinfo.h:51
MythSystemLegacy::Term
void Term(bool force=false)
Definition: mythsystemlegacy.cpp:285
TVRec::GetMajorId
uint GetMajorId(void)
Definition: tv_rec.h:236
ChannelChangeDirection
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
Definition: tv.h:28
MythSystemLegacy
Definition: mythsystemlegacy.h:67
ChannelBase::m_name
QString m_name
Definition: channelbase.h:139
CHANNEL_DIRECTION_UP
@ CHANNEL_DIRECTION_UP
Definition: tv.h:30
ChannelBase::HandleScriptEnd
virtual void HandleScriptEnd(bool ok)
Definition: channelbase.cpp:477
ChannelBase::Open
virtual bool Open(void)=0
Opens the channel changing hardware for use.
darwinfirewiredevice.h
CardUtil::GetFirstInputID
static uint GetFirstInputID(const QString &videodevice)
Convenience function for GetInputIDs()
Definition: cardutil.h:268
firewirechannel.h
GeneralDBOptions::m_inputType
QString m_inputType
Definition: tv_rec.h:73
frequencies.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
DarwinFirewireDevice
Definition: darwinfirewiredevice.h:10
ChannelBase::CreateChannel
static ChannelBase * CreateChannel(TVRec *tvrec, const GeneralDBOptions &genOpt, const DVBDBOptions &dvbOpt, const FireWireDBOptions &fwOpt, const QString &startchannel, bool enter_power_save_mode, QString &rbFileExt, bool setchan)
Definition: channelbase.cpp:696
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:619
ChannelBase::m_inputId
uint m_inputId
Definition: channelbase.h:137
ChannelBase::IsTunable
virtual bool IsTunable(const QString &channum) const
Definition: channelbase.cpp:131
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
CetonChannel
Definition: cetonchannel.h:22
string_to_guid
static uint64_t string_to_guid(const QString &guid)
Definition: avcinfo.h:17
channelbase.h
ChannelBase::m_startChanNum
QString m_startChanNum
Definition: channelbase.h:140
ChannelBase::m_systemLock
QMutex m_systemLock
Definition: channelbase.h:145
ChannelUtil::GetNextChannel
static uint GetNextChannel(const ChannelInfoList &sorted, uint old_chanid, uint mplexid_restriction, uint chanid_restriction, ChannelChangeDirection direction, bool skip_non_visible=true, bool skip_same_channum_and_callsign=false, bool skip_other_sources=false)
Definition: channelutil.cpp:2382
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:11
ChannelBase::m_tuneToChannel
QString m_tuneToChannel
Definition: channelbase.h:142
satipchannel.h
ChannelBase::IsExternalChannelChangeSupported
virtual bool IsExternalChannelChangeSupported(void)
Definition: channelbase.h:121
dvbchannel.h
HDHRChannel
Definition: hdhrchannel.h:20
CardUtil::GetFirewireChangerModel
static QString GetFirewireChangerModel(uint inputid)
Definition: cardutil.cpp:1637
ChannelBase::Renumber
virtual void Renumber(uint sourceid, const QString &oldChanNum, const QString &newChanNum)
Changes a channum if we have it cached anywhere.
Definition: channelbase.cpp:627
LinuxFirewireDevice
Definition: linuxfirewiredevice.h:19
ChannelBase::m_channels
ChannelInfoList m_channels
channels across all inputs
Definition: channelbase.h:143
ChannelUtil::SortChannels
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
Definition: channelutil.cpp:2325
ChannelBase::IsInputAvailable
virtual bool IsInputAvailable(uint &mplexid_restriction, uint &chanid_restriction) const
Switches to another input on hardware, and sets the channel is setstarting is true.
Definition: channelbase.cpp:229
SatIPChannel
Definition: satipchannel.h:12
ChannelBase::HandleScript
void HandleScript(const QString &freqid)
Definition: channelbase.cpp:281
TVRec::GetInputId
uint GetInputId(void) const
Returns the inputid.
Definition: tv_rec.h:234
sourceutil.h
cetonchannel.h
ChannelUtil::GetChanID
static int GetChanID(int db_mplexid, int service_transport_id, int major_channel, int minor_channel, int program_number)
Definition: channelutil.cpp:1312
mythlogging.h
DVBChannel::SetSlowTuning
void SetSlowTuning(std::chrono::milliseconds how_slow)
Definition: dvbchannel.h:47
ChannelBase
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:31
RemoteIsBusy
bool RemoteIsBusy(uint inputid, InputInfo &busy_input)
Definition: tvremoteutil.cpp:362
ChannelBase::StoreInputChannels
virtual void StoreInputChannels(void)
Saves current channel as the default channel for the current input.
Definition: channelbase.cpp:647
ChannelBase::m_curChannelName
QString m_curChannelName
Definition: channelbase.h:135
ChannelBase::ChannelBase
ChannelBase(TVRec *parent)
Definition: channelbase.cpp:51
FirewireChannel
FirewireChannel Copyright (c) 2005 by Jim Westfall and Dave Abrahams Distributed as part of MythTV un...
Definition: firewirechannel.h:14
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:551
compat.h
v4lchannel.h
DVBDBOptions::m_dvbOnDemand
bool m_dvbOnDemand
Definition: tv_rec.h:86
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
GENERIC_EXIT_START
@ GENERIC_EXIT_START
MythSystemLegacy process starting.
Definition: exitcodes.h:36
ChannelBase::IsExternalChannelChangeInUse
virtual bool IsExternalChannelChangeInUse(void)
Definition: channelbase.cpp:836
MythSystemLegacy::Wait
uint Wait(std::chrono::seconds timeout=0s)
Definition: mythsystemlegacy.cpp:243
IPTVChannel
Definition: iptvchannel.h:24
ChannelUtil::GetChannels
static ChannelInfoList GetChannels(uint sourceid, bool visible_only, const QString &group_by=QString(), uint channel_groupid=0)
Definition: channelutil.h:251
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:137
uint
unsigned int uint
Definition: compat.h:81
ExternalChannel
-*- Mode: c++ -*-
Definition: ExternalChannel.h:20
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
DTVChannel::EnterPowerSavingMode
virtual bool EnterPowerSavingMode(void)
Enters power saving mode if the card supports it.
Definition: dtvchannel.h:65
CardUtil::IsV4L
static bool IsV4L(const QString &rawtype)
Definition: cardutil.h:145
asichannel.h
CardUtil::GetFirewireChangerNode
static QString GetFirewireChangerNode(uint inputid)
Definition: cardutil.cpp:1620
kMSRunShell
@ kMSRunShell
run process through shell
Definition: mythsystem.h:43
channelutil.h
tvremoteutil.h
InputInfo::m_inputId
uint m_inputId
unique key in DB for this input
Definition: inputinfo.h:49
kMSRunBackground
@ kMSRunBackground
run child in the background
Definition: mythsystem.h:38
iptvchannel.h
LOC
#define LOC
Definition: channelbase.cpp:49
ChannelBase::GetScriptStatus
uint GetScriptStatus(bool holding_lock=false)
Definition: channelbase.cpp:429
ChannelUtil::GetChannelData
static bool GetChannelData(uint sourceid, uint &chanid, const QString &channum, QString &tvformat, QString &modulation, QString &freqtable, QString &freqid, int &finetune, uint64_t &frequency, QString &dtv_si_std, int &mpeg_prog_num, uint &atsc_major, uint &atsc_minor, uint &dvb_transportid, uint &dvb_networkid, uint &mplexid, bool &commfree)
Definition: channelutil.cpp:1904
InputInfo::m_sourceId
uint m_sourceId
associated channel listings source
Definition: inputinfo.h:48
DVBChannel
Provides interface to the tuning hardware when using DVB drivers.
Definition: dvbchannel.h:31
ChannelBase::ChangeInternalChannel
bool ChangeInternalChannel(const QString &freqid, uint cardinputid) const
Definition: channelbase.cpp:364
ChannelBase::SetChannelByString
virtual bool SetChannelByString(const QString &chan)=0
ASIChannel
-*- Mode: c++ -*-
Definition: asichannel.h:14
ChannelBase::m_systemStatus
uint m_systemStatus
These get mapped from the GENERIC_EXIT_* to these values for use with the signalmonitor code.
Definition: channelbase.h:150
ChannelBase::KillScript
bool KillScript(void)
Definition: channelbase.cpp:268
mythcorecontext.h
ChannelBase::m_sourceId
uint m_sourceId
Definition: channelbase.h:138
cardutil.h
ChannelBase::CheckChannel
bool CheckChannel(const QString &channum) const
Definition: channelbase.cpp:665
ExternalChannel.h
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:889
DVBDBOptions
Definition: tv_rec.h:81
GeneralDBOptions::m_videoDev
QString m_videoDev
Definition: tv_rec.h:70
TVRec
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:142
FireWireDBOptions
Definition: tv_rec.h:91
DVBDBOptions::m_dvbTuningDelay
std::chrono::milliseconds m_dvbTuningDelay
Definition: tv_rec.h:87
inputinfo.h
InputInfo
Definition: inputinfo.h:14
ChannelBase::GetDevice
virtual QString GetDevice(void) const
Returns String representing device, useful for debugging.
Definition: channelbase.h:78
dummychannel.h
ChannelBase::ChangeExternalChannel
bool ChangeExternalChannel(const QString &changer, const QString &freqid)
Definition: channelbase.cpp:410
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:838
ChannelBase::GetSourceID
virtual uint GetSourceID(void) const
Definition: channelbase.h:71
MythSystemLegacy::Run
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
Definition: mythsystemlegacy.cpp:213
DTVChannel
Class providing a generic interface to digital tuning hardware.
Definition: dtvchannel.h:33
ChannelBase::GetNextChannel
virtual uint GetNextChannel(uint chanid, ChannelChangeDirection direction) const
Definition: channelbase.cpp:201
DummyChannel
DummyChannel.
Definition: dummychannel.h:14
FirewireDevice::SetChannel
virtual bool SetChannel(const QString &panel_model, uint alt_method, uint channel)
Definition: firewiredevice.cpp:146
ChannelBase::m_system
MythSystemLegacy * m_system
Definition: channelbase.h:146
exitcodes.h
hdhrchannel.h
CardUtil::GetConflictingInputs
static std::vector< uint > GetConflictingInputs(uint inputid)
Definition: cardutil.cpp:2237
ChannelBase::GetMajorID
int GetMajorID(void)
Definition: channelbase.cpp:852
ChannelBase::InitializeInput
virtual bool InitializeInput(void)
Fills in input map from DB.
Definition: channelbase.cpp:548
V4LChannel
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
Definition: v4lchannel.h:30
GENERIC_EXIT_RUNNING
@ GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:26
ChannelBase::~ChannelBase
virtual ~ChannelBase(void)
Definition: channelbase.cpp:59
FirewireDevice::ClosePort
virtual bool ClosePort(void)=0
ChannelBase::m_pParent
TVRec * m_pParent
Definition: channelbase.h:134
InputInfo::m_mplexId
uint m_mplexId
mplexid restriction if applicable
Definition: inputinfo.h:50
find
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
Definition: dvbstreamhandler.cpp:363
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:898
FirewireDevice
Definition: firewiredevice.h:23
ChannelBase::m_externalChanger
QString m_externalChanger
Definition: channelbase.h:141
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:838
FirewireDevice::OpenPort
virtual bool OpenPort(void)=0
ChannelBase::GetChanID
virtual int GetChanID(void) const
Definition: channelbase.cpp:494