MythTV  master
livetvchain.cpp
Go to the documentation of this file.
1 #include "livetvchain.h"
2 #include "mythcontext.h"
3 #include "mythdb.h"
4 #include "mythlogging.h"
5 #include "programinfo.h"
6 #include "mythsocket.h"
7 #include "cardutil.h"
8 
9 #define LOC QString("LiveTVChain(%1): ").arg(m_id)
10 
11 static inline void clear(LiveTVChainEntry &entry)
12 {
13  entry.chanid = 0;
14  entry.starttime.setSecsSinceEpoch(0);
15  entry.endtime = QDateTime();
16  entry.discontinuity = true;
17  entry.hostprefix = QString();
18  entry.inputtype = QString();
19  entry.channum = QString();
20  entry.inputname = QString();
21 }
22 
27 {
29  LOG(VB_GENERAL, LOG_DEBUG, LOC + "ctor");
30 }
31 
33 {
34  LOG(VB_GENERAL, LOG_DEBUG, LOC + "dtor");
35 }
36 
37 QString LiveTVChain::InitializeNewChain(const QString &seed)
38 {
39  QDateTime curdt = MythDate::current();
40  m_id = QString("live-%1-%2").arg(seed).arg(curdt.toString(Qt::ISODate));
41  return m_id;
42 }
43 
44 void LiveTVChain::SetHostPrefix(const QString &prefix)
45 {
47 }
48 
49 void LiveTVChain::SetInputType(const QString &type)
50 {
51  m_inputType = type;
52 }
53 
54 void LiveTVChain::LoadFromExistingChain(const QString &id)
55 {
56  m_id = id;
57  ReloadAll();
58 }
59 
60 void LiveTVChain::AppendNewProgram(ProgramInfo *pginfo, const QString& channum,
61  const QString& inputname, bool discont)
62 {
63  QMutexLocker lock(&m_lock);
64 
65  LiveTVChainEntry newent;
66  newent.chanid = pginfo->GetChanID();
67  newent.starttime = pginfo->GetRecordingStartTime();
68  newent.endtime = pginfo->GetRecordingEndTime();
69  newent.discontinuity = discont;
70  newent.hostprefix = m_hostPrefix;
71  newent.inputtype = m_inputType;
72  newent.channum = channum;
73  newent.inputname = inputname;
74 
75  m_chain.append(newent);
76 
78  query.prepare("INSERT INTO tvchain (chanid, starttime, endtime, chainid,"
79  " chainpos, discontinuity, watching, hostprefix, cardtype, "
80  " channame, input) "
81  "VALUES(:CHANID, :START, :END, :CHAINID, :CHAINPOS, "
82  " :DISCONT, :WATCHING, :PREFIX, :INPUTTYPE, :CHANNAME, "
83  " :INPUT );");
84  query.bindValue(":CHANID", pginfo->GetChanID());
85  query.bindValue(":START", pginfo->GetRecordingStartTime());
86  query.bindValue(":END", pginfo->GetRecordingEndTime());
87  query.bindValueNoNull(":CHAINID", m_id);
88  query.bindValue(":CHAINPOS", m_maxPos);
89  query.bindValue(":DISCONT", discont);
90  query.bindValue(":WATCHING", 0);
91  query.bindValue(":PREFIX", m_hostPrefix);
92  query.bindValue(":INPUTTYPE", m_inputType);
93  query.bindValue(":CHANNAME", channum);
94  query.bindValue(":INPUT", inputname);
95 
96  if (!query.exec() || !query.isActive())
97  MythDB::DBError("Chain: AppendNewProgram", query);
98  else
99  {
100  LOG(VB_RECORD, LOG_INFO, QString("Chain: Appended@%3 '%1_%2'")
101  .arg(newent.chanid)
103  .arg(m_maxPos));
104  }
105 
106  m_maxPos++;
107  BroadcastUpdate();
108 }
109 
111 {
112  QMutexLocker lock(&m_lock);
113 
115  query.prepare("UPDATE tvchain SET endtime = :END "
116  "WHERE chanid = :CHANID AND starttime = :START ;");
117  query.bindValue(":END", pginfo->GetRecordingEndTime());
118  query.bindValue(":CHANID", pginfo->GetChanID());
119  query.bindValue(":START", pginfo->GetRecordingStartTime());
120 
121  if (!query.exec() || !query.isActive())
122  MythDB::DBError("Chain: FinishedRecording", query);
123  else
124  {
125  LOG(VB_RECORD, LOG_INFO,
126  QString("Chain: Updated endtime for '%1_%2' to %3")
127  .arg(pginfo->GetChanID())
130  }
131 
132  QList<LiveTVChainEntry>::iterator it;
133  for (it = m_chain.begin(); it != m_chain.end(); ++it)
134  {
135  if ((*it).chanid == pginfo->GetChanID() &&
136  (*it).starttime == pginfo->GetRecordingStartTime())
137  {
138  (*it).endtime = pginfo->GetRecordingEndTime();
139  }
140  }
141  BroadcastUpdate();
142 }
143 
145 {
146  QMutexLocker lock(&m_lock);
147 
148  for (auto it = m_chain.begin(); it != m_chain.end(); ++it)
149  {
150  if ((*it).chanid == pginfo->GetChanID() &&
151  (*it).starttime == pginfo->GetRecordingStartTime())
152  {
153  auto del = it;
154  ++it;
155 
157  if (it != m_chain.end())
158  {
159  (*it).discontinuity = true;
160  query.prepare("UPDATE tvchain SET discontinuity = :DISCONT "
161  "WHERE chanid = :CHANID AND starttime = :START "
162  "AND chainid = :CHAINID ;");
163  query.bindValue(":CHANID", (*it).chanid);
164  query.bindValue(":START", (*it).starttime);
165  query.bindValue(":CHAINID", m_id);
166  query.bindValue(":DISCONT", true);
167  if (!query.exec())
168  MythDB::DBError("LiveTVChain::DeleteProgram -- "
169  "discontinuity", query);
170  }
171 
172  query.prepare("DELETE FROM tvchain WHERE chanid = :CHANID "
173  "AND starttime = :START AND chainid = :CHAINID ;");
174  query.bindValue(":CHANID", (*del).chanid);
175  query.bindValue(":START", (*del).starttime);
176  query.bindValue(":CHAINID", m_id);
177  if (!query.exec())
178  MythDB::DBError("LiveTVChain::DeleteProgram -- delete", query);
179 
180  m_chain.erase(del);
181 
182  BroadcastUpdate();
183  break;
184  }
185  }
186 }
187 
189 {
190  QString message = QString("LIVETV_CHAIN UPDATE %1").arg(m_id);
191  MythEvent me(message, entriesToStringList());
192  gCoreContext->dispatch(me);
193 }
194 
196 {
197  QMutexLocker lock(&m_lock);
198 
199  m_chain.clear();
200 
202  query.prepare("DELETE FROM tvchain WHERE chainid = :CHAINID ;");
203  query.bindValue(":CHAINID", m_id);
204 
205  if (!query.exec())
206  MythDB::DBError("LiveTVChain::DestroyChain", query);
207 }
208 
209 void LiveTVChain::ReloadAll(const QStringList &data)
210 {
211  QMutexLocker lock(&m_lock);
212 
213  int prev_size = m_chain.size();
214  if (data.isEmpty() || !entriesFromStringList(data))
215  {
216  m_chain.clear();
217 
219  query.prepare("SELECT chanid, starttime, endtime, discontinuity, "
220  "chainpos, hostprefix, cardtype, channame, input "
221  "FROM tvchain "
222  "WHERE chainid = :CHAINID ORDER BY chainpos;");
223  query.bindValue(":CHAINID", m_id);
224 
225  if (query.exec() && query.isActive() && query.size() > 0)
226  {
227  while (query.next())
228  {
229  LiveTVChainEntry entry;
230  entry.chanid = query.value(0).toUInt();
231  entry.starttime =
232  MythDate::as_utc(query.value(1).toDateTime());
233  entry.endtime =
234  MythDate::as_utc(query.value(2).toDateTime());
235  entry.discontinuity = query.value(3).toBool();
236  entry.hostprefix = query.value(5).toString();
237  entry.inputtype = query.value(6).toString();
238  entry.channum = query.value(7).toString();
239  entry.inputname = query.value(8).toString();
240 
241  m_maxPos = query.value(4).toInt() + 1;
242 
243  m_chain.append(entry);
244  }
245  }
246  }
247 
249  if (m_curPos < 0)
250  m_curPos = 0;
251 
252  if (m_switchId >= 0)
254 
255  if (prev_size > m_chain.size())
256  {
257  LOG(VB_PLAYBACK, LOG_INFO, LOC +
258  QString("ReloadAll(): Removed %1 recording(s)")
259  .arg(prev_size - m_chain.size()));
260  LOG(VB_PLAYBACK, LOG_INFO, LOC + toString());
261  }
262  else if (prev_size < m_chain.size())
263  {
264  LOG(VB_PLAYBACK, LOG_INFO, LOC +
265  QString("ReloadAll(): Added %1 recording(s)")
266  .arg(m_chain.size() - prev_size));
267  LOG(VB_PLAYBACK, LOG_INFO, LOC + toString());
268  }
269 }
270 
271 void LiveTVChain::GetEntryAt(int at, LiveTVChainEntry &entry) const
272 {
273  QMutexLocker lock(&m_lock);
274 
275  int size = m_chain.count();
276  int new_at = (size && (at < 0 || at >= size)) ? size - 1 : at;
277 
278  if (size && new_at >= 0 && new_at < size)
279  entry = m_chain[new_at];
280  else
281  {
282  LOG(VB_GENERAL, LOG_ERR, QString("GetEntryAt(%1) failed.").arg(at));
283  if (at == -1)
284  {
285  LOG(VB_GENERAL, LOG_ERR, "It appears that your backend may "
286  "be misconfigured. Check your backend logs to determine "
287  "whether your inputs, lineups, channels, or storage "
288  "configuration are reporting errors. This issue is commonly "
289  "caused by failing to complete all setup steps properly. You "
290  "may wish to review the documentation for mythtv-setup.");
291  }
292  clear(entry);
293  }
294 }
295 
297 {
298  auto *pginfo = new ProgramInfo(entry.chanid, entry.starttime);
299 
300  if (pginfo->GetChanID())
301  {
302  pginfo->SetPathname(entry.hostprefix + pginfo->GetBasename());
303  return pginfo;
304  }
305 
306  LOG(VB_GENERAL, LOG_ERR,
307  QString("EntryToProgram(%1@%2) failed to get pginfo")
308  .arg(entry.chanid).arg(entry.starttime.toString(Qt::ISODate)));
309  delete pginfo;
310  return nullptr;
311 }
312 
321 {
322  LiveTVChainEntry entry;
323  GetEntryAt(at, entry);
324 
325  return EntryToProgram(entry);
326 }
327 
331 int LiveTVChain::ProgramIsAt(uint chanid, const QDateTime &starttime) const
332 {
333  QMutexLocker lock(&m_lock);
334 
335  int count = 0;
336  QList<LiveTVChainEntry>::const_iterator it;
337  for (it = m_chain.begin(); it != m_chain.end(); ++it, ++count)
338  {
339  if ((*it).chanid == chanid &&
340  (*it).starttime == starttime)
341  {
342  return count;
343  }
344  }
345 
346  return -1;
347 }
348 
352 int LiveTVChain::ProgramIsAt(const ProgramInfo &pginfo) const
353 {
354  return ProgramIsAt(pginfo.GetChanID(), pginfo.GetRecordingStartTime());
355 }
356 
361 {
362  return GetLengthAtPos(m_curPos);
363 }
364 
369 {
370  QMutexLocker lock(&m_lock);
371 
372  LiveTVChainEntry entry = m_chain[pos];
373  if (pos == (m_chain.count() - 1))
374  {
375  // We're on live program, it hasn't ended. Use current time as end time
376  return entry.starttime.secsTo(MythDate::current());
377  }
378 
379  // use begin time from the following program, as it's certain to be right
380  // the end time is set as per the EPG, but should playback be interrupted
381  // such as a channel change, the end value wouldn't have reflected the actual
382  // duration of the program
383  LiveTVChainEntry nextentry = m_chain[pos+1];
384  return entry.starttime.secsTo(nextentry.starttime);
385 }
386 
387 int LiveTVChain::TotalSize(void) const
388 {
389  return m_chain.count();
390 }
391 
393 {
394  QMutexLocker lock(&m_lock);
395 
396  m_curChanId = pginfo.GetChanID();
398 
399  m_curPos = ProgramIsAt(pginfo);
400  if (m_curPos < 0)
401  m_curPos = 0;
402  m_switchId = -1;
403 }
404 
405 bool LiveTVChain::HasNext(void) const
406 {
407  return (m_chain.count() - 1 > m_curPos);
408 }
409 
411 {
412  QMutexLocker lock(&m_lock);
413 
414  m_switchId = -1;
415  m_jumpPos = INT_MAX;
416 }
417 
428 ProgramInfo *LiveTVChain::GetSwitchProgram(bool &discont, bool &newtype,
429  int &newid)
430 {
431  ReloadAll();
432  QMutexLocker lock(&m_lock);
433 
434  int id = m_switchId;
436  discont, newtype);
437  if (pginfo)
438  {
439  newid = id;
440  }
441  ClearSwitch();
442 
443  return pginfo;
444 }
445 
446 ProgramInfo *LiveTVChain::DoGetNextProgram(bool up, int curpos, int &newid,
447  bool &discont, bool &newtype)
448 {
449  LiveTVChainEntry oldentry;
450  LiveTVChainEntry entry;
451  ProgramInfo *pginfo = nullptr;
452 
453  GetEntryAt(curpos, oldentry);
454 
455  if (newid < 0 || curpos == newid)
456  {
457  // already on the program
458  entry = oldentry;
459  pginfo = EntryToProgram(entry);
460  newid = curpos;
461  }
462  else
463  {
464  // try to find recordings during first pass
465  // we'll skip dummy and empty recordings
466  while (!pginfo && newid < m_chain.count() && newid >= 0)
467  {
468  GetEntryAt(newid, entry);
469 
470  bool at_last_entry =
471  ((newid > curpos) &&
472  (newid == m_chain.count()-1)) ||
473  ((newid <= curpos) && (newid == 0));
474 
475  // Skip dummy recordings, if possible.
476  if (at_last_entry || (entry.inputtype != "DUMMY"))
477  pginfo = EntryToProgram(entry);
478 
479  // Skip empty recordings, if possible
480  if (pginfo && (0 == pginfo->GetFilesize()) &&
481  newid < m_chain.count()-1)
482  {
483  LOG(VB_GENERAL, LOG_WARNING,
484  QString("Skipping empty program %1")
485  .arg(pginfo->MakeUniqueKey()));
486  delete pginfo;
487  pginfo = nullptr;
488  }
489 
490  if (!pginfo)
491  {
492  newid += up ? 1 : -1;
493  }
494  }
495 
496  if (!pginfo)
497  {
498  // didn't find in first pass, now get back to the next good one
499  // as this is the one we will use
500  do
501  {
502  newid += up ? -1 : 1;
503 
504  GetEntryAt(newid, entry);
505 
506  bool at_last_entry =
507  ((newid > curpos) &&
508  (newid == m_chain.count()-1)) ||
509  ((newid <= curpos) && (newid == 0));
510 
511  // Skip dummy recordings, if possible.
512  if (at_last_entry || (entry.inputtype != "DUMMY"))
513  pginfo = EntryToProgram(entry);
514 
515  // Skip empty recordings, if possible
516  if (pginfo && (0 == pginfo->GetFilesize()) &&
517  newid < m_chain.count()-1)
518  {
519  LOG(VB_GENERAL, LOG_WARNING,
520  QString("Skipping empty program %1")
521  .arg(pginfo->MakeUniqueKey()));
522  delete pginfo;
523  pginfo = nullptr;
524  }
525  }
526  while (!pginfo && newid < m_chain.count() && newid >= 0);
527 
528  if (!pginfo)
529  {
530  // still not found so abort (will never happen once playback has started)
531  return nullptr;
532  }
533  }
534  }
535 
536  discont = true;
537  if (curpos == newid - 1)
538  discont = entry.discontinuity;
539 
540  newtype = (oldentry.inputtype != entry.inputtype);
541 
542  // Some inputs can change their streams dramatically on a channel change...
543  if (discont)
545 
546  LOG(VB_PLAYBACK, LOG_DEBUG, LOC +
547  QString("DoGetNextProgram: %1 -> ").arg(newid) + pginfo->toString());
548 
549  return pginfo;
550 }
551 
557 {
558  QMutexLocker lock(&m_lock);
559 
560  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("SwitchTo(%1)").arg(num));
561 
562  int size = m_chain.count();
563  if ((num < 0) || (num >= size))
564  num = size - 1;
565 
566  if (m_curPos != num)
567  {
568  m_switchId = num;
570  }
571  else
572  LOG(VB_GENERAL, LOG_ERR, LOC + "SwitchTo() not switching to current");
573 
574  if (VERBOSE_LEVEL_CHECK(VB_PLAYBACK, LOG_DEBUG))
575  {
577  GetEntryAt(num, e);
578  QString msg = QString("%1_%2")
579  .arg(e.chanid)
580  .arg(MythDate::toString(e.starttime, MythDate::kFilename));
581  LOG(VB_PLAYBACK, LOG_DEBUG,
582  LOC + QString("Entry@%1: '%2')").arg(num).arg(msg));
583  }
584 }
585 
592 {
593 #if 0
594  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "SwitchToNext("<<(up?"up":"down")<<")");
595 #endif
596  if (up && HasNext())
597  SwitchTo(m_curPos + 1);
598  else if (!up && HasPrev())
599  SwitchTo(m_curPos - 1);
600 }
601 
602 void LiveTVChain::JumpTo(int num, int pos)
603 {
604  m_jumpPos = pos;
605  SwitchTo(num);
606 }
607 
617 void LiveTVChain::JumpToNext(bool up, int pos)
618 {
619  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("JumpToNext: %1 -> %2").arg(up).arg(pos));
620  if (pos >= 0)
621  {
622  m_jumpPos = pos;
623  SwitchToNext(up);
624  }
625  else
626  {
627  QMutexLocker lock(&m_lock);
628 
629  int current = m_curPos;
630  int switchto = m_curPos;
631  bool discont = false;
632  bool newtype = false;
633 
634  while (current >= 0 && current < m_chain.size())
635  {
636  switchto = current + (up ? 1 : -1);
637 
638  ProgramInfo *pginfo = DoGetNextProgram(up, current, switchto,
639  discont, newtype);
640  delete pginfo;
641 
642  if (switchto == current)
643  {
644  // we've reached the end
645  pos = up ? GetLengthAtPos(switchto) : 0;
646  break;
647  }
648 
649  int duration = GetLengthAtPos(switchto);
650 
651  pos += duration;
652 
653  if (pos >= 0)
654  {
655  if (up)
656  {
657  pos = - (pos - duration);
658  }
659  break;
660  }
661 
662  current = switchto;
663  }
664  m_switchId = switchto;
665  m_jumpPos = pos;
667  }
668 }
669 
674 {
675  int ret = m_jumpPos;
676  m_jumpPos = 0;
677  return ret;
678 }
679 
680 QString LiveTVChain::GetChannelName(int pos) const
681 {
682  LiveTVChainEntry entry;
683  GetEntryAt(pos, entry);
684 
685  return entry.channum;
686 }
687 
688 QString LiveTVChain::GetInputName(int pos) const
689 {
690  LiveTVChainEntry entry;
691  GetEntryAt(pos, entry);
692 
693  return entry.inputname;
694 }
695 
696 QString LiveTVChain::GetInputType(int pos) const
697 {
698  LiveTVChainEntry entry;
699  GetEntryAt(pos, entry);
700 
701  return entry.inputtype;
702 }
703 
705 {
706  QMutexLocker lock(&m_sockLock);
707 
708  if (!m_inUseSocks.contains(sock))
709  m_inUseSocks.append(sock);
710 }
711 
713 {
714  QMutexLocker lock(&m_sockLock);
715  return m_inUseSocks.contains(sock);
716 }
717 
719 {
720  QMutexLocker lock(&m_sockLock);
721  return m_inUseSocks.count();
722 }
723 
725 {
726  QMutexLocker lock(&m_sockLock);
727  m_inUseSocks.removeAll(sock);
728 }
729 
730 static QString toString(const LiveTVChainEntry &v)
731 {
732  return QString("%1: %2 (%3 to %4)%5")
733  .arg(v.inputtype,6).arg(v.chanid,4)
734  .arg(v.starttime.time().toString())
735  .arg(v.endtime.time().toString())
736  .arg(v.discontinuity?" discontinuous":"");
737 }
738 
739 QString LiveTVChain::toString() const
740 {
741  QMutexLocker lock(&m_lock);
742  QString ret = QString("LiveTVChain has %1 entries\n").arg(m_chain.size());
743  for (uint i = 0; i < (uint)m_chain.size(); i++)
744  {
745  ret += (QString((i==(uint)m_curPos) ? "* " : " ") +
746  ::toString(m_chain[i]) + "\n");
747  }
748  return ret;
749 }
750 
752 {
753  QMutexLocker lock(&m_lock);
754  QStringList ret;
755  ret << QString::number(m_maxPos);
756  for (const auto & entry : qAsConst(m_chain))
757  {
758  ret << QString::number(entry.chanid);
759  ret << entry.starttime.toString(Qt::ISODate);
760  ret << entry.endtime.toString(Qt::ISODate);
761  ret << QString::number(static_cast<int>(entry.discontinuity));
762  ret << entry.hostprefix;
763  ret << entry.inputtype;
764  ret << entry.channum;
765  ret << entry.inputname;
766  }
767  return ret;
768 }
769 
770 bool LiveTVChain::entriesFromStringList(const QStringList &items)
771 {
772  int numItems = items.size();
773  QList<LiveTVChainEntry> chain;
774  int itemIdx = 0;
775  int maxpos = 0;
776  bool ok = false;
777  if (itemIdx < numItems)
778  maxpos = items[itemIdx++].toInt(&ok);
779  while (ok && itemIdx < numItems)
780  {
781  LiveTVChainEntry entry;
782  entry.chanid = items[itemIdx++].toUInt(&ok);
783  if (ok && itemIdx < numItems)
784  {
785  entry.starttime =
786  QDateTime::fromString(items[itemIdx++], Qt::ISODate);
787  ok = entry.starttime.isValid();
788  }
789  if (ok && itemIdx < numItems)
790  {
791  entry.endtime =
792  QDateTime::fromString(items[itemIdx++], Qt::ISODate);
793  ok = entry.endtime.isValid();
794  }
795  if (ok && itemIdx < numItems)
796  entry.discontinuity = (items[itemIdx++].toInt(&ok) != 0);
797  if (ok && itemIdx < numItems)
798  entry.hostprefix = items[itemIdx++];
799  if (ok && itemIdx < numItems)
800  entry.inputtype = items[itemIdx++];
801  if (ok && itemIdx < numItems)
802  entry.channum = items[itemIdx++];
803  if (ok && itemIdx < numItems)
804  entry.inputname = items[itemIdx++];
805  if (ok)
806  chain.append(entry);
807  }
808  if (ok)
809  {
810  QMutexLocker lock(&m_lock);
811  m_maxPos = maxpos;
812  m_chain = chain;
813  }
814  else
815  {
816  LOG(VB_PLAYBACK, LOG_INFO,
817  QString("Failed to deserialize TVChain - ") + items.join("|"));
818  }
819  return ok;
820 }
LiveTVChain::DestroyChain
void DestroyChain(void)
Definition: livetvchain.cpp:195
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:204
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1420
LiveTVChain::SwitchTo
void SwitchTo(int num)
Sets the recording to switch to.
Definition: livetvchain.cpp:556
ProgramInfo::MakeUniqueKey
QString MakeUniqueKey(void) const
Creates a unique string that can be used to identify an existing recording.
Definition: programinfo.h:337
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:80
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:203
MSqlQuery::bindValueNoNull
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
Definition: mythdbcon.cpp:869
LiveTVChain::~LiveTVChain
~LiveTVChain() override
Definition: livetvchain.cpp:32
ProgramInfo::GetFilesize
virtual uint64_t GetFilesize(void) const
Definition: programinfo.cpp:6154
LiveTVChain::JumpTo
void JumpTo(int num, int pos)
Definition: livetvchain.cpp:602
mythdb.h
MythDate::as_utc
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:23
LiveTVChain::HasNext
bool HasNext(void) const
Definition: livetvchain.cpp:405
LiveTVChain::EntryToProgram
static ProgramInfo * EntryToProgram(const LiveTVChainEntry &entry)
Definition: livetvchain.cpp:296
LiveTVChain::GetLengthAtCurPos
int GetLengthAtCurPos(void)
Definition: livetvchain.cpp:360
LOC
#define LOC
Definition: livetvchain.cpp:9
LiveTVChain::GetChannelName
QString GetChannelName(int pos=-1) const
Definition: livetvchain.cpp:680
LiveTVChain::LoadFromExistingChain
void LoadFromExistingChain(const QString &id)
Definition: livetvchain.cpp:54
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:17
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:198
arg
arg(title).arg(filename).arg(doDelete))
LiveTVChain::m_chain
QList< LiveTVChainEntry > m_chain
Definition: livetvchain.h:107
LiveTVChain::TotalSize
int TotalSize(void) const
Definition: livetvchain.cpp:387
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
LiveTVChainEntry::channum
QString channum
Definition: livetvchain.h:27
LiveTVChain::m_curStartTs
QDateTime m_curStartTs
Definition: livetvchain.h:116
LiveTVChain::HostSocketCount
uint HostSocketCount(void) const
Definition: livetvchain.cpp:718
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
ProgramInfo::GetRecordingEndTime
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
Definition: programinfo.h:410
LiveTVChainEntry::endtime
QDateTime endtime
Definition: livetvchain.h:23
LiveTVChain::GetEntryAt
void GetEntryAt(int at, LiveTVChainEntry &entry) const
Definition: livetvchain.cpp:271
hardwareprofile.distros.mythtv_data.data_mythtv.prefix
string prefix
Definition: data_mythtv.py:40
LiveTVChain::DelHostSocket
void DelHostSocket(MythSocket *sock)
Definition: livetvchain.cpp:724
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
ProgramInfo::GetRecordingStartTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:402
LiveTVChainEntry::starttime
QDateTime starttime
Definition: livetvchain.h:22
LiveTVChain::LiveTVChain
LiveTVChain()
Definition: livetvchain.cpp:26
LiveTVChain::BroadcastUpdate
void BroadcastUpdate()
Definition: livetvchain.cpp:188
LiveTVChain::GetProgramAt
ProgramInfo * GetProgramAt(int at) const
Returns program at the desired location.
Definition: livetvchain.cpp:320
MythSocket
Class for communcating between myth backends and frontends.
Definition: mythsocket.h:27
LiveTVChain::IsHostSocket
bool IsHostSocket(MythSocket *sock)
Definition: livetvchain.cpp:712
LiveTVChain::m_inUseSocks
QList< MythSocket * > m_inUseSocks
Definition: livetvchain.h:124
programinfo.h
LiveTVChain::JumpToNext
void JumpToNext(bool up, int pos)
JumpToNext(bool up, int pos) jump to the next (up == true) or previous (up == false) liveTV program I...
Definition: livetvchain.cpp:617
clear
static void clear(LiveTVChainEntry &entry)
Definition: livetvchain.cpp:11
mythlogging.h
LiveTVChain::SetHostPrefix
void SetHostPrefix(const QString &prefix)
Definition: livetvchain.cpp:44
CardUtil::IsChannelChangeDiscontinuous
static bool IsChannelChangeDiscontinuous(const QString &rawtype)
Definition: cardutil.h:146
MythDate::kFilename
@ kFilename
Default UTC, "yyyyMMddhhmmss".
Definition: mythdate.h:15
toString
static QString toString(const LiveTVChainEntry &v)
Definition: livetvchain.cpp:730
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
LiveTVChain::SetHostSocket
void SetHostSocket(MythSocket *sock)
Definition: livetvchain.cpp:704
LiveTVChain::SetInputType
void SetInputType(const QString &type)
Definition: livetvchain.cpp:49
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:178
LiveTVChain::m_id
QString m_id
Definition: livetvchain.h:106
LiveTVChain::m_jumpPos
int m_jumpPos
Definition: livetvchain.h:121
LiveTVChain::GetSwitchProgram
ProgramInfo * GetSwitchProgram(bool &discont, bool &newtype, int &newid)
Returns the recording we should switch to.
Definition: livetvchain.cpp:428
LiveTVChain::m_hostPrefix
QString m_hostPrefix
Definition: livetvchain.h:111
ProgramInfo::toString
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
Definition: programinfo.cpp:1825
LiveTVChainEntry::inputtype
QString inputtype
Definition: livetvchain.h:26
LiveTVChain::m_inputType
QString m_inputType
Definition: livetvchain.h:112
LiveTVChain::m_curChanId
uint m_curChanId
Definition: livetvchain.h:115
LiveTVChain::ReloadAll
void ReloadAll(const QStringList &data=QStringList())
Definition: livetvchain.cpp:209
LiveTVChain::m_lock
QMutex m_lock
Definition: livetvchain.h:109
uint
unsigned int uint
Definition: compat.h:140
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:56
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:30
LiveTVChain::InitializeNewChain
QString InitializeNewChain(const QString &seed)
Definition: livetvchain.cpp:37
LiveTVChain::GetLengthAtPos
int GetLengthAtPos(int pos)
Definition: livetvchain.cpp:368
LiveTVChainEntry::hostprefix
QString hostprefix
Definition: livetvchain.h:25
LiveTVChain::m_curPos
int m_curPos
Definition: livetvchain.h:114
LiveTVChain::entriesToStringList
QStringList entriesToStringList() const
Definition: livetvchain.cpp:751
LiveTVChain::GetInputType
QString GetInputType(int pos=-1) const
Definition: livetvchain.cpp:696
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:370
LiveTVChainEntry::discontinuity
bool discontinuity
Definition: livetvchain.h:24
livetvchain.h
VERBOSE_LEVEL_CHECK
#define VERBOSE_LEVEL_CHECK(_MASK_, _LEVEL_)
Definition: mythlogging.h:14
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:68
LiveTVChain::m_switchId
int m_switchId
Definition: livetvchain.h:118
LiveTVChain::m_switchEntry
LiveTVChainEntry m_switchEntry
Definition: livetvchain.h:119
cardutil.h
LiveTVChain::SwitchToNext
void SwitchToNext(bool up)
Sets the recording to switch to.
Definition: livetvchain.cpp:591
LiveTVChain::m_sockLock
QMutex m_sockLock
Definition: livetvchain.h:123
LiveTVChainEntry::chanid
uint chanid
Definition: livetvchain.h:21
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:14
LiveTVChain::toString
QString toString() const
Definition: livetvchain.cpp:739
mythcontext.h
LiveTVChain::AppendNewProgram
void AppendNewProgram(ProgramInfo *pginfo, const QString &channum, const QString &inputname, bool discont)
Definition: livetvchain.cpp:60
LiveTVChainEntry::inputname
QString inputname
Definition: livetvchain.h:28
LiveTVChain::SetProgram
void SetProgram(const ProgramInfo &pginfo)
Definition: livetvchain.cpp:392
LiveTVChain::DoGetNextProgram
ProgramInfo * DoGetNextProgram(bool up, int curpos, int &newid, bool &discont, bool &newtype)
Definition: livetvchain.cpp:446
LiveTVChain::GetJumpPos
int GetJumpPos(void)
Returns the jump position in seconds and clears it.
Definition: livetvchain.cpp:673
LiveTVChainEntry
Definition: livetvchain.h:20
LiveTVChain::HasPrev
bool HasPrev(void) const
Definition: livetvchain.h:61
LiveTVChain::m_maxPos
int m_maxPos
Definition: livetvchain.h:108
LiveTVChain::GetInputName
QString GetInputName(int pos=-1) const
Definition: livetvchain.cpp:688
LiveTVChain::entriesFromStringList
bool entriesFromStringList(const QStringList &items)
Definition: livetvchain.cpp:770
mythsocket.h
LiveTVChain::ProgramIsAt
int ProgramIsAt(uint chanid, const QDateTime &starttime) const
Definition: livetvchain.cpp:331
query
MSqlQuery query(MSqlQuery::InitCon())
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1730
LiveTVChain::DeleteProgram
void DeleteProgram(ProgramInfo *pginfo)
Definition: livetvchain.cpp:144
ReferenceCounter
General purpose reference counter.
Definition: referencecounter.h:27
LiveTVChain::ClearSwitch
void ClearSwitch(void)
Definition: livetvchain.cpp:410
LiveTVChain::FinishedRecording
void FinishedRecording(ProgramInfo *pginfo)
Definition: livetvchain.cpp:110
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808