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);
121 startchannel = (*cit).m_chanNum;
122 msg2 = QString(
"selected '%1' instead.").arg(startchannel);
128 LOG(VB_GENERAL, ((msg_error) ? LOG_ERR : LOG_WARNING),
LOC + msg1 + msg2);
135 QString loc =
LOC + QString(
"IsTunable(%1)").arg(channum);
139 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
140 QString(
"Requested non-existant input"));
145 uint mplexid_restriction = 0;
146 uint chanid_restriction = 0;
149 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
150 QString(
"Requested channel is on input '%1' "
151 "which is in a busy input group")
164 uint64_t frequency = 0;
165 int mpeg_prog_num = 0;
172 bool commfree =
false;
175 tvformat, modulation, freqtable, freqid,
176 finetune, frequency, dtv_si_std,
177 mpeg_prog_num, atsc_major, atsc_minor,
178 tsid, netid, mplexid, commfree))
180 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
181 QString(
"Failed to find channel in DB on input '%1' ")
187 if ((mplexid_restriction && (mplexid != mplexid_restriction)) ||
188 (!mplexid_restriction &&
189 chanid_restriction && (chanid != chanid_restriction)))
191 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
192 QString(
"Channel is valid, but tuner is busy "
193 "on different multiplex/channel (%1 != %2) / (%3 != %4)")
194 .arg(mplexid).arg(mplexid_restriction)
195 .arg(chanid).arg(chanid_restriction));
213 uint mplexid_restriction = 0;
214 uint chanid_restriction = 0;
218 m_channels, chanid, mplexid_restriction, chanid_restriction,
232 uint &mplexid_restriction,
uint &chanid_restriction)
const
236 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"no m_inputId"));
242 mplexid_restriction = 0;
243 chanid_restriction = 0;
246 for (
uint inputid : inputids)
250 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
251 QString(
"Input %1 is busy on %2/%3")
253 .arg(
info.m_chanId).arg(
info.m_mplexId));
256 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Input is busy"));
259 mplexid_restriction =
info.m_mplexId;
260 chanid_restriction =
info.m_chanId;
264 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Input is free on %1/%2")
265 .arg(mplexid_restriction).arg(chanid_restriction));
304 if (freqid.isEmpty())
306 LOG(VB_GENERAL, LOG_WARNING,
LOC +
307 "A channel changer is set, but the freqid field is empty."
308 "\n\t\t\tWe will return success to ease setup pains, "
309 "but no script is will actually run.");
331 LOG(VB_GENERAL, LOG_ERR,
LOC +
332 "Can not execute channel changer, previous call to script "
333 "is still running.");
344 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can not execute internal channel "
360 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can not execute channel changer.");
369 [[maybe_unused]]
uint inputid)
const
371 #ifdef USING_FIREWIRE
377 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Internal channel change to %1 "
378 "on inputid %2, GUID %3 (%4)").arg(freqid).arg(inputid)
379 .arg(fwnode, fwmodel));
381 #ifdef USING_LINUX_FIREWIRE
384 #endif // USING_LINUX_FIREWIRE
386 #ifdef USING_OSX_FIREWIRE
388 #endif // USING_OSX_FIREWIRE
396 if (!device->
SetChannel(fwmodel, 0, freqid.toUInt()))
415 const QString &freqid)
420 if (changer.isEmpty() || freqid.isEmpty())
423 QString command = QString(
"%1 %2").arg(changer, freqid);
424 LOG(VB_CHANNEL, LOG_INFO,
LOC +
425 QString(
"Running command: %1").arg(command));
451 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"GetScriptStatus() %1")
469 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"GetScriptStatus() %1 -> %2")
485 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Channel change script succeeded.");
494 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Channel change script failed.");
508 query.
prepare(
"SELECT chanid,visible FROM channel "
509 "WHERE deleted IS NULL AND "
510 " channum = :CHANNUM AND "
511 " sourceid = :SOURCEID");
523 if (query.
value(1).toInt() > 0)
526 visible = query.
value(0).toInt();
530 id = query.
value(0).toInt();
536 LOG(VB_GENERAL, LOG_INFO,
537 QString(
"No visible channel ids for %1 on sourceid %2")
543 LOG(VB_GENERAL, LOG_WARNING,
544 QString(
"Found multiple visible channel ids for %1 on sourceid %2")
548 return (visible >= 0 ? visible :
id);
566 LOG(VB_GENERAL, LOG_ERR,
567 "InitializeInput(): Programmer error, no parent.");
573 "SELECT sourceid, inputname, "
574 " startchan, externalcommand, "
577 "WHERE cardid = :INPUTID");
587 LOG(VB_GENERAL, LOG_ERR,
LOC +
588 QString(
"No capturecard record in database for input %1")
603 LOG(VB_GENERAL, LOG_ERR,
LOC +
604 QString(
"No video source defined for input %1")
616 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"External Channel changer is "
617 "set, but this device does not support it.");
622 LOG(VB_CHANNEL, LOG_INFO,
LOC +
623 QString(
"Input #%1: '%2' schan(%3) sourceid(%4)")
634 const QString &oldChanNum,
635 const QString &newChanNum)
637 bool skip = (
m_name.isEmpty() ||
661 "UPDATE capturecard "
662 "SET startchan = :STARTCHAN "
663 "WHERE cardid = :CARDINPUTID");
678 "SELECT channel.chanid "
679 "FROM channel, capturecard "
680 "WHERE channel.deleted IS NULL AND "
681 " channel.channum = :CHANNUM AND "
682 " channel.sourceid = capturecard.sourceid AND "
683 " capturecard.cardid = :INPUTID AND "
684 " capturecard.hostname = :HOSTNAME");
693 else if (query.
size() > 0)
698 LOG(VB_CHANNEL, LOG_ERR,
LOC +
699 QString(
"Failed to find channel(%1) on input (%2).")
709 const QString &startchannel,
710 bool enter_power_save_mode,
721 auto *dvbchannel =
dynamic_cast<DVBChannel*
>(channel);
722 if (dvbchannel !=
nullptr)
728 #ifdef USING_FIREWIRE
732 #ifdef USING_HDHOMERUN
747 genOpt.
m_videoDev.startsWith(
"file:", Qt::CaseInsensitive)))
752 #if defined(USING_IPTV) || defined(USING_VBOX)
799 QString msg = QString(
800 "%1 card configured on video device %2, \n"
801 "but MythTV was not compiled with %3 support. \n"
803 "Recompile MythTV with %4 support or remove the card \n"
804 "from the configuration and restart MythTV.")
807 LOG(VB_GENERAL, LOG_ERR,
"ChannelBase: CreateChannel() Error: \n" +
812 if (!channel->
Open())
814 LOG(VB_GENERAL, LOG_ERR,
"ChannelBase: CreateChannel() Error: " +
815 QString(
"Failed to open device %1").arg(genOpt.
m_videoDev));
820 QString channum = startchannel;
821 channel->
Init(channum, setchan);
823 if (enter_power_save_mode)
835 auto *dtvchannel =
dynamic_cast<DTVChannel*
>(channel);
851 LOG(VB_GENERAL, LOG_ERR,
LOC +
852 QString(
"IsExternalChannelChangeInUse: "
853 "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)
virtual void HandleScriptEnd(bool ok)
virtual bool Open(void)=0
Opens the channel changing hardware for use.
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
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)
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.
@ GENERIC_EXIT_START
MythSystemLegacy process starting.
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.
@ GENERIC_EXIT_OK
Exited with no error.
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)
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
@ GENERIC_EXIT_RUNNING
Process is running.
@ 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.
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