MythTV  master
playercontext.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <utility>
3 
4 #include <QPainter>
5 
6 #include "mythconfig.h"
7 
8 #include "playercontext.h"
9 #include "mythplayer.h"
10 #include "remoteencoder.h"
11 #include "livetvchain.h"
12 #include "ringbuffer.h"
13 #include "playgroup.h"
14 #include "videoouttypes.h"
15 #include "storagegroup.h"
16 #include "mythcorecontext.h"
17 #include "videometadatautil.h"
18 #include "metadataimagehelper.h"
19 #include "mythlogging.h"
20 #include "DVD/mythdvdplayer.h"
21 #include "Bluray/mythbdplayer.h"
22 #include "channelutil.h"
23 #include "tv_play.h"
24 
25 #define LOC QString("playCtx: ")
26 
29 
30 PlayerContext::PlayerContext(QString inUseID) :
31  m_recUsage(std::move(inUseID))
32 {
35 }
36 
38 {
40  m_nextState.clear();
41 }
42 
44 {
45  m_ffRewState = 0;
46  m_ffRewIndex = 0;
47  m_ffRewSpeed = 0;
48  m_tsNormal = 1.0F;
49 
50  SetPlayer(nullptr);
51  SetRecorder(nullptr);
52  SetRingBuffer(nullptr);
53  SetTVChain(nullptr);
54  SetPlayingInfo(nullptr);
55 }
56 
62 {
63  TVState newState = kState_None;
64  QString newPlaygroup("Default");
65 
66  LockPlayingInfo(__FILE__, __LINE__);
67  if (islivetv)
68  {
69  SetTVChain(new LiveTVChain());
70  newState = kState_WatchingLiveTV;
71  }
72  else if (m_playingInfo)
73  {
74  int overrecordseconds = gCoreContext->GetNumSetting("RecordOverTime");
75  QDateTime curtime = MythDate::current();
76  QDateTime recendts = m_playingInfo->GetRecordingEndTime()
77  .addSecs(overrecordseconds);
78 
80  {
81  newState = (curtime < recendts) ?
83  }
84  else if (m_playingInfo->IsVideoDVD())
85  newState = kState_WatchingDVD;
86  else if (m_playingInfo->IsVideoBD())
87  newState = kState_WatchingBD;
88  else
89  newState = kState_WatchingVideo;
90 
91  newPlaygroup = m_playingInfo->GetPlaybackGroup();
92  }
93  UnlockPlayingInfo(__FILE__, __LINE__);
94 
95  ChangeState(newState);
96  SetPlayGroup(newPlaygroup);
97 }
98 
105 {
106  bool supported = false;
107  QMutexLocker locker(&m_deletePlayerLock);
108  if (m_player)
109  {
110  const MythVideoOutput *vid = m_player->GetVideoOutput();
111  if (vid)
112  supported = vid->IsPIPSupported();
113  }
114  return supported;
115 }
116 
123 {
124  bool supported = false;
125  QMutexLocker locker(&m_deletePlayerLock);
126  if (m_player)
127  {
128  const MythVideoOutput *vid = m_player->GetVideoOutput();
129  if (vid)
130  supported = vid->IsPBPSupported();
131  }
132  return supported;
133 }
134 
135 void PlayerContext::CreatePIPWindow(const QRect &rect, int pos,
136  QWidget *widget)
137 {
138  QString name;
139  if (pos > -1)
140  {
141  m_pipLocation = pos;
142  name = QString("pip player %1").arg(toString((PIPLocation)pos));
143  }
144  else
145  name = "pip player";
146 
147  if (widget)
148  m_parentWidget = widget;
149 
150  m_pipRect = QRect(rect);
151 }
152 
158 {
159  QRect rect = QRect(0, 0, 0, 0);
160  QMutexLocker locker(&m_deletePlayerLock);
161  if (m_player)
162  {
163  rect = m_pipRect;
164 
165  float saspect = (float)rect.width() / (float)rect.height();
166  float vaspect = m_player->GetVideoAspect();
167 
168  // Calculate new height or width according to relative aspect ratio
169  if (lroundf(saspect * 10) > lroundf(vaspect * 10))
170  {
171  rect.setWidth((int) ceil(rect.width() * (vaspect / saspect)));
172  }
173  else if (lroundf(saspect * 10) < lroundf(vaspect * 10))
174  {
175  rect.setHeight((int) ceil(rect.height() * (saspect / vaspect)));
176  }
177 
178  rect.setHeight(((rect.height() + 7) / 8) * 8);
179  rect.setWidth( ((rect.width() + 7) / 8) * 8);
180  }
181  return rect;
182 }
183 
184 bool PlayerContext::StartPIPPlayer(TV *tv, TVState desiredState)
185 {
186  bool ok = false;
187 
189  {
190  const QRect rect = m_pipRect;
191  ok = CreatePlayer(tv, m_parentWidget, desiredState,
192  true, rect);
193  }
194 
195  if (m_useNullVideo || !ok)
196  {
197  SetPlayer(nullptr);
198  m_useNullVideo = true;
199  ok = CreatePlayer(tv, nullptr, desiredState,
200  false);
201  }
202 
203  return ok;
204 }
205 
206 
213 {
214  if (m_buffer)
215  {
216  m_buffer->Pause();
218  }
219 
220  {
221  QMutexLocker locker(&m_deletePlayerLock);
222  StopPlaying();
223  }
224 
225  SetPlayer(nullptr);
226 
227  m_useNullVideo = false;
228  m_parentWidget = nullptr;
229 }
230 
234 void PlayerContext::ResizePIPWindow(const QRect &rect)
235 {
236  if (!IsPIP())
237  return;
238 
239  QRect tmpRect;
240  if (m_pipState == kPIPStandAlone)
241  tmpRect = GetStandAlonePIPRect();
242  else
243  tmpRect = QRect(rect);
244 
245  LockDeletePlayer(__FILE__, __LINE__);
246  if (m_player && m_player->GetVideoOutput())
247  m_player->GetVideoOutput()->ResizeDisplayWindow(tmpRect, false);
248  UnlockDeletePlayer(__FILE__, __LINE__);
249 
250  m_pipRect = QRect(rect);
251 }
252 
253 bool PlayerContext::StartEmbedding(const QRect &embedRect)
254 {
255  bool ret = false;
256  LockDeletePlayer(__FILE__, __LINE__);
257  if (m_player)
258  {
259  ret = true;
260  m_player->EmbedInWidget(embedRect);
261  }
262  UnlockDeletePlayer(__FILE__, __LINE__);
263  return ret;
264 }
265 
267 {
268  bool ret = false;
269  LockDeletePlayer(__FILE__, __LINE__);
270  if (m_player)
271  ret = m_player->IsEmbedding();
272  UnlockDeletePlayer(__FILE__, __LINE__);
273  return ret;
274 }
275 
277 {
278  LockDeletePlayer(__FILE__, __LINE__);
279  if (m_player)
281  UnlockDeletePlayer(__FILE__, __LINE__);
282 }
283 
284 bool PlayerContext::HasPlayer(void) const
285 {
286  QMutexLocker locker(&m_deletePlayerLock);
287  return m_player;
288 }
289 
291 {
292  QMutexLocker locker(&m_deletePlayerLock);
293  return m_player && m_player->IsErrored();
294 }
295 
297 {
298  QMutexLocker locker(&m_deletePlayerLock);
299  return m_player && m_player->IsPlaying();
300 }
301 
303 {
304  QMutexLocker locker(&m_deletePlayerLock);
306  {
307  m_ffRewSpeed = 0;
308  m_ffRewState = 0;
310  return true;
311  }
312  return false;
313 }
314 
316 {
317  QMutexLocker locker(&m_deletePlayerLock);
318  if (m_player && (m_player->GetNextPlaySpeed() != m_tsNormal) &&
320  {
321  // Speed got changed in player since we are close to the end of file
322  m_tsNormal = 1.0F;
323  return true;
324  }
325  return false;
326 }
327 
329  bool paddedFields) const
330 {
331  QMutexLocker locker(&m_deletePlayerLock);
332  if (m_player)
333  {
334  m_player->calcSliderPos(info, paddedFields);
335  return true;
336  }
337  return false;
338 }
339 
341 {
342  return m_recorder && m_recorder->GetErrorStatus();
343 }
344 
345 bool PlayerContext::CreatePlayer(TV *tv, QWidget *widget,
346  TVState desiredState,
347  bool embed, const QRect &embedbounds,
348  bool muted)
349 {
350  if (HasPlayer())
351  {
352  LOG(VB_GENERAL, LOG_ERR, LOC +
353  "Attempting to setup a player, but it already exists.");
354  return false;
355  }
356 
357  uint playerflags = kDecodeAllowEXT; // allow VDA etc for normal playback
358  playerflags |= muted ? kAudioMuted : kNoFlags;
359  playerflags |= m_useNullVideo ? kVideoIsNull : kNoFlags;
360  playerflags |= m_nohardwaredecoders ? kNoFlags : kDecodeAllowGPU;
361 
362  MythPlayer *player = nullptr;
363  if (kState_WatchingBD == desiredState)
364  player = new MythBDPlayer((PlayerFlags)playerflags);
365  else if (kState_WatchingDVD == desiredState)
366  player = new MythDVDPlayer((PlayerFlags)playerflags);
367  else
368  player = new MythPlayer((PlayerFlags)playerflags);
369 
370  QString passthru_device =
371  gCoreContext->GetBoolSetting("PassThruDeviceOverride", false) ?
372  gCoreContext->GetSetting("PassThruOutputDevice") : QString();
373 
374  player->SetPlayerInfo(tv, widget, this);
375  AudioPlayer *audio = player->GetAudio();
376  audio->SetAudioInfo(gCoreContext->GetSetting("AudioOutputDevice"),
377  passthru_device,
378  gCoreContext->GetNumSetting("AudioSampleRate", 44100));
380  player->SetLength(m_playingLen);
381 
383  0, gCoreContext->GetNumSetting("AudioSyncOffset", 0));
384 
385  bool isWatchingRecording = (desiredState == kState_WatchingRecording);
386  player->SetWatchingRecording(isWatchingRecording);
387 
388  if (!IsAudioNeeded())
389  audio->SetNoAudio();
390  else
391  {
392  QString subfn = m_buffer->GetSubtitleFilename();
393  bool isInProgress = (desiredState == kState_WatchingRecording ||
394  desiredState == kState_WatchingLiveTV);
395  if (!subfn.isEmpty() && player->GetSubReader())
396  player->GetSubReader()->LoadExternalSubtitles(subfn, isInProgress);
397  }
398 
399  if (embed && !embedbounds.isNull())
400  player->EmbedInWidget(embedbounds);
401 
402  SetPlayer(player);
403 
404  if (m_pipState == kPIPOff || m_pipState == kPBPLeft)
405  {
406  if (IsAudioNeeded())
407  {
408  // cppcheck-suppress unreadVariable
409  QString errMsg = audio->ReinitAudio();
410  }
411  }
412  else if (m_pipState == kPBPRight)
413  player->SetMuted(true);
414 
415  return StartPlaying(-1);
416 }
417 
424 {
425  if (!m_player)
426  return false;
427 
428  if (!m_player->StartPlaying())
429  {
430  LOG(VB_GENERAL, LOG_ERR, LOC + "StartPlaying() Failed to start player");
431  // no need to call StopPlaying here as the player context will be deleted
432  // later following the error
433  return false;
434  }
435  maxWait = (maxWait <= 0) ? 20000 : maxWait;
436 #ifdef USING_VALGRIND
437  maxWait = (1<<30);
438 #endif // USING_VALGRIND
439  MythTimer t;
440  t.start();
441 
442  while (!m_player->IsPlaying(50, true) && (t.elapsed() < maxWait))
443  ReloadTVChain();
444 
445  if (m_player->IsPlaying())
446  {
447  LOG(VB_PLAYBACK, LOG_INFO, LOC +
448  QString("StartPlaying(): took %1 ms to start player.")
449  .arg(t.elapsed()));
450  return true;
451  }
452  LOG(VB_GENERAL, LOG_ERR, LOC + "StartPlaying() Failed to start player");
453  StopPlaying();
454  return false;
455 }
456 
458 {
459  if (m_player)
461 }
462 
463 void PlayerContext::UpdateTVChain(const QStringList &data)
464 {
465  QMutexLocker locker(&m_deletePlayerLock);
466  if (m_tvchain && m_player)
467  {
468  m_tvchain->ReloadAll(data);
470  }
471 }
472 
474 {
475  if (!m_tvchain)
476  return false;
477 
478  m_tvchain->ReloadAll();
479  ProgramInfo *pinfo = m_tvchain->GetProgramAt(-1);
480  if (pinfo)
481  {
482  SetPlayingInfo(pinfo);
483  delete pinfo;
484  return true;
485  }
486  return false;
487 }
488 
493 {
494  if (!m_tvchain)
495  return;
496 
497  // Don't store more than kMaxChannelHistory channels. Remove the first item
498  if (m_prevChan.size() >= kMaxChannelHistory)
499  m_prevChan.pop_front();
500 
501  // This method builds the stack of previous channels
502  QString curChan = m_tvchain->GetChannelName(-1);
503  if (m_prevChan.empty() ||
504  curChan != m_prevChan[m_prevChan.size() - 1])
505  {
506  const QString& chan = curChan;
507  m_prevChan.push_back(chan);
508  }
509 }
510 
512 {
513  if (m_prevChan.empty())
514  return QString();
515 
516  QString curChan = m_tvchain->GetChannelName(-1);
517  if ((curChan == m_prevChan.back()) && !m_prevChan.empty())
518  m_prevChan.pop_back();
519 
520  if (m_prevChan.empty())
521  return QString();
522 
523  QString chan = m_prevChan.back();
524  m_prevChan.pop_back();
525  // add the current channel back to the list, to allow easy flipping between
526  // two channels using PREVCHAN
528  return chan;
529 }
530 
532 {
533  if (m_prevChan.empty())
534  return QString();
535 
536  QString curChan = m_tvchain->GetChannelName(-1);
537  QString preChan;
538  if (curChan != m_prevChan.back() || m_prevChan.size() < 2)
539  preChan = m_prevChan.back();
540  else
541  preChan = m_prevChan[m_prevChan.size()-2];
542  return preChan;
543 }
544 
545 void PlayerContext::LockPlayingInfo(const char *file, int line) const
546 {
547 #if 0
548  LOG(VB_GENERAL, LOG_DEBUG, QString("LockPlayingInfo(%1,%2)")
549  .arg(file).arg(line));
550 #else
551  Q_UNUSED(file);
552  Q_UNUSED(line);
553 #endif
554  m_playingInfoLock.lock();
555 }
556 
557 void PlayerContext::UnlockPlayingInfo(const char *file, int line) const
558 {
559 #if 0
560  LOG(VB_GENERAL, LOG_DEBUG, QString("UnlockPlayingInfo(%1,%2)")
561  .arg(file).arg(line));
562 #else
563  Q_UNUSED(file);
564  Q_UNUSED(line);
565 #endif
566  m_playingInfoLock.unlock();
567 }
568 
574 void PlayerContext::LockDeletePlayer(const char *file, int line) const
575 {
576 #if 0
577  LOG(VB_GENERAL, LOG_DEBUG, QString("LockDeletePlayer(%1,%2)")
578  .arg(file).arg(line));
579 #else
580  Q_UNUSED(file);
581  Q_UNUSED(line);
582 #endif
583  m_deletePlayerLock.lock();
584 }
585 
589 void PlayerContext::UnlockDeletePlayer(const char *file, int line) const
590 {
591 #if 0
592  LOG(VB_GENERAL, LOG_DEBUG, QString("UnlockDeletePlayer(%1,%2)")
593  .arg(file).arg(line));
594 #else
595  Q_UNUSED(file);
596  Q_UNUSED(line);
597 #endif
598  m_deletePlayerLock.unlock();
599 }
600 
601 void PlayerContext::LockState(void) const
602 {
603  m_stateLock.lock();
604 }
605 
607 {
608  m_stateLock.unlock();
609 }
610 
612 {
613  m_player->LockOSD();
614 }
615 
616 void PlayerContext::UnlockOSD(void) const
617 {
618  m_player->UnlockOSD();
619 }
620 
622 {
623  if (!m_stateLock.tryLock())
624  return true;
625  bool inStateChange = !m_nextState.empty();
626  m_stateLock.unlock();
627  return inStateChange;
628 }
629 
634 {
635  QMutexLocker locker(&m_stateLock);
636  m_nextState.enqueue(newState);
637 }
638 
640 {
641  QMutexLocker locker(&m_stateLock);
642  return m_nextState.dequeue();
643 }
644 
649 {
650  QMutexLocker locker(&m_stateLock);
651  m_nextState.clear();
652  m_nextState.push_back(kState_None);
653 }
654 
656 {
657  QMutexLocker locker(&m_stateLock);
658  return m_playingState;
659 }
660 
662 {
663  bool loaded = false;
664  LockPlayingInfo(__FILE__, __LINE__);
665  if (m_playingInfo)
666  {
667  m_playingInfo->ToMap(infoMap);
668  infoMap["tvstate"] = StateToString(m_playingState);
669  infoMap["iconpath"] = ChannelUtil::GetIcon(m_playingInfo->GetChanID());
673  {
674  infoMap["coverartpath"] = VideoMetaDataUtil::GetArtPath(
675  m_playingInfo->GetPathname(), "Coverart");
676  infoMap["fanartpath"] = VideoMetaDataUtil::GetArtPath(
677  m_playingInfo->GetPathname(), "Fanart");
678  infoMap["bannerpath"] = VideoMetaDataUtil::GetArtPath(
679  m_playingInfo->GetPathname(), "Banners");
680  infoMap["screenshotpath"] = VideoMetaDataUtil::GetArtPath(
681  m_playingInfo->GetPathname(), "Screenshots");
682  }
683  else
684  {
687  infoMap["coverartpath"] =
688  artmap.value(kArtworkCoverart).url;
689  infoMap["fanartpath"] =
690  artmap.value(kArtworkFanart).url;
691  infoMap["bannerpath"] =
692  artmap.value(kArtworkBanner).url;
693  infoMap["screenshotpath"] =
694  artmap.value(kArtworkScreenshot).url;
695  }
696  if (m_player)
697  m_player->GetCodecDescription(infoMap);
698 
699  loaded = true;
700  }
701  UnlockPlayingInfo(__FILE__, __LINE__);
702  return loaded;
703 }
704 
706 {
707  bool ret = false;
708  LockPlayingInfo(__FILE__, __LINE__);
709  if (m_playingInfo)
710  ret = m_playingInfo->IsSameProgram(p);
711  UnlockPlayingInfo(__FILE__, __LINE__);
712  return ret;
713 }
714 
715 QString PlayerContext::GetFilters(const QString &baseFilters) const
716 {
717  QString filters = baseFilters;
718  QString chanFilters;
719 
721  return baseFilters;
722 
723  LockPlayingInfo(__FILE__, __LINE__);
724  if (m_playingInfo) // Recordings have this info already.
725  chanFilters = m_playingInfo->GetChannelPlaybackFilters();
726  UnlockPlayingInfo(__FILE__, __LINE__);
727 
728  if (!chanFilters.isEmpty())
729  {
730  if ((chanFilters[0] != '+'))
731  {
732  filters = chanFilters;
733  }
734  else
735  {
736  if (!filters.isEmpty() && (!filters.endsWith(",")))
737  filters += ",";
738 
739  filters += chanFilters.mid(1);
740  }
741  }
742 
743  LOG(VB_CHANNEL, LOG_INFO, LOC +
744  QString("Output filters for this channel are: '%1'")
745  .arg(filters));
746 
747  return filters;
748 }
749 
750 QString PlayerContext::GetPlayMessage(void) const
751 {
752  QString mesg = QObject::tr("Play");
753  if (m_tsNormal != 1.0F)
754  {
755  if (m_tsNormal == 0.5F)
756  mesg += QString(" 1/2x");
757  else if (0.32F < m_tsNormal && m_tsNormal < 0.34F)
758  mesg += QString(" 1/3x");
759  else if (m_tsNormal == 0.25F)
760  mesg += QString(" 1/4x");
761  else if (m_tsNormal == 0.125F)
762  mesg += QString(" 1/8x");
763  else if (m_tsNormal == 0.0625F)
764  mesg += QString(" 1/16x");
765  else
766  mesg += QString(" %1x").arg(m_tsNormal);
767  }
768 
769  return mesg;
770 }
771 
773 {
774  QMutexLocker locker(&m_deletePlayerLock);
775  if (m_player)
776  {
777  StopPlaying();
778  delete m_player;
779  }
780  m_player = newplayer;
781 }
782 
784 {
785  if (m_recorder)
786  {
787  delete m_recorder;
788  m_recorder = nullptr;
789  }
790 
791  if (rec)
792  {
793  m_recorder = rec;
795  }
796 }
797 
799 {
800  if (m_tvchain)
801  {
803  m_tvchain->DecrRef();
804  m_tvchain = nullptr;
805  }
806 
807  m_tvchain = chain;
808 
809  if (m_tvchain)
810  {
811 #if 0
812  QString seed = QString("");
813 
814  if (IsPIP())
815  seed = "PIP";
816 
817  seed += gCoreContext->GetHostName();
818 #endif
820  }
821 }
822 
824 {
825  if (m_buffer)
826  {
827  delete m_buffer;
828  m_buffer = nullptr;
829  }
830 
831  m_buffer = buf;
832 }
833 
838 {
839  bool ignoreDB = gCoreContext->IsDatabaseIgnored();
840 
841  QMutexLocker locker(&m_playingInfoLock);
842 
843  if (m_playingInfo)
844  {
845  if (!ignoreDB)
847  delete m_playingInfo;
848  m_playingInfo = nullptr;
849  }
850 
851  if (info)
852  {
853  m_playingInfo = new ProgramInfo(*info);
854  if (!ignoreDB)
857  }
858 }
859 
860 void PlayerContext::SetPlayGroup(const QString &group)
861 {
862  m_fftime = PlayGroup::GetSetting(group, "skipahead", 30);
863  m_rewtime = PlayGroup::GetSetting(group, "skipback", 5);
864  m_jumptime = PlayGroup::GetSetting(group, "jump", 10);
865  m_tsNormal = PlayGroup::GetSetting(group, "timestretch", 100) * 0.01F;
866  m_tsAlt = (m_tsNormal == 1.0F) ? 1.5F : 1.0F;
867 }
868 
870  const ProgramInfo *pi, PseudoState new_state)
871 {
872  ProgramInfo *old_rec = m_pseudoLiveTVRec;
873  ProgramInfo *new_rec = nullptr;
874 
875  if (pi)
876  {
877  new_rec = new ProgramInfo(*pi);
878  QString msg = QString("Wants to record: %1 %2 %3 %4")
879  .arg(new_rec->GetTitle()).arg(new_rec->GetChanNum())
881  .arg(new_rec->GetRecordingEndTime(MythDate::ISODate));
882  LOG(VB_PLAYBACK, LOG_INFO, LOC + msg);
883  }
884 
885  m_pseudoLiveTVRec = new_rec;
886  m_pseudoLiveTVState = new_state;
887 
888  if (old_rec)
889  {
890  QString msg = QString("Done recording: %1 %2 %3 %4")
891  .arg(old_rec->GetTitle()).arg(old_rec->GetChanNum())
893  .arg(old_rec->GetRecordingEndTime(MythDate::ISODate));
894  LOG(VB_PLAYBACK, LOG_INFO, LOC + msg);
895  delete old_rec;
896  }
897 }
void LockOSD(void)
Definition: mythplayer.h:358
bool m_nohardwaredecoders
long long m_playingLen
Initial CalculateLength()
int m_ffRewState
0 == normal, +1 == fast forward, -1 == rewind
virtual void ResizeDisplayWindow(const QRect &Rect, bool SaveVisible)
Resize Display Window.
float GetVideoAspect(void) const
Definition: mythplayer.h:189
void SetStretchFactor(float factor)
void Pause(void)
Pauses the read-ahead thread.
Definition: ringbuffer.cpp:733
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
MythPlayer * m_player
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
Definition: tv.h:63
virtual void ToMap(InfoMap &progMap, bool showrerecord=false, uint star_range=10) const
Converts ProgramInfo into QString QHash containing each field in ProgramInfo converted into localized...
PlayerFlags
Definition: mythplayer.h:86
QString GetPreviousChannel(void) const
void ChangeState(TVState newState)
Puts a state change on the nextState queue.
PIPState m_pipState
QString toString(MarkTypes type)
TVState m_playingState
int m_ffRewIndex
Index into m_ffRewSpeeds for FF and Rewind speeds.
bool HasPlayer(void) const
bool IsPlaying(uint wait_in_msec=0, bool wait_for=true) const
Definition: mythplayer.cpp:376
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
bool HandlePlayerSpeedChangeFFRew(void)
void DestroyChain(void)
void StopEmbedding(void)
RingBuffer * m_buffer
bool IsVideoDVD(void) const
Definition: programinfo.h:339
QString GetPlayMessage(void) const
void UnlockPlayingInfo(const char *file, int line) const
virtual bool StartPlaying(void)
ProgramInfo * GetProgramAt(int at) const
Returns program at the desired location.
void LockDeletePlayer(const char *file, int line) const
prevent MythPlayer from being deleted used to ensure player can only be deleted after osd in TV() is ...
QString StateToString(TVState state)
Returns a human readable QString representing a TVState.
Definition: tv.cpp:10
void SetAudioInfo(const QString &main_device, const QString &passthru_device, uint samplerate, int codec_profile=-1)
Set audio output device parameters.
QString GetTitle(void) const
Definition: programinfo.h:353
void SetRingBuffer(RingBuffer *buf)
void SetNoAudio(void)
Definition: audioplayer.h:51
Watching Recording is the state for when we are watching an in progress recording,...
Definition: tv.h:80
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString ReinitAudio(void)
bool IsEmbedding(void) const
Watching Pre-recorded is a TV only state for when we are watching a pre-existing recording.
Definition: tv.h:67
void SetRecorder(RemoteEncoder *rec)
bool IsDatabaseIgnored(void) const
/brief Returns true if database is being ignored.
Watching DVD is the state when we are watching a DVD.
Definition: tv.h:73
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...
void SetLength(int len)
Definition: mythplayer.h:165
QString PopPreviousChannel(void)
QString GetChanNum(void) const
This is the channel "number", in the form 1, 1_2, 1-2, 1#1, etc.
Definition: programinfo.h:368
TVState
TVState is an enumeration of the states used by TV and TVRec.
Definition: tv.h:50
void enqueue(T d)
Adds item to the back of the list. O(1).
Definition: mythdeque.h:42
void PushPreviousChannel(void)
most recently selected channel to the previous channel list
QString GetChannelPlaybackFilters(void) const
Definition: programinfo.h:379
virtual bool IsPBPSupported(void) const
Definition: mythvideoout.h:91
void ForceNextStateNone(void)
Removes any pending state changes, and puts kState_None on the queue.
void StopPlaying(void)
StringDeque m_prevChan
Previous channels.
QString GetInetRef(void) const
Definition: programinfo.h:429
QWidget * m_parentWidget
PseudoState m_pseudoLiveTVState
void EmbedInWidget(QRect rect)
bool StartPlaying(int maxWait=-1)
Starts player, must be called after StartRecorder().
bool IsPlayerErrored(void) const
ProgramInfo * m_playingInfo
Currently playing info.
Holds information on recordings and videos.
Definition: programinfo.h:66
void SetPlayingInfo(const ProgramInfo *info)
assign programinfo to the context
void ReloadAll(const QStringList &data=QStringList())
QRect GetStandAlonePIPRect(void)
Get PIP more accurate display size for standalone PIP by factoring the aspect ratio of the video.
static const uint kMaxChannelHistory
MythVideoOutput * GetVideoOutput(void)
Definition: mythplayer.h:252
QString GetChannelName(int pos=-1) const
AudioPlayer * GetAudio(void)
Definition: mythplayer.h:202
PlayerContext(QString inUseID=QString("Unknown"))
void SetPlayer(MythPlayer *newplayer)
bool StartEmbedding(const QRect &)
bool GetPlayingInfoMap(InfoMap &infoMap) const
uint GetSecondsInRecording(void) const
Returns length of program/recording in seconds.
virtual bool IsPIPSupported(void) const
Definition: mythvideoout.h:90
static const int kInitFFRWSpeed
1x, default to normal speed
Definition: tv_play.h:1055
TVState DequeueNextState(void)
bool IsRecording(void) const
Definition: programinfo.h:477
Watching Video is the state when we are watching a video and is not a dvd or BD.
Definition: tv.h:71
void SetPlayGroup(const QString &group)
QString InitializeNewChain(const QString &seed)
Definition: livetvchain.cpp:41
virtual void StopPlaying(void)
QString GetBasename(void) const
Definition: programinfo.h:336
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
T dequeue()
Removes item from front of list and returns a copy. O(1).
Definition: mythdeque.h:32
void CheckTVChain()
QString GetSetting(const QString &key, const QString &defaultval="")
bool IsVideoBD(void) const
Definition: programinfo.h:341
void LockOSD(void) const
bool IsRecorderErrored(void) const
bool IsAudioNeeded(void) const
void LockPlayingInfo(const char *file, int line) const
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
void SetPseudoLiveTV(const ProgramInfo *pi, PseudoState new_state)
void UnlockDeletePlayer(const char *file, int line) const
allow player to be deleted.
void LockState(void) const
int m_lastCardid
CardID of current/last recorder.
static QString GetIcon(uint chanid)
Control TV playback.
Definition: tv_play.h:279
QString GetFilters(const QString &baseFilters) const
Watching BD is the state when we are watching a BD.
Definition: tv.h:75
uint GetSeason(void) const
Definition: programinfo.h:358
unsigned int uint
Definition: compat.h:140
void UnlockOSD(void)
Definition: mythplayer.h:359
virtual void calcSliderPos(osdInfo &info, bool paddedFields=false)
bool IsErrored(void) const
QMutex m_deletePlayerLock
bool m_useNullVideo
True iff software scaled PIP should be used.
QString GetPlaybackGroup(void) const
Definition: programinfo.h:412
static const uint kSMExitTimeout
Timeout after last Signal Monitor message for ignoring OSD when exiting.
void StopEmbedding(void)
int64_t AdjustAudioTimecodeOffset(int64_t v, int newsync=-9999)
void ResizePIPWindow(void)
RemoteEncoder * m_recorder
bool IsVideoFile(void) const
Definition: programinfo.h:337
LiveTVChain * m_tvchain
ProgramInfo * m_pseudoLiveTVRec
void UnlockOSD(void) const
void WaitForPause(void)
Waits for Pause(void) to take effect.
Definition: ringbuffer.cpp:770
void addMSecs(int ms)
Adds an offset to the last call to start() or restart().
Definition: mythtimer.cpp:145
void SetPlayerInfo(TV *tv, QWidget *widget, PlayerContext *ctx)
bool GetErrorStatus(void)
Definition: remoteencoder.h:78
int m_ffRewSpeed
Caches value of m_ffRewSpeeds[m_ffRewIndex].
None State, this is the initial state in both TV and TVRec, it indicates that we are ready to change ...
Definition: tv.h:58
PIPLocation
Definition: videoouttypes.h:19
void LoadExternalSubtitles(const QString &subtitleFileName, bool isInProgress)
int m_pipLocation
Position of PIP on TV screen.
int GetNumSetting(const QString &key, int defaultval=0)
bool AtNormalSpeed(void) const
Definition: mythplayer.h:233
void GetCodecDescription(InfoMap &infoMap)
bool ReloadTVChain(void)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
bool HandlePlayerSpeedChangeEOF(void)
TVState GetState(void) const
bool GetBoolSetting(const QString &key, bool defaultval=false)
bool IsPBPSupported(void) const
Check if PBP is supported for current video renderer running.
QString GetSubtitleFilename(void) const
static int GetSetting(const QString &name, const QString &field, int defval)
Definition: playgroup.cpp:246
bool IsPIP(void) const
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:364
bool InStateChange(void) const
bool IsEmbedding(void)
bool IsPIPSupported(void) const
Check if PIP is supported for current video renderer running.
#define LOC
int GetRecorderNumber(void) const
bool CalcPlayerSliderPosition(osdInfo &info, bool paddedFields=false) const
MythTimer m_lastSignalMsgTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:396
PseudoState
Definition: playercontext.h:39
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
Definition: programinfo.h:404
QString m_recUsage
void SetTVChain(LiveTVChain *chain)
bool StartPIPPlayer(TV *tv, TVState desiredState)
void PIPTeardown(void)
stop player but pause the ringbuffer.
void UpdateTVChain(const QStringList &data=QStringList())
Default UTC.
Definition: mythdate.h:14
bool SetMuted(bool mute)
Definition: mythplayer.h:412
Implements a file/stream reader/writer.
QMutex m_stateLock
float GetNextPlaySpeed(void) const
Definition: mythplayer.h:205
QMultiMap< VideoArtworkType, ArtworkInfo > ArtworkMap
void CreatePIPWindow(const QRect &, int pos=-1, QWidget *widget=nullptr)
void TeardownPlayer(void)
bool IsPlayerPlaying(void) const
MythDeque< TVState > m_nextState
void SetInitialTVState(bool islivetv)
determine initial tv state and playgroup for the recording
float m_tsNormal
Time stretch speed, 1.0F for normal playback.
bool CreatePlayer(TV *tv, QWidget *widget, TVState desiredState, bool embed, const QRect &embedBounds=QRect(), bool muted=false)
static QString GetArtPath(const QString &pathname, const QString &type)
QString GetHostName(void)
bool IsSameProgram(const ProgramInfo &p) const
bool IsSameProgram(const ProgramInfo &other) const
Checks whether this is the same program as "other", which may or may not be a repeat or on another ch...
QString GetPathname(void) const
Definition: programinfo.h:335
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
Keeps track of recordings in a current LiveTV instance.
Definition: livetvchain.h:31
void SetWatchingRecording(bool mode)
Definition: mythplayer.cpp:246
void UnlockState(void) const
QMutex m_playingInfoLock
ArtworkMap GetArtwork(const QString &inetref, uint season, bool strict)
virtual SubtitleReader * GetSubReader(uint=0)
Definition: mythplayer.h:300