MythTV  master
remoteencoder.cpp
Go to the documentation of this file.
1 #include <unistd.h>
2 
3 #include <QStringList>
4 
5 #include "remoteencoder.h"
6 #include "programinfo.h"
7 #include "mythdate.h"
8 #include "mythcorecontext.h"
9 #include "signalmonitor.h"
10 #include "videooutbase.h"
11 #include "mythdb.h"
12 #include "mythsocket.h"
13 #include "mythlogging.h"
14 
15 using namespace std;
16 
17 #define LOC QString("RemoteEncoder(%1): ").arg(recordernum)
18 
19 #define MAX_SIZE_CHECK 500 // in ms
20 
21 RemoteEncoder::RemoteEncoder(int num, const QString &host, short port)
22  : recordernum(num), controlSock(nullptr), remotehost(host),
23  remoteport(port), lastchannel(""), lastinput(""),
24  backendError(false), cachedFramesWritten(0)
25 {
26 }
27 
29 {
30  if (controlSock)
31  {
33  controlSock = nullptr;
34  }
35 }
36 
38 {
39  if (!controlSock)
40  {
41  LOG(VB_NETWORK, LOG_DEBUG, "RemoteEncoder::Setup(): Connecting...");
42 
43  QString ann = QString("ANN Playback %1 %2")
44  .arg(gCoreContext->GetHostName()).arg(false);
45 
47  remotehost, remoteport, ann);
48 
49  if (controlSock)
50  {
51  LOG(VB_NETWORK, LOG_DEBUG, "RemoteEncoder::Setup(): Connected");
52  }
53  else
54  {
55  LOG(VB_GENERAL, LOG_ERR,
56  "RemoteEncoder::Setup(): Failed to connect to backend");
57  }
58  }
59  else
60  {
61  LOG(VB_NETWORK, LOG_DEBUG, "RemoteEncoder::Setup(): Already connected");
62  }
63  return controlSock;
64 }
65 
67 {
68  return (recordernum >= 0);
69 }
70 
72 {
73  return recordernum;
74 }
75 
77  QStringList &strlist, uint min_reply_length)
78 {
79  QMutexLocker locker(&lock);
80  if (!controlSock)
81  Setup();
82 
83  backendError = false;
84 
85  if (!controlSock)
86  {
87  LOG(VB_GENERAL, LOG_ERR, "RemoteEncoder::SendReceiveStringList(): "
88  "Failed to reconnect with backend.");
89  backendError = true;
90  return false;
91  }
92 
93  if (!controlSock->WriteStringList(strlist))
94  {
95  LOG(VB_GENERAL, LOG_ERR, "RemoteEncoder::SendReceiveStringList(): "
96  "Failed to write data.");
97  backendError = true;
98  }
99 
100  if (!backendError &&
102  {
103  LOG(VB_GENERAL, LOG_ERR,
104  "RemoteEncoder::SendReceiveStringList(): No response.");
105  backendError = true;
106  }
107 
108  if (!backendError &&
109  min_reply_length && ((uint)strlist.size() < min_reply_length))
110  {
111  LOG(VB_GENERAL, LOG_ERR,
112  "RemoteEncoder::SendReceiveStringList(): Response too short");
113  backendError = true;
114  }
115 
116  if (backendError)
117  {
118  controlSock->DecrRef();
119  controlSock = nullptr;
120  return false;
121  }
122 
123  return true;
124 }
125 
127 {
128  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
129  strlist << "IS_RECORDING";
130 
131  bool ret = SendReceiveStringList(strlist, 1);
132  if (!ret)
133  {
134  if (ok)
135  *ok = false;
136 
137  return false;
138  }
139 
140  if (ok)
141  *ok = true;
142 
143  return strlist[0].toInt();
144 }
145 
147 {
148  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
149  strlist << "GET_RECORDING";
150 
151  if (SendReceiveStringList(strlist))
152  {
153  ProgramInfo *proginfo = new ProgramInfo(strlist);
154  if (proginfo->GetChanID())
155  return proginfo;
156  delete proginfo;
157  }
158 
159  return nullptr;
160 }
161 
169 {
170  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
171  strlist << "GET_FRAMERATE";
172 
173  bool ok = false;
174  float retval = 30.0f;
175 
176  if (SendReceiveStringList(strlist, 1))
177  {
178  retval = strlist[0].toFloat(&ok);
179 
180  if (!ok)
181  {
182  LOG(VB_GENERAL, LOG_ERR, LOC +
183  QString("GetFrameRate() failed to parse response '%1'")
184  .arg(strlist[0]));
185  }
186  }
187  else
188  {
189  LOG(VB_GENERAL, LOG_ERR, LOC +
190  "GetFrameRate(): SendReceiveStringList() failed");
191  }
192 
193  return (ok) ? retval : 30.0f;
194 }
195 
204 {
206  {
207  return cachedFramesWritten;
208  }
209 
210  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
211  strlist << "GET_FRAMES_WRITTEN";
212 
213  if (!SendReceiveStringList(strlist, 1))
214  {
215  LOG(VB_GENERAL, LOG_ERR, LOC + "GetFramesWritten() -- network error");
216  }
217  else
218  {
219  cachedFramesWritten = strlist[0].toLongLong();
221  }
222 
223  return cachedFramesWritten;
224 }
225 
233 {
234  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
235  strlist << "GET_FILE_POSITION";
236 
237  if (SendReceiveStringList(strlist, 1))
238  return strlist[0].toLongLong();
239 
240  return -1;
241 }
242 
248 {
249  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
250  strlist << "GET_MAX_BITRATE";
251 
252  if (SendReceiveStringList(strlist, 1))
253  return strlist[0].toLongLong();
254 
255  return 20200000LL; // Peek bit rate for HD-PVR
256 }
257 
265 int64_t RemoteEncoder::GetKeyframePosition(uint64_t desired)
266 {
267  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
268  strlist << "GET_KEYFRAME_POS";
269  strlist << QString::number(desired);
270 
271  if (SendReceiveStringList(strlist, 1))
272  return strlist[0].toLongLong();
273 
274  return -1;
275 }
276 
277 void RemoteEncoder::FillPositionMap(int64_t start, int64_t end,
278  frm_pos_map_t &positionMap)
279 {
280  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
281  strlist << "FILL_POSITION_MAP";
282  strlist << QString::number(start);
283  strlist << QString::number(end);
284 
285  if (!SendReceiveStringList(strlist))
286  return;
287 
288  QStringList::const_iterator it = strlist.begin();
289  for (; it != strlist.end(); ++it)
290  {
291  bool ok;
292  uint64_t index = (*it).toLongLong(&ok);
293  if (++it == strlist.end() || !ok)
294  break;
295 
296  uint64_t pos = (*it).toLongLong(&ok);
297  if (!ok)
298  break;
299 
300  positionMap[index] = pos;
301  }
302 }
303 
304 void RemoteEncoder::FillDurationMap(int64_t start, int64_t end,
305  frm_pos_map_t &durationMap)
306 {
307  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
308  strlist << "FILL_DURATION_MAP";
309  strlist << QString::number(start);
310  strlist << QString::number(end);
311 
312  if (!SendReceiveStringList(strlist))
313  return;
314 
315  QStringList::const_iterator it = strlist.begin();
316  for (; it != strlist.end(); ++it)
317  {
318  bool ok;
319  uint64_t index = (*it).toLongLong(&ok);
320  if (++it == strlist.end() || !ok)
321  break;
322 
323  uint64_t pos = (*it).toLongLong(&ok);
324  if (!ok)
325  break;
326 
327  durationMap[index] = pos;
328  }
329 }
330 
332 {
333  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
334  strlist << "CANCEL_NEXT_RECORDING";
335  strlist << QString::number((cancel) ? 1 : 0);
336 
337  SendReceiveStringList(strlist);
338 }
339 
341 {
342  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
343  strlist << "FRONTEND_READY";
344 
345  SendReceiveStringList(strlist);
346 }
347 
353 {
354  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
355  strlist << "STOP_PLAYING";
356 
357  SendReceiveStringList(strlist);
358 }
359 
365 void RemoteEncoder::SpawnLiveTV(QString chainId, bool pip, QString startchan)
366 {
367  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
368  strlist << "SPAWN_LIVETV";
369  strlist << chainId;
370  strlist << QString::number((int)pip);
371  strlist << startchan;
372 
373  SendReceiveStringList(strlist);
374 }
375 
382 {
383  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
384  strlist << "STOP_LIVETV";
385 
386  SendReceiveStringList(strlist);
387 }
388 
395 {
396  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
397  strlist << "PAUSE";
398 
399  if (SendReceiveStringList(strlist))
400  lastinput = "";
401 }
402 
404 {
405  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
406  strlist << "FINISH_RECORDING";
407 
408  SendReceiveStringList(strlist);
409 }
410 
412 {
413  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
414  strlist << "SET_LIVE_RECORDING";
415  strlist << QString::number(recording);
416 
417  SendReceiveStringList(strlist);
418 }
419 
421 {
422  if (!lastinput.isEmpty())
423  return lastinput;
424 
425  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
426  strlist << "GET_INPUT";
427 
428  if (SendReceiveStringList(strlist, 1))
429  {
430  lastinput = strlist[0];
431  return lastinput;
432  }
433 
434  return "Error";
435 }
436 
437 QString RemoteEncoder::SetInput(QString input)
438 {
439  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
440  strlist << "SET_INPUT";
441  strlist << input;
442 
443  if (SendReceiveStringList(strlist, 1))
444  {
445  lastchannel = "";
446  lastinput = "";
447  return strlist[0];
448  }
449 
450  return (lastinput.isEmpty()) ? "Error" : lastinput;
451 }
452 
453 void RemoteEncoder::ToggleChannelFavorite(QString changroupname)
454 {
455  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
456  strlist << "TOGGLE_CHANNEL_FAVORITE";
457  strlist << changroupname;
458 
459  SendReceiveStringList(strlist);
460 }
461 
462 void RemoteEncoder::ChangeChannel(int channeldirection)
463 {
464  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
465  strlist << "CHANGE_CHANNEL";
466  strlist << QString::number(channeldirection);
467 
468  if (!SendReceiveStringList(strlist))
469  return;
470 
471  lastchannel = "";
472  lastinput = "";
473 }
474 
475 void RemoteEncoder::SetChannel(QString channel)
476 {
477  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
478  strlist << "SET_CHANNEL";
479  strlist << channel;
480 
481  if (!SendReceiveStringList(strlist))
482  return;
483 
484  lastchannel = "";
485  lastinput = "";
486 }
487 
504 int RemoteEncoder::SetSignalMonitoringRate(int rate, bool notifyFrontend)
505 {
506  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
507  strlist << "SET_SIGNAL_MONITORING_RATE";
508  strlist << QString::number(rate);
509  strlist << QString::number((int)notifyFrontend);
510 
511  if (SendReceiveStringList(strlist, 1))
512  return strlist[0].toInt();
513 
514  return 0;
515 }
516 
518 {
519  QMutexLocker locker(&lock);
520 
521  QMap<QString,uint>::const_iterator it = cachedTimeout.find(input);
522  if (it != cachedTimeout.end())
523  return *it;
524 
525  uint cardid = recordernum;
526  uint timeout = 0xffffffff;
527  MSqlQuery query(MSqlQuery::InitCon());
528  query.prepare(
529  "SELECT channel_timeout, cardtype "
530  "FROM capturecard "
531  "WHERE capturecard.inputname = :INNAME AND "
532  " capturecard.cardid = :CARDID");
533  query.bindValue(":INNAME", input);
534  query.bindValue(":CARDID", cardid);
535  if (!query.exec() || !query.isActive())
536  MythDB::DBError("Getting timeout", query);
537  else if (query.next() &&
538  SignalMonitor::IsRequired(query.value(1).toString()))
539  timeout = max(query.value(0).toInt(), 500);
540 
541 #if 0
542  LOG(VB_PLAYBACK, LOG_DEBUG, "RemoteEncoder: " +
543  QString("GetSignalLockTimeout(%1): Set lock timeout to %2 ms")
544  .arg(cardid).arg(timeout));
545 #endif
546  cachedTimeout[input] = timeout;
547  return timeout;
548 }
549 
550 
552 {
553  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
554 
555  if (kPictureAttribute_Contrast == attr)
556  strlist << "GET_CONTRAST";
557  else if (kPictureAttribute_Brightness == attr)
558  strlist << "GET_BRIGHTNESS";
559  else if (kPictureAttribute_Colour == attr)
560  strlist << "GET_COLOUR";
561  else if (kPictureAttribute_Hue == attr)
562  strlist << "GET_HUE";
563  else
564  return -1;
565 
566  if (SendReceiveStringList(strlist, 1))
567  return strlist[0].toInt();
568 
569  return -1;
570 }
571 
580  PictureAdjustType type, PictureAttribute attr, bool up)
581 {
582  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
583 
584  if (kPictureAttribute_Contrast == attr)
585  strlist << "CHANGE_CONTRAST";
586  else if (kPictureAttribute_Brightness == attr)
587  strlist << "CHANGE_BRIGHTNESS";
588  else if (kPictureAttribute_Colour == attr)
589  strlist << "CHANGE_COLOUR";
590  else if (kPictureAttribute_Hue == attr)
591  strlist << "CHANGE_HUE";
592  else
593  return -1;
594 
595  strlist << QString::number(type);
596  strlist << QString::number((int)up);
597 
598  if (SendReceiveStringList(strlist, 1))
599  return strlist[0].toInt();
600 
601  return -1;
602 }
603 
605 {
606  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
607  strlist << "CHANGE_DEINTERLACER";
608  strlist << QString::number(deint_mode);
609 
610  SendReceiveStringList(strlist);
611 }
612 
622 bool RemoteEncoder::CheckChannel(QString channel)
623 {
624  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
625  strlist << "CHECK_CHANNEL";
626  strlist << channel;
627 
628  if (SendReceiveStringList(strlist, 1))
629  return strlist[0].toInt();
630 
631  return false;
632 }
633 
644 {
645  // this function returns true if the channelid is not a valid
646  // channel on the current recorder. It queries to server in order
647  // to determine this.
648  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
649  strlist << "SHOULD_SWITCH_CARD";
650  strlist << channelid;
651 
652  if (SendReceiveStringList(strlist, 1))
653  return strlist[0].toInt();
654 
655  return false;
656 }
657 
665  const QString &prefix,
666  uint &is_complete_valid_channel_on_rec,
667  bool &is_extra_char_useful,
668  QString &needed_spacer)
669 {
670  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
671  strlist << "CHECK_CHANNEL_PREFIX";
672  strlist << prefix;
673 
674  if (!SendReceiveStringList(strlist, 4))
675  return false;
676 
677  is_complete_valid_channel_on_rec = strlist[1].toInt();
678  is_extra_char_useful = strlist[2].toInt();
679  needed_spacer = (strlist[3] == "X") ? "" : strlist[3];
680 
681  return strlist[0].toInt();
682 }
683 
684 static QString cleanup(const QString &str)
685 {
686  if (str == " ")
687  return "";
688  return str;
689 }
690 
691 static QString make_safe(const QString &str)
692 {
693  if (str.isEmpty())
694  return " ";
695  return str;
696 }
697 
704 void RemoteEncoder::GetNextProgram(int direction,
705  QString &title, QString &subtitle,
706  QString &desc, QString &category,
707  QString &starttime, QString &endtime,
708  QString &callsign, QString &iconpath,
709  QString &channelname, QString &chanid,
710  QString &seriesid, QString &programid)
711 {
712  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
713  strlist << "GET_NEXT_PROGRAM_INFO";
714  strlist << channelname;
715  strlist << chanid;
716  strlist << QString::number(direction);
717  strlist << starttime;
718 
719  if (!SendReceiveStringList(strlist, 12))
720  return;
721 
722  title = cleanup(strlist[0]);
723  subtitle = cleanup(strlist[1]);
724  desc = cleanup(strlist[2]);
725  category = cleanup(strlist[3]);
726  starttime = cleanup(strlist[4]);
727  endtime = cleanup(strlist[5]);
728  callsign = cleanup(strlist[6]);
729  iconpath = cleanup(strlist[7]);
730  channelname = cleanup(strlist[8]);
731  chanid = cleanup(strlist[9]);
732  seriesid = cleanup(strlist[10]);
733  programid = cleanup(strlist[11]);
734 }
735 
737 {
738  QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum));
739  strlist << "GET_CHANNEL_INFO";
740  strlist << QString::number(chanid);
741 
742  if (!SendReceiveStringList(strlist, 6))
743  return;
744 
745  infoMap["chanid"] = cleanup(strlist[0]);
746  infoMap["sourceid"] = cleanup(strlist[1]);
747  infoMap["callsign"] = cleanup(strlist[2]);
748  infoMap["channum"] = cleanup(strlist[3]);
749  infoMap["channame"] = cleanup(strlist[4]);
750  infoMap["XMLTV"] = cleanup(strlist[5]);
751 
752  infoMap["oldchannum"] = infoMap["channum"];
753 }
754 
756 {
757  QStringList strlist( "SET_CHANNEL_INFO" );
758  strlist << make_safe(infoMap["chanid"]);
759  strlist << make_safe(infoMap["sourceid"]);
760  strlist << make_safe(infoMap["oldchannum"]);
761  strlist << make_safe(infoMap["callsign"]);
762  strlist << make_safe(infoMap["channum"]);
763  strlist << make_safe(infoMap["channame"]);
764  strlist << make_safe(infoMap["XMLTV"]);
765 
766  if (SendReceiveStringList(strlist, 1))
767  return strlist[0].toInt();
768 
769  return false;
770 }
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:794
bool Setup(void)
bool CheckChannel(QString channel)
Checks if named channel exists on current tuner.
int restart(void)
Returns milliseconds elapsed since last start() or restart() and resets the count.
Definition: mythtimer.cpp:62
void FrontendReady(void)
void bindValue(const QString &placeholder, const QVariant &val)
Definition: mythdbcon.cpp:875
void GetChannelInfo(InfoMap &infoMap, uint chanid=0)
void CancelNextRecording(bool cancel)
void StopLiveTV(void)
Tells TVRec to stop a "Live TV" recorder.
void ChangeDeinterlacer(int deint_mode)
bool ShouldSwitchToAnotherCard(QString channelid)
Checks if named channel exists on current tuner, or another tuner.
void GetNextProgram(int direction, QString &title, QString &subtitle, QString &desc, QString &category, QString &starttime, QString &endtime, QString &callsign, QString &iconpath, QString &channelname, QString &chanid, QString &seriesid, QString &programid)
Returns information about the program that would be seen if we changed the channel using ChangeChanne...
long long GetFilePosition(void)
Returns total number of bytes written by TVRec's RingBuffer.
int GetPictureAttribute(PictureAttribute attr)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
void FillDurationMap(int64_t start, int64_t end, frm_pos_map_t &durationMap)
MythSocket * controlSock
Definition: remoteencoder.h:85
unsigned int uint
Definition: compat.h:140
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QMap< QString, uint > cachedTimeout
Definition: remoteencoder.h:96
void ToggleChannelFavorite(QString)
static QString make_safe(const QString &str)
QString lastinput
Definition: remoteencoder.h:92
bool isRunning(void) const
Returns true if start() or restart() has been called at least once since construction and since any c...
Definition: mythtimer.cpp:134
long long GetFramesWritten(void)
Returns number of frames written to disk by TVRec's RecorderBase instance.
QVariant value(int i) const
Definition: mythdbcon.h:182
bool IsValidRecorder(void) const
QString remotehost
Definition: remoteencoder.h:88
Holds information on recordings and videos.
Definition: programinfo.h:66
MythSocket * ConnectCommandSocket(const QString &hostname, int port, const QString &announcement, bool *proto_mismatch=nullptr, int maxConnTry=-1, int setup_timeout=-1)
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
static bool IsRequired(const QString &cardtype)
Returns true iff the card type supports signal monitoring.
void FillPositionMap(int64_t start, int64_t end, frm_pos_map_t &positionMap)
bool IsRecording(bool *ok=nullptr)
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
bool isActive(void) const
Definition: mythdbcon.h:188
void SpawnLiveTV(QString chainid, bool pip, QString startchan)
Tells TVRec to Spawn a "Live TV" recorder.
RemoteEncoder(int num, const QString &host, short port)
void SetChannel(QString channel)
float GetFrameRate(void)
Returns recordering frame rate set by nvr.
PictureAttribute
Definition: videoouttypes.h:89
int ChangePictureAttribute(PictureAdjustType type, PictureAttribute attr, bool up)
Changes brightness/contrast/colour/hue of a recording.
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:547
int SetSignalMonitoringRate(int rate, bool notifyFrontend=true)
Sets the signal monitoring rate.
void PauseRecorder(void)
Tells TVRec to pause a recorder, used for channel and input changes.
bool CheckChannelPrefix(const QString &, uint &, bool &, QString &)
Checks a prefix against the channels in the DB.
int elapsed(void) const
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:90
int64_t GetKeyframePosition(uint64_t desired)
Returns byte position in RingBuffer of a keyframe.
bool ReadStringList(QStringList &list, uint timeoutMS=kShortTimeout)
Definition: mythsocket.cpp:332
void StopPlaying(void)
Tells TVRec to stop streaming a recording to the frontend.
QString lastchannel
Definition: remoteencoder.h:91
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:819
#define MAX_SIZE_CHECK
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
PictureAdjustType
Definition: tv.h:120
bool SetChannelInfo(const InfoMap &infoMap)
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:366
ProgramInfo * GetRecording(void)
static const uint kShortTimeout
Definition: mythsocket.h:71
bool SendReceiveStringList(QStringList &strlist, uint min_reply_length=0)
int GetRecorderNumber(void) const
void SetLiveRecording(bool recording)
QString SetInput(QString)
static QString cleanup(const QString &str)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:615
bool WriteStringList(const QStringList &list)
Definition: mythsocket.cpp:320
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:46
long long cachedFramesWritten
Definition: remoteencoder.h:95
long long GetMaxBitrate()
Returns the maximum bits per second this recorder can produce.
void FinishRecording(void)
QString GetHostName(void)
QString GetInput(void)
uint GetSignalLockTimeout(QString input)
MythTimer lastTimeCheck
Definition: remoteencoder.h:97
void ChangeChannel(int channeldirection)
#define LOC