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")
165 uint64_t frequency = 0;
166 int mpeg_prog_num = 0;
173 bool commfree =
false;
176 tvformat, modulation, freqtable, freqid,
177 finetune, frequency, dtv_si_std,
178 mpeg_prog_num, atsc_major, atsc_minor,
179 tsid, netid, mplexid, commfree))
181 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
182 QString(
"Failed to find channel in DB on input '%1' ")
188 if ((mplexid_restriction && (mplexid != mplexid_restriction)) ||
189 (!mplexid_restriction &&
190 chanid_restriction && (chanid != chanid_restriction)))
192 LOG(VB_GENERAL, LOG_ERR, loc +
" " +
193 QString(
"Channel is valid, but tuner is busy "
194 "on different multiplex/channel (%1 != %2) / (%3 != %4)")
195 .arg(mplexid).arg(mplexid_restriction)
196 .arg(chanid).arg(chanid_restriction));
214 uint mplexid_restriction = 0;
215 uint chanid_restriction = 0;
219 m_channels, chanid, mplexid_restriction, chanid_restriction,
233 uint &mplexid_restriction,
uint &chanid_restriction)
const
237 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"no m_inputId"));
243 mplexid_restriction = 0;
244 chanid_restriction = 0;
247 for (
uint inputid : inputids)
251 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
252 QString(
"Input %1 is busy on %2/%3")
254 .arg(
info.m_chanId).arg(
info.m_mplexId));
257 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Input is busy"));
260 mplexid_restriction =
info.m_mplexId;
261 chanid_restriction =
info.m_chanId;
265 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Input is free on %1/%2")
266 .arg(mplexid_restriction).arg(chanid_restriction));
305 if (freqid.isEmpty())
307 LOG(VB_GENERAL, LOG_WARNING,
LOC +
308 "A channel changer is set, but the freqid field is empty."
309 "\n\t\t\tWe will return success to ease setup pains, "
310 "but no script is will actually run.");
332 LOG(VB_GENERAL, LOG_ERR,
LOC +
333 "Can not execute channel changer, previous call to script "
334 "is still running.");
345 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can not execute internal channel "
361 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can not execute channel changer.");
370 [[maybe_unused]]
uint inputid)
const
378 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Internal channel change to %1 "
379 "on inputid %2, GUID %3 (%4)").arg(freqid).arg(inputid)
380 .arg(fwnode, fwmodel));
382#if CONFIG_FIREWIRE_LINUX
386#if CONFIG_FIREWIRE_OSX
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)
747 genOpt.
m_videoDev.startsWith(
"file:", Qt::CaseInsensitive)))
752#if CONFIG_IPTV || CONFIG_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"));
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 &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)