Go to the documentation of this file.
16 #include <QCoreApplication>
24 #ifdef USING_OSX_FIREWIRE
27 #ifdef USING_LINUX_FIREWIRE
49 #define LOC QString("ChannelBase[%1]: ").arg(m_inputId)
79 QString msg1 = QString(
"Setting start channel '%1' failed ").arg(startchannel);
80 QString msg2 =
"and no suitable channel found.";
81 bool msg_error =
true;
86 if (channel.m_chanNum == startchannel &&
89 LOG(VB_CHANNEL, LOG_INFO,
LOC +
90 QString(
"Found startchannel '%1'").arg(startchannel));
95 uint mplexid_restriction = 0;
96 uint chanid_restriction = 0;
107 if ((chanid != 0U) && (cit !=
m_channels.end()))
111 ok =
IsTunable((mplexid_restriction || chanid_restriction)
112 ? (*cit).m_chanNum : startchannel);
119 startchannel = (*cit).m_chanNum;
120 msg2 = QString(
"selected '%1' instead.").arg(startchannel);
126 LOG(VB_GENERAL, ((msg_error) ? LOG_ERR : LOG_WARNING),
LOC + msg1 + msg2);
133 QString loc =
LOC + QString(
"IsTunable(%1)").arg(channum);
137 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
138 QString(
"Requested non-existant input"));
143 uint mplexid_restriction = 0;
144 uint chanid_restriction = 0;
147 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
148 QString(
"Requested channel is on input '%1' "
149 "which is in a busy input group")
162 uint64_t frequency = 0;
163 int mpeg_prog_num = 0;
170 bool commfree =
false;
173 tvformat, modulation, freqtable, freqid,
174 finetune, frequency, dtv_si_std,
175 mpeg_prog_num, atsc_major, atsc_minor,
176 tsid, netid, mplexid, commfree))
178 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
179 QString(
"Failed to find channel in DB on input '%1' ")
185 if ((mplexid_restriction && (mplexid != mplexid_restriction)) ||
186 (!mplexid_restriction &&
187 chanid_restriction && (chanid != chanid_restriction)))
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));
211 uint mplexid_restriction = 0;
212 uint chanid_restriction = 0;
216 m_channels, chanid, mplexid_restriction, chanid_restriction,
230 uint &mplexid_restriction,
uint &chanid_restriction)
const
234 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"no m_inputId"));
240 mplexid_restriction = 0;
241 chanid_restriction = 0;
244 for (
uint inputid : inputids)
248 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
249 QString(
"Input %1 is busy on %2/%3")
254 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Input is busy"));
262 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Input is free on %1/%2")
263 .arg(mplexid_restriction).arg(chanid_restriction));
302 if (freqid.isEmpty())
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.");
329 LOG(VB_GENERAL, LOG_ERR,
LOC +
330 "Can not execute channel changer, previous call to script "
331 "is still running.");
342 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can not execute internal channel "
356 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can not execute channel changer.");
365 [[maybe_unused]]
uint inputid)
const
367 #ifdef USING_FIREWIRE
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));
377 #ifdef USING_LINUX_FIREWIRE
380 #endif // USING_LINUX_FIREWIRE
382 #ifdef USING_OSX_FIREWIRE
384 #endif // USING_OSX_FIREWIRE
392 if (!device->
SetChannel(fwmodel, 0, freqid.toUInt()))
411 const QString &freqid)
416 if (changer.isEmpty() || freqid.isEmpty())
419 QString command = QString(
"%1 %2").arg(changer, freqid);
420 LOG(VB_CHANNEL, LOG_INFO,
LOC +
421 QString(
"Running command: %1").arg(command));
447 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"GetScriptStatus() %1")
465 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"GetScriptStatus() %1 -> %2")
481 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Channel change script succeeded.");
490 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Channel change script failed.");
504 query.
prepare(
"SELECT chanid,visible FROM channel "
505 "WHERE deleted IS NULL AND "
506 " channum = :CHANNUM AND "
507 " sourceid = :SOURCEID");
519 if (query.
value(1).toInt() > 0)
522 visible = query.
value(0).toInt();
525 id = query.
value(0).toInt();
530 LOG(VB_GENERAL, LOG_INFO,
531 QString(
"No visible channel ids for %1 on sourceid %2")
537 LOG(VB_GENERAL, LOG_WARNING,
538 QString(
"Found multiple visible channel ids for %1 on sourceid %2")
542 return (visible >= 0 ? visible :
id);
560 LOG(VB_GENERAL, LOG_ERR,
561 "InitializeInput(): Programmer error, no parent.");
567 "SELECT sourceid, inputname, "
568 " startchan, externalcommand, "
571 "WHERE cardid = :INPUTID");
581 LOG(VB_GENERAL, LOG_ERR,
LOC +
582 QString(
"No capturecard record in database for input %1")
597 LOG(VB_GENERAL, LOG_ERR,
LOC +
598 QString(
"No video source defined for input %1")
610 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"External Channel changer is "
611 "set, but this device does not support it.");
616 LOG(VB_CHANNEL, LOG_INFO,
LOC +
617 QString(
"Input #%1: '%2' schan(%3) sourceid(%4)")
628 const QString &oldChanNum,
629 const QString &newChanNum)
631 bool skip = (
m_name.isEmpty() ||
655 "UPDATE capturecard "
656 "SET startchan = :STARTCHAN "
657 "WHERE cardid = :CARDINPUTID");
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");
687 else if (query.
size() > 0)
690 LOG(VB_CHANNEL, LOG_ERR,
LOC +
691 QString(
"Failed to find channel(%1) on input (%2).")
701 const QString &startchannel,
702 bool enter_power_save_mode,
713 auto *dvbchannel =
dynamic_cast<DVBChannel*
>(channel);
714 if (dvbchannel !=
nullptr)
720 #ifdef USING_FIREWIRE
724 #ifdef USING_HDHOMERUN
739 genOpt.
m_videoDev.startsWith(
"file:", Qt::CaseInsensitive)))
744 #if defined(USING_IPTV) || defined(USING_VBOX)
791 QString msg = QString(
792 "%1 card configured on video device %2, \n"
793 "but MythTV was not compiled with %3 support. \n"
795 "Recompile MythTV with %4 support or remove the card \n"
796 "from the configuration and restart MythTV.")
799 LOG(VB_GENERAL, LOG_ERR,
"ChannelBase: CreateChannel() Error: \n" +
804 if (!channel->
Open())
806 LOG(VB_GENERAL, LOG_ERR,
"ChannelBase: CreateChannel() Error: " +
807 QString(
"Failed to open device %1").arg(genOpt.
m_videoDev));
812 QString channum = startchannel;
813 channel->
Init(channum, setchan);
815 if (enter_power_save_mode)
827 auto *dtvchannel =
dynamic_cast<DTVChannel*
>(channel);
843 LOG(VB_GENERAL, LOG_ERR,
LOC +
844 QString(
"IsExternalChannelChangeInUse: "
845 "non-existant input"));
bool isActive(void) const
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
virtual void Close(void)=0
Closes the channel changing hardware to use.
virtual bool Init(QString &startchannel, bool setchan)
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
void Term(bool force=false)
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
virtual void HandleScriptEnd(bool ok)
virtual bool Open(void)=0
Opens the channel changing hardware for use.
static uint GetFirstInputID(const QString &videodevice)
Convenience function for GetInputIDs()
QVariant value(int i) const
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)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
virtual bool IsTunable(const QString &channum) const
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static uint64_t string_to_guid(const QString &guid)
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)
@ GENERIC_EXIT_OK
Exited with no error.
virtual bool IsExternalChannelChangeSupported(void)
static QString GetFirewireChangerModel(uint inputid)
virtual void Renumber(uint sourceid, const QString &oldChanNum, const QString &newChanNum)
Changes a channum if we have it cached anywhere.
ChannelInfoList m_channels
channels across all inputs
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
virtual bool IsInputAvailable(uint &mplexid_restriction, uint &chanid_restriction) const
Switches to another input on hardware, and sets the channel is setstarting is true.
void HandleScript(const QString &freqid)
uint GetInputId(void) const
Returns the inputid.
static int GetChanID(int db_mplexid, int service_transport_id, int major_channel, int minor_channel, int program_number)
void SetSlowTuning(std::chrono::milliseconds how_slow)
Abstract class providing a generic interface to tuning hardware.
bool RemoteIsBusy(uint inputid, InputInfo &busy_input)
virtual void StoreInputChannels(void)
Saves current channel as the default channel for the current input.
ChannelBase(TVRec *parent)
FirewireChannel Copyright (c) 2005 by Jim Westfall and Dave Abrahams Distributed as part of MythTV un...
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
static void DBError(const QString &where, const MSqlQuery &query)
@ GENERIC_EXIT_START
MythSystemLegacy process starting.
virtual bool IsExternalChannelChangeInUse(void)
uint Wait(std::chrono::seconds timeout=0s)
static ChannelInfoList GetChannels(uint sourceid, bool visible_only, const QString &group_by=QString(), uint channel_groupid=0)
bool isConnected(void) const
Only updated once during object creation.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
virtual bool EnterPowerSavingMode(void)
Enters power saving mode if the card supports it.
static bool IsV4L(const QString &rawtype)
static QString GetFirewireChangerNode(uint inputid)
@ kMSRunShell
run process through shell
@ kMSRunBackground
run child in the background
uint GetScriptStatus(bool holding_lock=false)
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)
Provides interface to the tuning hardware when using DVB drivers.
bool ChangeInternalChannel(const QString &freqid, uint cardinputid) const
virtual bool SetChannelByString(const QString &chan)=0
uint m_systemStatus
These get mapped from the GENERIC_EXIT_* to these values for use with the signalmonitor code.
bool CheckChannel(const QString &channum) const
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
This is the coordinating class of the Recorder Subsystem.
std::chrono::milliseconds m_dvbTuningDelay
virtual QString GetDevice(void) const
Returns String representing device, useful for debugging.
bool ChangeExternalChannel(const QString &changer, const QString &freqid)
QString GetHostName(void)
virtual uint GetSourceID(void) const
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
Class providing a generic interface to digital tuning hardware.
virtual uint GetNextChannel(uint chanid, ChannelChangeDirection direction) const
virtual bool SetChannel(const QString &panel_model, uint alt_method, uint channel)
MythSystemLegacy * m_system
static std::vector< uint > GetConflictingInputs(uint inputid)
virtual bool InitializeInput(void)
Fills in input map from DB.
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
@ GENERIC_EXIT_RUNNING
Process is running.
virtual ~ChannelBase(void)
virtual bool ClosePort(void)=0
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)
QString GetSetting(const QString &key, const QString &defaultval="")
QString m_externalChanger
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
virtual bool OpenPort(void)=0
virtual int GetChanID(void) const