Go to the documentation of this file.
32 #include "mythconfig.h"
42 #include "../vboxutils.h"
44 #define DEBUG_CHANNEL_PREFIX 0
46 #define LOC QString("TVRec[%1]: ").arg(m_inputId)
47 #define LOC2 QString("TVRec[%1]: ").arg(inputid) // for static functions
57 bool on_host,
bool transcode_bfr_comm,
bool on_line_comm);
87 : m_eventThread(new
MThread(
"TVRecEvent", this)),
95 bool enter_power_save_mode)
97 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"CreateChannel(%1)")
110 startchannel, enter_power_save_mode,
m_rbFileExt, setchan);
117 LOG(VB_GENERAL, LOG_ERR,
LOC +
118 QString(
"CreateChannel(%1) failed due to VBOX not responding "
119 "to network check on inputid [%2]")
197 LOG(VB_RECORD, LOG_INFO,
LOC +
"TeardownAll");
279 LOG(VB_RECORD, LOG_INFO,
LOC +
"Pending recording revoked on " +
286 (*it).m_doNotAsk = (*it).m_canceled =
true;
291 LOG(VB_RECORD, LOG_INFO,
LOC +
292 QString(
"RecordPending on inputid [%1]").
arg(rcinfo->
GetInputID()));
298 pending.
m_ask =
true;
315 for (
uint inputid : inputids)
350 LOG(VB_RECORD, LOG_INFO,
LOC +
351 QString(
"CancelNextRecording(%1) -- begin").
arg(cancel));
356 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"CancelNextRecording(%1) -- "
357 "error, unknown recording").
arg(cancel));
363 vector<uint> &inputids = (*it).m_possibleConflicts;
364 for (
uint inputid : inputids)
366 LOG(VB_RECORD, LOG_INFO,
LOC +
367 QString(
"CancelNextRecording -- inputid 0x%1")
368 .
arg((uint64_t)inputid,0,16));
375 LOG(VB_RECORD, LOG_INFO,
LOC +
376 QString(
"CancelNextRecording -- inputid [%1]")
383 (*it).m_canceled =
false;
386 LOG(VB_RECORD, LOG_INFO,
LOC +
387 QString(
"CancelNextRecording(%1) -- end").
arg(cancel));
404 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"StartRecording(%1)")
430 .addSecs(post_roll_seconds);
432 QString msg = QString(
"updating recording: %1 %2 %3 %4")
436 LOG(VB_RECORD, LOG_INFO,
LOC + msg);
444 bool cancelNext =
false;
446 PendingMap::iterator it;
451 (*it).m_ask = (*it).m_doNotAsk =
false;
452 cancelNext = (*it).m_canceled;
473 LOG(VB_RECORD, LOG_INFO,
LOC +
474 "Checking input group recorders - begin");
480 vector<uint> inputids2;
484 for (
uint inputid : inputids)
489 if (is_busy && !sourceid)
499 ((mplexid == 0 || mplexid == 32767) &&
503 inputids2.push_back(inputid);
508 for (
uint i = 0; (i < inputids2.size()) && ok; i++)
510 LOG(VB_RECORD, LOG_INFO,
LOC +
511 QString(
"Attempting to stop input [%1] in state %2")
518 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"a [%1]: %2")
526 QString message = QString(
"QUIT_LIVETV %1").arg(inputids2[i]);
531 LOG(VB_RECORD, LOG_INFO,
LOC +
532 QString(
"Stopping recording on [%1], %2") .
arg(inputids2[i])
533 .
arg(success ?
"succeeded" :
"failed"));
547 LOG(VB_RECORD, LOG_INFO,
LOC +
"Checking input group recorders - done");
550 bool did_switch =
false;
554 did_switch = (
nullptr != ri2);
575 QString message = QString(
"LIVETV_EXITED");
597 LOG(VB_RECORD, LOG_WARNING,
LOC +
"Still failing.");
609 QString message = QString(
"LIVETV_WATCH %1 1").arg(
m_inputId);
615 else if (!did_switch)
617 QString msg = QString(
"Wanted to record: %1 %2 %3 %4\n\t\t\t")
624 msg +=
"But a user has canceled this recording";
629 msg += QString(
"But the current state is: %1")
636 msg += QString(
"\n\t\t\tCurrently recording: %1 %2 %3 %4")
642 LOG(VB_GENERAL, LOG_INFO,
LOC + msg);
691 LOG(VB_RECORD, LOG_INFO,
LOC +
692 QString(
"SetRecordingStatus(%1->%2) on line %3")
714 if (now < m_curRecording->GetDesiredEndTime())
756 LOG(VB_GENERAL, LOG_ERR,
LOC +
757 QString(
"Unknown state in RemoveRecording: %1")
776 QString msg =
"Unknown state in RemovePlaying: %1";
793 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"StartedRecording(%1) fn(%2)")
825 LOG((recq->
IsDamaged()) ? VB_GENERAL : VB_RECORD, LOG_INFO,
826 LOC + QString(
"FinishedRecording(%1) %2 recq:\n%3")
828 .arg((recq->
IsDamaged()) ?
"damaged" :
"good")
845 bool was_finished =
false;
846 static QMutex s_finRecLock;
847 static QHash<QString,QDateTime> s_finRecMap;
849 QMutexLocker locker(&s_finRecLock);
851 QDateTime expired = now.addSecs(-60*5);
852 QHash<QString,QDateTime>::iterator it = s_finRecMap.begin();
853 while (it != s_finRecMap.end())
856 it = s_finRecMap.erase(it);
861 it = s_finRecMap.find(key);
862 if (it != s_finRecMap.end())
865 s_finRecMap[key] = now;
869 LOG(VB_RECORD, LOG_INFO,
LOC +
870 QString(
"FinishedRecording(%1) %2 quality"
871 "\n\t\t\ttitle: %3\n\t\t\t"
872 "in recgroup: %4 status: %5:%6 %7 %8")
874 .arg(is_good ?
"Good" :
"Bad")
880 .
arg(was_finished?
"already_finished":
"finished_now"));
905 ((avg_height > 2000) ?
VID_4K :
907 ((avg_height > 700) ?
VID_720 : 0))) |
927 if (curRec->
IsLocal() && (fsize >= 1000) &&
937 if (recgrp !=
"LiveTV")
939 LOG(VB_RECORD, LOG_INFO,
LOC +
940 QString(
"FinishedRecording -- UPDATE_RECORDING_STATUS: %1")
943 MythEvent me(QString(
"UPDATE_RECORDING_STATUS %1 %2 %3 %4 %5")
958 QString message = QString(
"DONE_RECORDING %1 %2 %3")
964 QHash<QString,int>::iterator autoJob =
968 LOG(VB_GENERAL, LOG_INFO,
969 "autoRunJobs not initialized until FinishedRecording()");
975 LOG(VB_JOBQUEUE, LOG_INFO, QString(
"AutoRunJobs 0x%1").
arg(*autoJob,0,16));
976 if ((recgrp ==
"LiveTV") || (fsize < 1000) ||
989 #define TRANSITION(ASTATE,BSTATE) \
990 ((m_internalState == (ASTATE)) && (m_desiredNextState == (BSTATE)))
991 #define SET_NEXT() do { nextState = m_desiredNextState; changed = true; } while(false)
992 #define SET_LAST() do { nextState = m_internalState; changed = true; } while(false)
1005 bool changed =
false;
1007 QString transMsg = QString(
" %1 to %2")
1013 LOG(VB_GENERAL, LOG_ERR,
LOC +
1014 "HandleStateChange(): Null transition" + transMsg);
1060 QString msg = (changed) ?
"Changing from" :
"Unknown state transition:";
1061 LOG(VB_GENERAL, LOG_INFO,
LOC + msg + transMsg);
1109 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"TeardownRecorder(%1)")
1123 __FILE__, __LINE__);
1140 LOG(VB_FILE, LOG_INFO,
LOC +
"calling StopReads()");
1191 #endif // USING_V4L2
1198 "SELECT SUM(useeit) "
1199 "FROM videosource, capturecard "
1200 "WHERE videosource.sourceid = capturecard.sourceid AND"
1201 " capturecard.cardid = :INPUTID");
1218 "SELECT SUM(dishnet_eit) "
1219 "FROM videosource, capturecard "
1220 "WHERE videosource.sourceid = capturecard.sourceid AND"
1221 " capturecard.cardid = :INPUTID");
1240 "SELECT COUNT(cardid) "
1241 "FROM capturecard ";
1264 timeout += eitTransportTimeout * inputId / no_inputs;
1299 __FILE__, __LINE__);
1305 LOG(VB_GENERAL, LOG_ERR,
LOC +
1306 "RunTV encountered fatal error, exiting event thread.");
1355 QString message = QString(
"QUIT_LIVETV %1").arg(
m_inputId);
1371 bool enable_ui =
true;
1387 LOG(VB_RECORD, LOG_INFO,
LOC +
1388 "Switching Buffer (" +
1389 QString(
"!has_rec(%1) && ").
arg(has_rec) +
1390 QString(
"!rec_soon(%1) && (").
arg(rec_soon) +
1403 LOG(VB_RECORD, LOG_INFO,
"Waiting for ringbuffer switch");
1411 LOG(VB_RECORD, LOG_INFO,
LOC +
"Enabling Full LiveTV UI.");
1412 QString message = QString(
"LIVETV_WATCH %1 0").arg(
m_inputId);
1435 LOG(VB_EIT, LOG_INFO,
LOC +
1436 "EIT scanning disabled for this input.");
1441 LOG(VB_EIT, LOG_INFO,
LOC +
1442 "EIT scanning disabled for all channels on this input.");
1451 bool allow_eit =
true;
1452 vector<uint> inputids =
1455 for (
uint i = 0; i < inputids.size() && allow_eit; ++i)
1462 QDateTime::currentDateTime().addYears(1);
1466 LOG(VB_EIT, LOG_INFO,
LOC + QString(
1467 "Postponing EIT scan on input [%1] "
1468 "because input %2 is busy")
1529 while (!ok && ((
unsigned long)
t.elapsed()) < time)
1555 std::this_thread::sleep_for(std::chrono::microseconds(10-te));
1566 auto next = it; ++next;
1569 LOG(VB_RECORD, LOG_INFO,
LOC +
"Deleting stale pending recording " +
1570 QString(
"[%1] '%2'")
1571 .
arg((*it).m_info->GetInputID())
1572 .arg((*it).m_info->GetTitle()));
1574 delete (*it).m_info;
1586 LOG(VB_CHANNEL, LOG_INFO,
1587 LOC +
"Stopping active EIT scan for pending recording.");
1595 bool has_rec =
false;
1599 ((*it).m_info->GetInputID() ==
m_inputId) &&
1605 (*it).m_recordingStart);
1610 if (!(*it).m_ask && !(*it).m_doNotAsk)
1613 int timeuntil = ((*it).m_doNotAsk) ?
1617 (*it).m_canceled =
true;
1619 QString
query = QString(
"ASK_RECORDING %1 %2 %3 %4")
1622 .arg(has_rec ? 1 : 0)
1623 .arg((*it).m_hasLaterShowing ? 1 : 0);
1628 (*it).m_info->ToStringList(msg);
1632 (*it).m_ask = (*it).m_doNotAsk =
false;
1647 "SELECT videodevice, vbidevice, audiodevice, "
1648 " audioratelimit, cardtype, "
1649 " skipbtaudio, signal_timeout, channel_timeout, "
1650 " dvb_wait_for_seqstart, "
1652 " dvb_on_demand, dvb_tuning_delay, dvb_eitscan,"
1654 " firewire_speed, firewire_model, firewire_connection, "
1658 "WHERE cardid = :INPUTID");
1672 if (!test.isEmpty())
1676 if (!test.isEmpty())
1680 if (!test.isEmpty())
1686 if (!test.isEmpty())
1697 if (table_timeout < 1000)
1709 uint fireoff = dvboff + 3;
1713 if (!test.isEmpty())
1727 LOG(VB_RECORD, LOG_INFO,
LOC2 + QString(
"GetStartChannel for input %1")
1735 "WHERE capturecard.cardid = :INPUTID");
1745 if (!startchan.isEmpty())
1747 LOG(VB_CHANNEL, LOG_INFO,
LOC2 + QString(
"Start channel: %1")
1757 "FROM capturecard, channel "
1758 "WHERE deleted IS NULL AND "
1759 " channel.sourceid = capturecard.sourceid AND "
1760 " capturecard.cardid = :INPUTID");
1770 if (!startchan.isEmpty())
1772 LOG(VB_GENERAL, LOG_ERR,
LOC2 + QString(
"Start channel from DB is "
1773 "empty, setting to '%1' instead.").
arg(startchan));
1781 "SELECT channum, inputname "
1782 "FROM capturecard, channel "
1783 "WHERE deleted IS NULL AND "
1784 " channel.sourceid = capturecard.sourceid AND "
1785 " capturecard.cardid = :INPUTID");
1795 if (!startchan.isEmpty())
1797 LOG(VB_GENERAL, LOG_ERR,
LOC2 + QString(
"Start channel invalid, "
1798 "setting to '%1' on input %2 instead.").
arg(startchan)
1806 LOG(VB_GENERAL, LOG_ERR,
LOC2 + QString(
"Problem finding starting channel, "
1807 "setting to default of '%1'.").
arg(startchan));
1823 pid_cache.push_back(item);
1831 channel->GetCachedPids(pid_cache);
1832 bool vctpid_cached =
false;
1833 for (
auto pid : pid_cache)
1838 vctpid_cached =
true;
1842 return vctpid_cached;
1862 LOG(VB_RECORD, LOG_INFO,
LOC +
"Setting up table monitoring.");
1866 if (!sm || !dtvchan)
1868 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Setting up table monitoring.");
1879 QString recording_type =
"all";
1885 recording_type = setting->
getValue();
1892 if ((
minor > 0) && (tuningmode ==
"atsc"))
1894 QString msg = QString(
"ATSC channel: %1_%2").arg(major).arg(
minor);
1895 LOG(VB_RECORD, LOG_INFO,
LOC + msg);
1916 LOG(VB_RECORD, LOG_INFO,
LOC +
1917 "Successfully set up ATSC table monitoring.");
1937 LOG(VB_RECORD, LOG_INFO,
LOC +
1938 QString(
"DVB service_id %1 on net_id %2 tsid %3")
1959 LOG(VB_RECORD, LOG_INFO,
LOC +
1960 "Successfully set up DVB table monitoring.");
1975 QString msg = QString(
"MPEG program number: %1").arg(progNum);
1976 LOG(VB_RECORD, LOG_INFO,
LOC + msg);
1996 LOG(VB_RECORD, LOG_INFO,
LOC +
1997 "Successfully set up MPEG table monitoring.");
2008 for (
auto item = pid_cache.cbegin(); !ok && item != pid_cache.cend(); ++item)
2009 ok |= item->IsPermanent();
2014 QString msg =
"No valid DTV info, ATSC maj(%1) min(%2), MPEG pn(%3)";
2015 LOG(VB_GENERAL, LOG_ERR,
LOC + msg.arg(major).arg(
minor).arg(progNum));
2019 LOG(VB_RECORD, LOG_INFO,
LOC +
2020 "Successfully set up raw pid monitoring.");
2042 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetupSignalMonitor(%1, %2)")
2043 .
arg(tablemon).
arg(notify));
2066 LOG(VB_RECORD, LOG_INFO,
LOC +
"Signal monitor successfully created");
2071 LOG(VB_GENERAL, LOG_ERR,
LOC +
2072 "Failed to setup digital signal monitoring");
2099 LOG(VB_RECORD, LOG_INFO,
LOC +
"TeardownSignalMonitor() -- begin");
2104 if (dtvMon && dtvChan)
2108 if (!pid_cache.empty())
2118 LOG(VB_RECORD, LOG_INFO,
LOC +
"TeardownSignalMonitor() -- end");
2134 QString msg =
"SetSignalMonitoringRate(%1, %2)";
2135 LOG(VB_RECORD, LOG_INFO,
LOC +
2136 msg.arg(rate).arg(notifyFrontend) +
"-- start");
2142 LOG(VB_GENERAL, LOG_ERR,
LOC +
2143 "Signal Monitoring is notsupported by your hardware.");
2149 LOG(VB_GENERAL, LOG_ERR,
LOC +
2150 "Signal can only be monitored in LiveTV Mode.");
2165 LOG(VB_RECORD, LOG_INFO,
LOC +
2166 msg.arg(rate).arg(notifyFrontend) +
" -- end");
2194 query.
prepare(
"SELECT channel.channum, channel.callsign "
2196 "WHERE channel.chanid = :CHANID");
2204 QString channelname =
query.
value(0).toString();
2205 QString callsign =
query.
value(1).toString();
2208 "SELECT channel.channum "
2209 "FROM channel, capturecard "
2210 "WHERE deleted IS NULL AND "
2211 " ( channel.chanid = :CHANID OR "
2212 " ( channel.channum = :CHANNUM AND "
2213 " channel.callsign = :CALLSIGN ) "
2215 " channel.sourceid = capturecard.sourceid AND "
2216 " capturecard.cardid = :INPUTID");
2228 msg =
"Found channel (%1) on current input[%2].";
2235 "SELECT channel.channum, capturecard.cardid "
2236 "FROM channel, capturecard "
2237 "WHERE deleted IS NULL AND "
2238 " ( channel.chanid = :CHANID OR "
2239 " ( channel.channum = :CHANNUM AND "
2240 " channel.callsign = :CALLSIGN ) "
2242 " channel.sourceid = capturecard.sourceid AND "
2243 " capturecard.cardid != :INPUTID");
2255 msg = QString(
"Found channel (%1) on different input(%2).")
2257 LOG(VB_RECORD, LOG_INFO,
LOC + msg);
2261 msg = QString(
"Did not find channel(%1) on any input.").arg(channelname);
2262 LOG(VB_RECORD, LOG_ERR,
LOC + msg);
2290 if ((chan.length() >= 2) && !spacer.isEmpty())
2291 return chan.left(chan.length()-1) + spacer + chan.right(1);
2323 uint &complete_valid_channel_on_rec,
2324 bool &is_extra_char_useful,
2325 QString &needed_spacer)
const
2327 #if DEBUG_CHANNEL_PREFIX
2328 LOG(VB_GENERAL, LOG_DEBUG, QString(
"CheckChannelPrefix(%1)").
arg(
prefix));
2331 static const std::array<const QString,5> s_spacers = {
"",
"_",
"-",
"#",
"." };
2334 QString basequery = QString(
2335 "SELECT channel.chanid, channel.channum, capturecard.cardid "
2336 "FROM channel, capturecard "
2337 "WHERE deleted IS NULL AND "
2338 " channel.channum LIKE '%1%' AND "
2339 " channel.sourceid = capturecard.sourceid");
2341 const std::array<const QString,2> inputquery
2343 QString(
" AND capturecard.cardid = '%1'").arg(
m_inputId),
2344 QString(
" AND capturecard.cardid != '%1'").arg(
m_inputId),
2347 vector<uint> fchanid;
2348 vector<QString> fchannum;
2349 vector<uint> finputid;
2350 vector<QString> fspacer;
2352 for (
const auto & str : inputquery)
2354 for (
const auto & spacer : s_spacers)
2357 prefix, (spacer ==
"_") ?
"\\_" : spacer);
2369 fchannum.push_back(
query.
value(1).toString());
2371 fspacer.emplace_back(spacer);
2372 #if DEBUG_CHANNEL_PREFIX
2373 LOG(VB_GENERAL, LOG_DEBUG,
2374 QString(
"(%1,%2) Adding %3 rec %4")
2387 is_extra_char_useful =
false;
2388 complete_valid_channel_on_rec = 0;
2389 needed_spacer.clear();
2391 if (fchanid.empty())
2394 if (fchanid.size() == 1)
2396 needed_spacer = fspacer[0];
2399 complete_valid_channel_on_rec = (nc) ? 0 : finputid[0];
2400 is_extra_char_useful = nc;
2408 is_extra_char_useful =
false;
2409 for (
uint i = 0; (i < fchannum.size()) && !is_extra_char_useful; i++)
2412 #if DEBUG_CHANNEL_PREFIX
2413 LOG(VB_GENERAL, LOG_DEBUG, QString(
"is_extra_char_useful(%1!=%2): %3")
2415 .
arg(is_extra_char_useful));
2422 for (
size_t i = 0; i < fchannum.size(); i++)
2424 if (fchannum[i] ==
prefix)
2426 complete_valid_channel_on_rec = finputid[i];
2432 if (complete_valid_channel_on_rec != 0)
2436 bool spacer_needed =
true;
2437 for (
uint i = 0; (i < fspacer.size() && spacer_needed); i++)
2438 spacer_needed = !fspacer[i].isEmpty();
2440 needed_spacer = fspacer[0];
2444 for (
size_t i = 0; i < ((is_extra_char_useful) ? 0 : fchanid.size()); i++)
2448 needed_spacer = fspacer[i];
2449 complete_valid_channel_on_rec = finputid[i];
2458 const QString &channum)
2464 if (!videoFilters.isEmpty())
2492 busy_input = &dummy;
2494 busy_input->
Clear();
2511 bool has_pending =
false;
2521 if (!busy_input->
m_inputId && has_pending)
2526 if (timeLeft <= time_buffer)
2649 long long bitrate = 0;
2652 bitrate = 10080000LL;
2656 bitrate = 20200000LL;
2660 bitrate = 22200000LL;
2664 bitrate = 10080000LL;
2792 MythEvent me(
"SCHEDULER_ADD_RECORDING", prog);
2819 LOG(VB_JOBQUEUE, LOG_INFO,
2820 QString(
"InitAutoRunJobs for %1, line %2 -> 0x%3")
2838 LOG(VB_GENERAL, LOG_INFO,
LOC +
2839 QString(
"SetLiveRecording(%1)").
arg(recording));
2849 LOG(VB_GENERAL, LOG_INFO,
LOC +
"SetLiveRecording() -- cancel");
2857 LOG(VB_GENERAL, LOG_INFO,
LOC +
"SetLiveRecording() -- record");
2870 MythEvent me(QString(
"UPDATE_RECORDING_STATUS %1 %2 %3 %4 %5")
2887 LOG(VB_RECORD, LOG_INFO,
LOC +
2888 QString(
"StopLiveTV(void) curRec: 0x%1 pseudoRec: 0x%2")
2937 LOG(VB_GENERAL, LOG_ERR,
LOC +
2938 "PauseRecorder() called with no recorder");
2973 LOG(VB_GENERAL, LOG_ERR,
LOC +
2974 QString(
"Channel: \'%1\' was not found in the database.\n"
2975 "\t\tMost likely, the 'starting channel' for this "
2976 "Input Connection is invalid.\n"
2977 "\t\tCould not toggle favorite.").
arg(channum));
2984 LOG(VB_RECORD, LOG_ERR,
LOC +
2985 QString(
"ToggleChannelFavorite: Invalid channel group name %1,")
2986 .
arg(changroupname));
2993 LOG(VB_RECORD, LOG_ERR,
LOC +
"Unable to toggle channel favorite.");
2996 LOG(VB_RECORD, LOG_INFO,
LOC +
2997 QString(
"Toggled channel favorite.channum %1, chan group %2")
2998 .
arg(channum).
arg(changroupname));
3016 return (ret < 0) ? -1 : ret / 655;
3036 return (ret < 0) ? -1 : ret / 655;
3070 QString origIn = input;
3071 LOG(VB_RECORD, LOG_INFO,
LOC +
"SetInput(" + input +
") -- begin");
3075 LOG(VB_RECORD, LOG_INFO,
LOC +
"SetInput() -- end no channel class");
3079 LOG(VB_RECORD, LOG_INFO,
LOC +
"SetInput(" + origIn +
":" + input +
3080 ") -- end nothing to do");
3098 LOG(VB_CHANNEL, LOG_INFO,
LOC +
3099 QString(
"SetChannel(%1) -- begin").
arg(name));
3132 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"SetChannel(%1) -- end").
arg(name));
3144 LOG(VB_CHANNEL, LOG_INFO,
LOC +
3145 QString(
"QueueEITChannelChange(%1) -- begin").
arg(name));
3162 LOG(VB_CHANNEL, LOG_INFO,
LOC +
3163 QString(
"QueueEITChannelChange(%1) -- end --> %2").
arg(name).
arg(ok));
3169 QString &
title, QString &subtitle,
3171 QString &starttime, QString &endtime,
3172 QString &callsign, QString &iconpath,
3173 QString &channum,
uint &sourceChanid,
3174 QString &seriesid, QString &programid)
3176 QString compare =
"<=";
3177 QString sortorder =
"desc";
3182 chanid = sourceChanid;
3230 QString querystr = QString(
3231 "SELECT title, subtitle, description, category, "
3232 " starttime, endtime, callsign, icon, "
3233 " channum, seriesid, programid "
3234 "FROM program, channel "
3235 "WHERE program.chanid = channel.chanid AND "
3236 " channel.chanid = :CHANID AND "
3237 " starttime %1 :STARTTIME "
3238 "ORDER BY starttime %2 "
3239 "LIMIT 1").arg(compare).arg(sortorder);
3248 starttime = endtime = callsign = iconpath =
"";
3249 channum = seriesid = programid =
"";
3270 sourceChanid = chanid;
3276 "SELECT channum, callsign, icon "
3278 "WHERE chanid = :CHANID");
3287 sourceChanid = chanid;
3295 QString &callsign, QString &channum,
3296 QString &channame, QString &xmltvid)
const
3303 if ((!chanid || !sourceid) && !
m_channel)
3314 "SELECT callsign, channum, name, xmltvid "
3316 "WHERE chanid = :CHANID");
3336 const QString& oldchannum,
3337 const QString& callsign,
const QString& channum,
3338 const QString& channame,
const QString& xmltvid)
3340 if (!chanid || !sourceid || channum.isEmpty())
3346 "SET callsign = :CALLSIGN, "
3347 " channum = :CHANNUM, "
3348 " name = :CHANNAME, "
3349 " xmltvid = :XMLTVID "
3350 "WHERE chanid = :CHANID AND "
3351 " sourceid = :SOURCEID");
3381 if (oldbuffer && (oldbuffer !=
Buffer))
3393 LOG(VB_GENERAL, LOG_INFO,
LOC +
"RingBufferChanged()");
3413 QString &input)
const
3440 if (
m_channel && !channum.isEmpty() && (channum.indexOf(
"NextChannel") >= 0))
3443 int dir = channum.rightRef(channum.length() - 12).toInt();
3508 LOG(VB_RECORD, LOG_INFO,
LOC +
3509 "HandleTuning Request: " + request.
toString());
3516 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"On same multiplex");
3530 LOG(VB_RECORD, LOG_INFO,
LOC +
3531 "No recorder yet, calling TuningFrequency");
3536 LOG(VB_RECORD, LOG_INFO,
LOC +
"Waiting for recorder pause..");
3549 LOG(VB_RECORD, LOG_INFO,
LOC +
3550 "Recorder paused, calling TuningFrequency");
3577 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"TuningShutdowns(%1)")
3604 if (sd && (sd != rec_sd))
3638 LOG(VB_RECORD, LOG_INFO,
LOC +
"Tearing down RingBuffer");
3666 LOG(VB_GENERAL, LOG_INFO,
LOC +
"TuningFrequency");
3683 if (request.
m_minorChan && (tuningmode ==
"atsc"))
3712 slist<<
"message"<<QObject::tr(
"On known multiplex...");
3726 if (!channum.isEmpty())
3739 LOG(VB_GENERAL, LOG_ERR,
LOC +
3740 QString(
"Failed to set channel to %1. Reverting to kState_None")
3749 LOG(VB_GENERAL, LOG_ERR,
LOC +
3750 QString(
"Failed to set channel to %1.").
arg(channum));
3770 bool use_dr = use_sm && (livetv || antadj);
3771 bool has_dummy =
false;
3792 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create RingBuffer 1");
3802 LOG(VB_RECORD, LOG_INFO,
LOC +
"Starting Signal Monitor");
3807 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to setup signal monitor");
3825 SetVideoStreamsRequired(0);
3852 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
3853 QString(
"Pre-fail start deadline: %1 "
3854 "Start recording deadline: %2 "
3855 "Good signal deadline: %3")
3857 .toString(
"hh:mm:ss.zzz"))
3859 .toString(
"hh:mm:ss.zzz"))
3861 .toString(
"hh:mm:ss.zzz")));
3885 LOG(VB_RECORD, LOG_INFO,
"DummyDTVRecorder -- started");
3911 bool keep_trying =
false;
3924 LOG(VB_RECORD, LOG_INFO,
LOC +
"TuningSignalCheck: Good signal");
3930 QString desc = tr(
"Good signal seen after %1 ms")
3939 tr(
"See 'Tuning timeout' in mythtv-setup "
3940 "for this input."));
3943 LOG(VB_GENERAL, LOG_WARNING,
LOC +
3944 QString(
"It took longer than %1 ms to get a signal lock. "
3945 "Keeping status of '%2'")
3948 LOG(VB_GENERAL, LOG_WARNING,
LOC +
3949 "See 'Tuning timeout' in mythtv-setup for this input");
3958 LOG(VB_GENERAL, LOG_ERR,
LOC +
"TuningSignalCheck: SignalMonitor " +
3971 LOG(VB_GENERAL, LOG_ERR,
LOC +
3972 "TuningSignalCheck: Hit pre-fail timeout");
3986 QString desc = tr(
"Taking more than %1 ms to get a lock.")
3994 tr(
"See 'Tuning timeout' in mythtv-setup "
3995 "for this input."));
3999 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4000 QString(
"TuningSignalCheck: taking more than %1 ms to get a lock. "
4001 "marking this recording as '%2'.")
4004 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4005 "See 'Tuning timeout' in mythtv-setup for this input");
4013 LOG(VB_RECORD, LOG_INFO,
LOC +
4014 QString(
"TuningSignalCheck: Still waiting. Will timeout @ %1")
4016 .toString(
"hh:mm:ss.zzz")));
4027 MythEvent me(QString(
"UPDATE_RECORDING_STATUS %1 %2 %3 %4 %5")
4059 LOG(VB_EIT, LOG_INFO,
LOC +
4060 "EIT scanning disabled for all sources on this input.");
4070 bool on_host,
bool transcode_bfr_comm,
bool on_line_comm)
4086 if ((!autoTrans) || (autoTrans->
getValue().toInt() == 0))
4110 !transcode_bfr_comm;
4134 QString profileName =
"Live TV";
4135 if (!tvchain && rec)
4138 QString profileRequested = profileName;
4143 LOG(VB_RECORD, LOG_INFO,
LOC +
4144 QString(
"Using profile '%1' to record")
4149 profileName =
"Default";
4152 LOG(VB_RECORD, LOG_INFO,
LOC +
4153 QString(
"Profile '%1' not found, using "
4154 "fallback profile '%2' to record")
4155 .
arg(profileRequested).
arg(profileName));
4159 LOG(VB_RECORD, LOG_ERR,
LOC +
4160 QString(
"Profile '%1' not found, and unable "
4161 "to load fallback profile '%2'. Results "
4162 "may be unpredicable")
4163 .
arg(profileRequested).
arg(profileName));
4175 LOG(VB_RECORD, LOG_INFO,
LOC +
"Starting Recorder");
4177 bool had_dummyrec =
false;
4183 had_dummyrec =
true;
4204 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create RingBuffer 2");
4213 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"rec->GetPathname(): '%1'")
4218 LOG(VB_GENERAL, LOG_ERR,
LOC +
4219 QString(
"RingBuffer '%1' not open...")
4229 LOG(VB_GENERAL, LOG_ERR,
LOC +
4230 QString(
"Failed to start recorder! ringBuffer is NULL\n"
4231 "\t\t\t\t Tuning request was %1\n")
4236 QString message = QString(
"QUIT_LIVETV %1").arg(
m_inputId);
4246 LOG(VB_GENERAL, LOG_INFO,
LOC +
"TuningNewRecorder - CreateRecorder()");
4255 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialize recorder!");
4263 LOG(VB_GENERAL, LOG_ERR,
LOC +
4264 QString(
"Failed to start recorder!\n"
4265 "\t\t\t\t Tuning request was %1\n")
4270 QString message = QString(
"QUIT_LIVETV %1").arg(
m_inputId);
4311 std::this_thread::sleep_for(std::chrono::microseconds(5));
4340 LOG(VB_RECORD, LOG_INFO,
LOC +
4341 QString(
"TuningNewRecorder -- UPDATE_RECORDING_STATUS: %1")
4343 MythEvent me(QString(
"UPDATE_RECORDING_STATUS %1 %2 %3 %4 %5")
4361 LOG(VB_RECORD, LOG_INFO,
LOC +
"Restarting Recorder");
4363 bool had_dummyrec =
false;
4374 had_dummyrec =
true;
4400 QString msg1 = QString(
"Recording: %1 %2 %3 %4")
4405 QString msg2 = QString(
"Recording: %1 %2 %3 %4")
4410 LOG(VB_RECORD, LOG_INFO,
LOC +
"Pseudo LiveTV recording starting." +
4411 "\n\t\t\t" + msg1 +
"\n\t\t\t" + msg2);
4428 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetFlags(%1) -> %2 @ %3:%4")
4437 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"ClearFlags(%1) -> %2 @ %3:%4")
4448 msg +=
"FrontendReady,";
4450 msg +=
"RunMainLoop,";
4452 msg +=
"ExitPlayer,";
4454 msg +=
"FinishRecording,";
4458 msg +=
"CancelNextRecording,";
4468 msg +=
"Recording,";
4481 msg +=
"AntennaAdjust,";
4484 msg +=
"PENDINGACTIONS,";
4488 msg +=
"WaitingForRecPause,";
4490 msg +=
"WaitingForSignal,";
4492 msg +=
"NeedToStartRecorder,";
4494 msg +=
"KillRingBuffer,";
4497 msg +=
"ANYRUNNING,";
4501 msg +=
"SignalMonitorRunning,";
4503 msg +=
"EITScannerRunning,";
4505 msg +=
"ANYRECRUNNING,";
4509 msg +=
"DummyRecorderRunning,";
4511 msg +=
"RecorderRunning,";
4515 msg +=
"RingBufferReady,";
4518 msg = QString(
"0x%1").arg(
f,0,16);
4546 const QString & channum)
4548 LOG(VB_RECORD, LOG_INFO,
LOC +
"GetProgramRingBufferForLiveTV()");
4570 LOG(VB_GENERAL, LOG_ERR,
LOC +
4571 QString(
"Channel: \'%1\' was not found in the database.\n"
4572 "\t\tMost likely, the 'starting channel' for this "
4573 "Input Connection is invalid.\n"
4574 "\t\tCould not start livetv.").
arg(channum));
4596 LOG(VB_GENERAL, LOG_ERR,
LOC +
"GetProgramRingBufferForLiveTV()"
4597 "\n\t\t\tProgramInfo is invalid."
4627 if (!(*
Buffer) || !(*Buffer)->IsOpen())
4629 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"RingBuffer '%1' not open...")
4644 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"CreateLiveTVRingBuffer(%1)")
4661 LOG(VB_GENERAL, LOG_ERR,
LOC +
4662 QString(
"CreateLiveTVRingBuffer(%1) failed").
arg(channum));
4689 bool discont,
bool set_rec)
4694 msg = QString(
" curRec(%1) curRec.size(%2)")
4698 LOG(VB_RECORD, LOG_INFO,
LOC +
4699 QString(
"SwitchLiveTVRingBuffer(discont %1, set_next_rec %2)")
4700 .
arg(discont).
arg(set_rec) + msg);
4758 LOG(VB_RECORD, LOG_INFO,
LOC +
"SwitchRecordingRingBuffer()");
4762 LOG(VB_RECORD, LOG_ERR,
LOC +
"SwitchRecordingRingBuffer -> "
4763 "already switching.");
4769 LOG(VB_RECORD, LOG_ERR,
LOC +
"SwitchRecordingRingBuffer -> "
4770 "invalid recorder.");
4776 LOG(VB_RECORD, LOG_ERR,
LOC +
"SwitchRecordingRingBuffer -> "
4777 "invalid recording.");
4783 LOG(VB_RECORD, LOG_ERR,
LOC +
"SwitchRecordingRingBuffer -> "
4784 "Not the same channel.");
4795 LOG(VB_RECORD, LOG_ERR,
LOC +
4796 QString(
"SwitchRecordingRingBuffer() -> "
4797 "cannot switch profile '%1' to '%2'")
4809 if (!buffer || !buffer->
IsOpen())
4816 LOG(VB_RECORD, LOG_ERR,
LOC +
"SwitchRecordingRingBuffer() -> "
4817 "Failed to create new RB.");
4826 LOG(VB_RECORD, LOG_INFO,
LOC +
"SwitchRecordingRingBuffer -> done");
4832 QMap<uint,TVRec*>::const_iterator it =
s_inputs.constFind(inputid);
4840 return QString(
"Program(%1) channel(%2) input(%3) flags(%4)")
bool CreateLiveTVRingBuffer(const QString &channum)
uint GetMajorChannel(void) const
Returns major channel, 0 if unknown.
bool isActive(void) const
@ BROWSE_LEFT
Fetch information on current channel in the past.
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.
void SetFlags(uint f, const QString &file, int line)
bool GetKeyframeDurations(int64_t start, int64_t end, frm_pos_map_t &map) const
void AddFlags(uint64_t _flags) override
bool IsReallyRecording(void)
Returns true if frontend can consider the recorder started.
static int eit_start_rand(uint inputId, int eitTransportTimeout)
QString MakeUniqueKey(void) const
Creates a unique string that can be used to identify an existing recording.
std::vector< uint > m_possibleConflicts
virtual bool Init(QString &startchannel, bool setchan)
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
static const uint kFlagNoRec
static const uint kFlagErrored
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
QDateTime m_startRecordingDeadline
static void RemoveJobsFromMask(int jobs, int &mask)
static const uint kFlagEITScannerRunning
void FinishedRecording(bool allowReRecord)
If not a premature stop, adds program to history of recorded programs.
@ BROWSE_UP
Fetch information on previous channel.
static bool JobIsInMask(int job, int mask)
void SetPseudoLiveTVRecording(RecordingInfo *pi)
Sets the pseudo LiveTV RecordingInfo.
void SetVideoStreamsRequired(uint num)
void SetDVBService(uint network_id, uint transport_id, int service_id)
static void error(const char *str,...)
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
void SetRecordingStatus(RecStatus::Type status)
uint QueryMplexID(void) const
Queries multiplex any recording would be made on, zero if unknown.
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
void SetDesiredProgram(int p)
static RecorderBase * CreateRecorder(TVRec *tvrec, ChannelBase *channel, RecordingProfile &profile, const GeneralDBOptions &genOpt)
bool ShouldSwitchToAnotherInput(const QString &chanid) const
Checks if named channel exists on current tuner, or another tuner.
static const uint kFlagRecording
final result desired is a timed recording
bool Save(bool sendSig=true)
virtual bool IsAllGood(void) const
void SetDuration(int Duration)
Contains a duration during which the notification will be displayed for. The duration is informative ...
static bool QueueJob(int jobType, uint chanid, const QDateTime &recstartts, const QString &args="", const QString &comment="", QString host="", int flags=0, int status=JOB_QUEUED, QDateTime schedruntime=QDateTime())
static QString GetInputName(uint inputid)
void StopPassiveScan(void)
Stops inserting Event Information Tables into DB.
A QElapsedTimer based timer to replace use of QTime as a timer.
QMutex m_triggerEventSleepLock
virtual bool Open(void)=0
Opens the channel changing hardware for use.
TuningQueue m_tuningRequests
uint RemoteGetState(uint inputid)
virtual QString GetInputName(void) const
const QString kRecorderInUseID
void ApplyRecordRecID(void)
Sets recordid to match RecordingRule recordid.
void SetCaching(bool cacheTables)
virtual void SetRecordingID(uint _recordedid)
bool Init(void)
Performs instance initialization, returns true on success.
static bool IsSupported(const QString &cardtype)
Holds information on a TV Program one might wish to record.
void ToggleChannelFavorite(const QString &changroupname)
Toggles whether the current channel should be on our favorites list.
uint64_t GetFilesize(void) const override
virtual bool IsOpen(void) const =0
Reports whether channel is already open.
bool QueryAverageScanProgressive(void) const
If present in recording this loads average video scan type of the main video stream from database's s...
virtual void Unpause(void)
Unpause tells recorder to unpause.
static const uint kFlagRingBufferReady
uint GetRecordingID(void) const
MythMediaBuffer * m_buffer
virtual bool IsErrored(void)=0
Tells us whether an unrecoverable error has been encountered.
QString GetID(void) const
QWaitCondition m_triggerLiveTVDir
MThread * m_eventThread
Event processing thread, runs TVRec::run().
static const uint kFlagRecorderRunning
This class is used as a container for messages.
static const uint kFlagRec
void StartActiveScan(TVRec *_rec, uint max_seconds_per_source)
RecStatus::Type m_recStatus
static bool GetATSCChannel(uint sourceid, const QString &channum, uint &major, uint &minor)
QString SetInput(QString input)
Changes to the specified input.
def write(text, progress=True)
static int GetProgramNumber(uint sourceid, const QString &channum)
static const uint64_t kDTVSigMon_WaitForMGT
uint GetSourceID(void) const
Returns current source id.
void StartPassiveScan(ChannelBase *channel, EITSource *eitSource)
Start inserting Event Information Tables from the multiplex we happen to be tuned to into the databas...
static bool QueueRecordingJobs(const RecordingInfo &recinfo, int jobTypes=JOB_NONE)
QVariant value(int i) const
arg(title).arg(filename).arg(doDelete))
QString m_overRecordCategory
QString GetCategory(void) const
virtual void SetStreamData(MPEGStreamData *data)
bool GetProgramRingBufferForLiveTV(RecordingInfo **pginfo, MythMediaBuffer **Buffer, const QString &channum)
uint GetMinorChannel(void) const
Returns minor channel, 0 if unknown.
static void apply_broken_dvb_driver_crc_hack(ChannelBase *, MPEGStreamData *)
QString toString(void) const
MPEGStreamData * GetStreamData()
Returns the MPEG stream data if it exists.
int TotalSize(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
RecordingInfo * m_curRecording
void SaveCommFlagged(CommFlagStatus flag)
Set "commflagged" field in "recorded" table to "flag".
void StopRecording(bool killFile=false)
Changes from a recording state to kState_None.
bool GetKeyframePositions(long long start, long long end, frm_pos_map_t &map) const
void start(void)
starts measuring elapsed time.
QDateTime GetScheduledEndTime(void) const
The scheduled end time of the program.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
long long GetFramesWritten(void)
Returns number of frames written to disk by recorder.
static bool GetDevices(uint inputid, uint &parentid, GeneralDBOptions &gen_opts, DVBDBOptions &dvb_opts, FireWireDBOptions &firewire_opts)
static ChannelBase * CreateChannel(TVRec *tvrec, const GeneralDBOptions &genOpt, DVBDBOptions dvbOpt, const FireWireDBOptions &fwOpt, const QString &startchannel, bool enter_power_save_mode, QString &rbFileExt, bool setchan)
void UpdateInUseMark(bool force=false)
static int num_inputs(void)
QString GetInput(void) const
Returns current input.
static uint GetMplexID(uint sourceid, const QString &channum)
static const uint kFlagDummyRecorderRunning
virtual QString GetChannelName(void) const
bool IsDamaged(void) const
void UpdateRecordingEnd(void)
Update information in the recorded table when the end-time of a recording is changed.
DTVChannel * GetDTVChannel(void)
static const uint kFlagPendingActions
bool CheckChannelPrefix(const QString &prefix, uint &complete_valid_channel_on_rec, bool &is_extra_char_useful, QString &needed_spacer) const
Checks a prefix against the channels in the DB.
virtual void Pause(bool clear=true)
Pause tells recorder to pause, it should not block.
bool IsBusy(InputInfo *busy_input=nullptr, int time_buffer=5) const
Returns true if the recorder is busy, or will be within the next time_buffer seconds.
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
virtual int GetPictureAttribute(PictureAttribute) const
QString GetRecordingGroup(void) const
QString GetChainID(void)
Get the chainid of the livetv instance.
void SetUpdateRate(int msec)
Sets the number of milliseconds between signal monitoring attempts in the signal monitoring thread.
bool GetKeyframeDurations(long long start, long long end, frm_pos_map_t &map) const
bool QueryTuningInfo(QString &channum, QString &input) const
Returns the channel and input needed to record the program.
static void GetPidsToCache(DTVSignalMonitor *dtvMon, pid_cache_t &pid_cache)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
bool TuningOnSameMultiplex(TuningRequest &request)
void TeardownRecorder(uint request_flags)
Tears down the recorder.
@ kState_Error
Error State, if we ever try to enter this state errored is set.
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
long long GetFilePosition(void)
Returns total number of bytes written by RingBuffer.
QString GetPathname(void) const
static const uint kFlagCancelNextRecording
QString toStringXML(void) const
virtual void Renumber(uint sourceid, const QString &oldChanNum, const QString &newChanNum)
Changes a channum if we have it cached anywhere.
RecordingInfo * SwitchRecordingRingBuffer(const RecordingInfo &rcinfo)
QDateTime GetRecordEndTime(const ProgramInfo *pi) const
Returns recording end time with proper post-roll.
QDateTime m_recordEndTime
QString GetTuningMode(void) const
Returns tuning mode last set by SetTuningMode().
@ kState_ChangingState
This is a placeholder state which we never actually enter, but is returned by GetState() when we are ...
uint GetOriginalNetworkID(void) const
Returns DVB original_network_id, 0 if unknown.
ProgramInfo * GetProgramAt(int at) const
Returns program at the desired location.
@ kState_None
None State, this is the initial state in both TV and TVRec, it indicates that we are ready to change ...
void StopActiveScan(void)
static bool IsRequired(const QString &cardtype)
Returns true iff the card type supports signal monitoring.
void SetIgnoreCRC(bool haveCRCbug)
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
PendingMap m_pendingRecordings
#define TRANSITION(ASTATE, BSTATE)
static const uint kFlagAnyRecRunning
virtual bool InitPictureAttributes(void)
uint GetInputId(void) const
Returns the inputid.
void MarkAsInUse(bool inuse, const QString &usedFor="")
Tracks a recording's in use status, to prevent deletion and to allow the storage scheduler to perform...
uint GetTransportID(void) const
Returns DVB transport_stream_id, 0 if unknown.
virtual void ReturnCachedTable(const PSIPTable *psip) const
static const uint kFlagWaitingForSignal
static const uint kFlagDetect
void SetPathname(const QString &pn)
void SaveVideoProperties(uint mask, uint video_property_flags)
void SetRecordingEndTime(const QDateTime &dt)
bool CreateChannel(const QString &startchannel, bool enter_power_save_mode)
QHash< QString, int > m_autoRunJobs
RecordingFile * GetRecordingFile() const
void PauseRecorder(void)
Tells "recorder" to pause, used for channel and input changes.
void NotifySchedulerOfRecording(RecordingInfo *rec)
Tell scheduler about the recording.
void SetDesiredChannel(int major, int minor)
static int GetChanID(int db_mplexid, int service_transport_id, int major_channel, int minor_channel, int program_number)
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
static const uint64_t kDVBSigMon_WaitForPos
Wait for rotor to complete turning the antenna.
RecStatus::Type GetRecordingStatus(void) const
void SetRecordingStatus(RecStatus::Type new_status, int line, bool have_lock=false)
MarkTypes QueryAverageAspectRatio(void) const
static bool is_dishnet_eit(uint inputid)
void SetDishNetEIT(bool use_dishnet_eit)
void SetHostPrefix(const QString &prefix)
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
bool RemoteStopRecording(uint inputid)
Abstract class providing a generic interface to tuning hardware.
void SetRingBuffer(MythMediaBuffer *Buffer)
Tells recorder to use an externally created ringbuffer.
uint TablePID(uint i) const
static bool IsEncoder(const QString &rawtype)
bool RemoteIsBusy(uint inputid, InputInfo &busy_input)
static const uint kFlagKillRec
close recorder, discard recording
void SetScheduledEndTime(const QDateTime &dt)
void SaveCachedPids(const pid_cache_t &pid_cache) const
Saves MPEG PIDs to cache to database.
int GetBackendServerPort(void)
Returns the locally defined backend control port.
RecorderBase * m_recorder
void SendSystemEvent(const QString &msg)
virtual void StoreInputChannels(void)
Saves current channel as the default channel for the current input.
long long GetMaxBitrate(void) const
Returns the maximum bits per second this recorder can produce.
void SendEvent(const MythEvent &event)
static const uint kFlagRunMainLoop
void SetRecordingRuleType(RecordingType type)
TVState RemoveRecording(TVState state) const
If "state" is kState_RecordingOnly or kState_WatchingLiveTV, returns a kState_None,...
bool WaitForEventThreadSleep(bool wake=true, ulong time=ULONG_MAX)
RecordingInfo * m_pseudoLiveTVRecording
void SetRecordingType(const QString &recording_type)
static QString FlagToString(uint f)
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetTitle(void) const
void HandleStateChange(void)
Changes the internalState to the desiredNextState if possible.
std::vector< pid_cache_item_t > pid_cache_t
void SetInputType(const QString &type)
Encapsulates data about ATSC stream and emits events for most tables.
static void DBError(const QString &where, const MSqlQuery &query)
bool CheckChannel(const QString &name) const
Checks if named channel exists on current tuner.
static const uint64_t kDTVSigMon_WaitForPMT
virtual void Reset(void)=0
Reset the recorder to the startup state.
static const uint kFlagSignalMonitorRunning
void SetRecordingGroup(const QString &group)
bool SetupSignalMonitor(bool tablemon, bool EITscan, bool notify)
This creates a SignalMonitor instance and begins signal monitoring.
static const uint64_t kDTVSigMon_WaitForPAT
QString TuningGetChanNum(const TuningRequest &request, QString &input) const
static const uint kFlagEITScan
final result desired is an EIT Scan
static const uint64_t kDTVSigMon_WaitForSDT
void TeardownSignalMonitor(void)
If a SignalMonitor instance exists, the monitoring thread is stopped and the instance is deleted.
virtual RecordingQuality * GetRecordingQuality(const RecordingInfo *ri) const
Returns a report about the current recordings quality.
bool WaitForNextLiveTVDir(void)
void SetDesiredStartTime(const QDateTime &dt)
static const uint kSignalMonitoringRate
How many milliseconds the signal monitor should wait between checks.
static const uint kFlagCloseRec
close recorder, keep recording
int GetAutoRunJobs(void) const
Returns a bitmap of which jobs are attached to this RecordingInfo.
uint GetSourceID(void) const
Encapsulates data about MPEG stream and emits events for each table.
QWaitCondition m_triggerEventSleepWait
double GetFrameRate(void) const
Returns the latest frame rate.
static bool JobIsNotInMask(int job, int mask)
static const uint kFlagKillRingBuffer
void ChangeState(TVState nextState)
Puts a state change on the nextState queue.
TVState m_desiredNextState
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
void run(void) override
Event handling method, contains event loop.
bool m_triggerEventLoopSignal
MPEGStreamData * GetStreamData(void) const
static QString add_spacer(const QString &channel, const QString &spacer)
Adds the spacer before the last character in chan.
virtual bool IsRecording(void)
Tells whether the StartRecorder() loop is running.
AutoExpireType GetAutoExpire(void) const
void TuningShutdowns(const TuningRequest &request)
This shuts down anything that needs to be shut down before handling the passed in tuning request.
QString m_liveTVStartChannel
friend class TuningRequest
virtual int GetVideoFd(void)=0
Returns file descriptor of recorder device.
virtual QString getValue(void) const
void ReloadAll(const QStringList &data=QStringList())
int SetSignalMonitoringRate(int rate, int notifyFrontend=1)
Sets the signal monitoring rate.
QDateTime m_eitScanStartTime
int GetPictureAttribute(PictureAttribute attr)
void TuningNewRecorder(MPEGStreamData *streamData)
Creates a recorder instance.
void StartedRecording(const QString &ext)
Inserts this RecordingInfo into the database as an existing recording.
bool GetKeyframePositions(int64_t start, int64_t end, frm_pos_map_t &map) const
Returns byte position in RingBuffer of a keyframes according to recorder.
static QReadWriteLock s_inputsLock
static const uint kFlagWaitingForRecPause
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
@ CHANNEL_DIRECTION_FAVORITE
bool isConnected(void) const
Only updated once during object creation.
static const uint kFlagLiveTV
final result desired is LiveTV recording
void SetNextLiveTVDir(QString dir)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
float GetFramerate(void)
Returns recordering frame rate from the recorder.
bool m_signalEventCmdSent
RecStatus::Type GetRecordingStatus(void) const
bool QueueEITChannelChange(const QString &name)
Queues up a channel change for the EITScanner.
ATSCStreamData * GetATSCStreamData()
Returns the ATSC stream data if it exists.
QWaitCondition m_triggerEventLoopWait
virtual bool EnterPowerSavingMode(void)
Enters power saving mode if the card supports it.
@ BROWSE_DOWN
Fetch information on next channel.
static bool IsV4L(const QString &rawtype)
bool IsErrored(void) const
Returns true is "errored" is true, false otherwise.
int GetNumSetting(const QString &key, int defaultval=0)
virtual long long GetFramesWritten(void)=0
Returns number of frames written to disk.
void SaveAutoExpire(AutoExpireType autoExpire, bool updateDelete=false)
Set "autoexpire" field in "recorded" table to "autoExpire".
virtual void SetFd(int fd)
Sets file descriptor.
@ BROWSE_RIGHT
Fetch information on current channel in the future.
ProgramInfo * GetRecording(void)
Allocates and returns a ProgramInfo for the current recording.
void SpawnLiveTV(LiveTVChain *newchain, bool pip, QString startchan)
Tells TVRec to spawn a "Live TV" recorder.
static bool IsVBoxPresent(uint inputid)
Returns true if the VBox responds to a ping.
void CancelNextRecording(bool cancel)
Tells TVRec to cancel the upcoming recording.
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
static SignalMonitor * Init(const QString &cardtype, int db_cardnum, ChannelBase *channel, bool release_stream)
virtual void StopRecording(void)
StopRecording() signals to the recorder that it should stop recording and exit cleanly.
bool m_triggerEventSleepSignal
static QString GetVideoFilters(uint sourceid, const QString &channum)
virtual void Initialize(void)=0
This is called between SetOptionsFromProfile() and run() to initialize any devices,...
QString GetSIStandard(void) const
Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
int m_eitTransportTimeout
void GetNextProgram(BrowseDirection direction, QString &title, QString &subtitle, QString &desc, QString &category, QString &starttime, QString &endtime, QString &callsign, QString &iconpath, QString &channum, uint &chanid, QString &seriesid, QString &programid)
Defini