16#include <QCoreApplication>
21#include "libmythbase/mythconfig.h"
25#if CONFIG_FIREWIRE_OSX
28#if CONFIG_FIREWIRE_LINUX
50#define LOC QString("ChannelBase[%1]: ").arg(m_inputId)
80 QString msg1 = QString(
"Setting start channel '%1' failed ").arg(startchannel);
81 QString msg2 =
"and no suitable channel found.";
82 bool msg_error =
true;
87 if (channel.m_chanNum == startchannel &&
90 LOG(VB_CHANNEL, LOG_INFO,
LOC +
91 QString(
"Found startchannel '%1'").arg(startchannel));
96 uint mplexid_restriction = 0;
97 uint chanid_restriction = 0;
108 if ((chanid != 0U) && (cit !=
m_channels.end()))
112 ok =
IsTunable((mplexid_restriction || chanid_restriction)
113 ? (*cit).m_chanNum : startchannel);
122 startchannel = (*cit).m_chanNum;
123 msg2 = QString(
"selected '%1' instead.").arg(startchannel);
129 LOG(VB_GENERAL, ((msg_error) ? LOG_ERR : LOG_WARNING),
LOC + msg1 + msg2);
136 QString loc =
LOC + QString(
"IsTunable(%1)").arg(channum);
140 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
141 QString(
"Requested non-existant input"));
146 uint mplexid_restriction = 0;
147 uint chanid_restriction = 0;
150 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
151 QString(
"Requested channel is on input '%1' "
152 "which is in a busy input group")
167 uint64_t frequency = 0;
168 int mpeg_prog_num = 0;
175 bool commfree =
false;
179 tvformat, modulation, freqtable, freqid,
180 finetune, frequency, dtv_si_std,
181 mpeg_prog_num, atsc_major, atsc_minor,
182 tsid, netid, mplexid, commfree))
184 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
185 QString(
"Failed to find channel in DB on input '%1' ")
191 if ((mplexid_restriction && (mplexid != mplexid_restriction)) ||
192 (!mplexid_restriction &&
193 chanid_restriction && (chanid != chanid_restriction)))
195 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
196 QString(
"Channel is valid, but tuner is busy "
197 "on different multiplex/channel (%1 != %2) / (%3 != %4)")
198 .arg(mplexid).arg(mplexid_restriction)
199 .arg(chanid).arg(chanid_restriction));
217 uint mplexid_restriction = 0;
218 uint chanid_restriction = 0;
222 m_channels, chanid, mplexid_restriction, chanid_restriction,
236 uint &mplexid_restriction,
uint &chanid_restriction)
const
240 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"no m_inputId"));
246 mplexid_restriction = 0;
247 chanid_restriction = 0;
250 for (
uint inputid : inputids)
254 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
255 QString(
"Input %1 is busy on %2/%3")
257 .arg(
info.m_chanId).arg(
info.m_mplexId));
260 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Input is busy"));
263 mplexid_restriction =
info.m_mplexId;
264 chanid_restriction =
info.m_chanId;
268 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Input is free on %1/%2")
269 .arg(mplexid_restriction).arg(chanid_restriction));
308 if (freqid.isEmpty())
310 LOG(VB_GENERAL, LOG_WARNING,
LOC +
311 "A channel changer is set, but the freqid field is empty."
312 "\n\t\t\tWe will return success to ease setup pains, "
313 "but no script is will actually run.");
335 LOG(VB_GENERAL, LOG_ERR,
LOC +
336 "Can not execute channel changer, previous call to script "
337 "is still running.");
348 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can not execute internal channel "
364 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can not execute channel changer.");
373 [[maybe_unused]]
uint inputid)
const
381 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Internal channel change to %1 "
382 "on inputid %2, GUID %3 (%4)").arg(freqid).arg(inputid)
383 .arg(fwnode, fwmodel));
385#if CONFIG_FIREWIRE_LINUX
389#if CONFIG_FIREWIRE_OSX
399 if (!device->
SetChannel(fwmodel, 0, freqid.toUInt()))
418 const QString &freqid)
423 if (changer.isEmpty() || freqid.isEmpty())
426 QString command = QString(
"%1 %2").arg(changer, freqid);
427 LOG(VB_CHANNEL, LOG_INFO,
LOC +
428 QString(
"Running command: %1").arg(command));
454 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"GetScriptStatus() %1")
472 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"GetScriptStatus() %1 -> %2")
488 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Channel change script succeeded.");
497 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Channel change script failed.");
511 query.
prepare(
"SELECT chanid,visible FROM channel "
512 "WHERE deleted IS NULL AND "
513 " channum = :CHANNUM AND "
514 " sourceid = :SOURCEID");
526 if (query.
value(1).toInt() > 0)
529 visible = query.
value(0).toInt();
533 id = query.
value(0).toInt();
539 LOG(VB_GENERAL, LOG_INFO,
540 QString(
"No visible channel ids for %1 on sourceid %2")
546 LOG(VB_GENERAL, LOG_WARNING,
547 QString(
"Found multiple visible channel ids for %1 on sourceid %2")
551 return (visible >= 0 ? visible :
id);
569 LOG(VB_GENERAL, LOG_ERR,
570 "InitializeInput(): Programmer error, no parent.");
576 "SELECT sourceid, inputname, "
577 " startchan, externalcommand, "
580 "WHERE cardid = :INPUTID");
590 LOG(VB_GENERAL, LOG_ERR,
LOC +
591 QString(
"No capturecard record in database for input %1")
606 LOG(VB_GENERAL, LOG_ERR,
LOC +
607 QString(
"No video source defined for input %1")
619 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"External Channel changer is "
620 "set, but this device does not support it.");
625 LOG(VB_CHANNEL, LOG_INFO,
LOC +
626 QString(
"Input #%1: '%2' schan(%3) sourceid(%4)")
637 const QString &oldChanNum,
638 const QString &newChanNum)
640 bool skip = (
m_name.isEmpty() ||
664 "UPDATE capturecard "
665 "SET startchan = :STARTCHAN "
666 "WHERE cardid = :CARDINPUTID");
681 "SELECT channel.chanid "
682 "FROM channel, capturecard "
683 "WHERE channel.deleted IS NULL AND "
684 " channel.channum = :CHANNUM AND "
685 " channel.sourceid = capturecard.sourceid AND "
686 " capturecard.cardid = :INPUTID AND "
687 " capturecard.hostname = :HOSTNAME");
696 else if (query.
size() > 0)
701 LOG(VB_CHANNEL, LOG_ERR,
LOC +
702 QString(
"Failed to find channel(%1) on input (%2).")
712 const QString &startchannel,
713 bool enter_power_save_mode,
724 auto *dvbchannel =
dynamic_cast<DVBChannel*
>(channel);
725 if (dvbchannel !=
nullptr)
750 genOpt.
m_videoDev.startsWith(
"file:", Qt::CaseInsensitive)))
755#if CONFIG_IPTV || CONFIG_VBOX
802 QString msg = QString(
803 "%1 card configured on video device %2, \n"
804 "but MythTV was not compiled with %3 support. \n"
806 "Recompile MythTV with %4 support or remove the card \n"
807 "from the configuration and restart MythTV.")
810 LOG(VB_GENERAL, LOG_ERR,
"ChannelBase: CreateChannel() Error: \n" +
815 if (!channel->
Open())
817 LOG(VB_GENERAL, LOG_ERR,
"ChannelBase: CreateChannel() Error: " +
818 QString(
"Failed to open device %1").arg(genOpt.
m_videoDev));
823 QString channum = startchannel;
824 channel->
Init(channum, setchan);
826 if (enter_power_save_mode)
838 auto *dtvchannel =
dynamic_cast<DTVChannel*
>(channel);
854 LOG(VB_GENERAL, LOG_ERR,
LOC +
855 QString(
"IsExternalChannelChangeInUse: "
856 "non-existant input"));
static uint64_t string_to_guid(const QString &guid)
static QString GetFirewireChangerModel(uint inputid)
static uint GetFirstInputID(const QString &videodevice)
Convenience function for GetInputIDs()
static bool IsV4L(const QString &rawtype)
static QString GetFirewireChangerNode(uint inputid)
static std::vector< uint > GetConflictingInputs(uint inputid)
Abstract class providing a generic interface to tuning hardware.
void HandleScript(const QString &freqid)
virtual uint GetSourceID(void) const
ChannelBase(TVRec *parent)
bool ChangeInternalChannel(const QString &freqid, uint cardinputid) const
bool ChangeExternalChannel(const QString &changer, const QString &freqid)
virtual bool Open(void)=0
Opens the channel changing hardware for use.
virtual uint GetNextChannel(uint chanid, ChannelChangeDirection direction) const
virtual bool IsInputAvailable(uint &mplexid_restriction, uint &chanid_restriction) const
Switches to another input on hardware, and sets the channel is setstarting is true.
virtual void HandleScriptEnd(bool ok)
virtual bool IsTunable(const QString &channum) const
virtual void StoreInputChannels(void)
Saves current channel as the default channel for the current input.
virtual void Close(void)=0
Closes the channel changing hardware to use.
virtual ~ChannelBase(void)
ChannelInfoList m_channels
channels across all inputs
virtual void Renumber(uint sourceid, const QString &oldChanNum, const QString &newChanNum)
Changes a channum if we have it cached anywhere.
virtual bool IsExternalChannelChangeInUse(void)
bool CheckChannel(const QString &channum) const
uint m_systemStatus
These get mapped from the GENERIC_EXIT_* to these values for use with the signalmonitor code.
virtual int GetChanID(void) const
virtual bool IsExternalChannelChangeSupported(void)
virtual bool Init(QString &startchannel, bool setchan)
QString m_externalChanger
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)
virtual bool SetChannelByString(const QString &chan)=0
virtual bool InitializeInput(void)
Fills in input map from DB.
uint GetScriptStatus(bool holding_lock=false)
MythSystemLegacy * m_system
virtual QString GetDevice(void) const
Returns String representing device, useful for debugging.
static int GetChanID(int db_mplexid, int service_transport_id, int major_channel, int minor_channel, int program_number)
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
static bool GetChannelData(uint sourceid, uint &chanid, const QString &channum, QString &name, QString &callsign, 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)
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)
static ChannelInfoList GetChannels(uint sourceid, bool visible_only, const QString &group_by=QString(), uint channel_groupid=0)
Class providing a generic interface to digital tuning hardware.
virtual bool EnterPowerSavingMode(void)
Enters power saving mode if the card supports it.
Provides interface to the tuning hardware when using DVB drivers.
void SetSlowTuning(std::chrono::milliseconds how_slow)
std::chrono::milliseconds m_dvbTuningDelay
FirewireChannel Copyright (c) 2005 by Jim Westfall and Dave Abrahams Distributed as part of MythTV un...
virtual bool OpenPort(void)=0
virtual bool SetChannel(const QString &panel_model, uint alt_method, uint channel)
virtual bool ClosePort(void)=0
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool isConnected(void) const
Only updated once during object creation.
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetHostName(void)
QString GetSetting(const QString &key, const QString &defaultval="")
static void DBError(const QString &where, const MSqlQuery &query)
uint Wait(std::chrono::seconds timeout=0s)
void Term(bool force=false)
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
This is the coordinating class of the Recorder Subsystem.
uint GetInputId(void) const
Returns the inputid.
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
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)
@ GENERIC_EXIT_START
MythSystemLegacy process starting.
@ GENERIC_EXIT_OK
Exited with no error.
@ GENERIC_EXIT_RUNNING
Process is running.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
@ kMSRunShell
run process through shell
@ kMSRunBackground
run child in the background
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
bool RemoteIsBusy(uint inputid, InputInfo &busy_input)