MythTV  master
mythplayer.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 #undef HAVE_AV_CONFIG_H
4 
5 // C++ headers
6 #include <algorithm>
7 #include <cassert>
8 #include <cmath>
9 #include <cstdint>
10 #include <cstdio>
11 #include <cstdlib>
12 #include <unistd.h>
13 
14 // Qt headers
15 #include <QCoreApplication>
16 #include <QDir>
17 #include <QHash>
18 #include <QMap>
19 #include <QThread>
20 #include <QtCore/qnumeric.h>
21 #include <utility>
22 
23 // MythTV headers
24 #include "mthread.h"
25 #include "mythconfig.h"
26 #include "mythplayer.h"
27 #include "DetectLetterbox.h"
28 #include "audioplayer.h"
29 #include "programinfo.h"
30 #include "mythcorecontext.h"
31 #include "livetvchain.h"
32 #include "avformatdecoder.h"
33 #include "dummydecoder.h"
34 #include "tv_play.h"
35 #include "mythlogging.h"
36 #include "mythmiscutil.h"
37 #include "audiooutput.h"
38 #include "cardutil.h"
39 #include "mythavutil.h"
40 #include "jitterometer.h"
41 #include "mythtimer.h"
42 #include "mythuiactions.h"
43 #include "io/mythmediabuffer.h"
44 #include "tv_actions.h"
46 #include "mythvideooutnull.h"
47 #include "mythcodeccontext.h"
48 
49 // MythUI headers
50 #include <mythmainwindow.h>
51 
52 extern "C" {
53 #include "libavcodec/avcodec.h"
54 }
55 
56 #include "remoteencoder.h"
57 
58 #if ! HAVE_ROUND
59 #define round(x) ((int) ((x) + 0.5))
60 #endif
61 
62 static unsigned dbg_ident(const MythPlayer* /*player*/);
63 
64 #define LOC QString("Player(%1): ").arg(dbg_ident(this),0,36)
65 
68 
69 // Exact frame seeking, no inaccuracy allowed.
70 const double MythPlayer::kInaccuracyNone = 0;
71 
72 // By default, when seeking, snap to a keyframe if the keyframe's
73 // distance from the target frame is less than 10% of the total seek
74 // distance.
75 const double MythPlayer::kInaccuracyDefault = 0.1;
76 
77 // Allow greater inaccuracy (50%) in the cutlist editor (unless the
78 // editor seek distance is set to 1 frame or 1 keyframe).
79 const double MythPlayer::kInaccuracyEditor = 0.5;
80 
81 // Any negative value means completely inexact, i.e. seek to the
82 // keyframe that is closest to the target.
83 const double MythPlayer::kInaccuracyFull = -1.0;
84 
86  : m_playerCtx(Context),
87  m_playerFlags(Flags),
88  // CC608/708
89  m_cc608(this), m_cc708(this),
90  // Audio
91  m_audio(this, (Flags & kAudioMuted) != 0)
92 {
93  m_playerThread = QThread::currentThread();
94 #ifdef Q_OS_ANDROID
95  m_playerThreadId = gettid();
96 #endif
99 
102  m_clearSavedPosition = gCoreContext->GetNumSetting("ClearSavedPosition", 1);
103  m_endExitPrompt = gCoreContext->GetNumSetting("EndOfRecordingExitPrompt");
104 
105  // Get VBI page number
106  QString mypage = gCoreContext->GetSetting("VBIpageNr", "888");
107  bool valid = false;
108  uint tmp = mypage.toInt(&valid, 16);
109  m_ttPageNum = (valid) ? tmp : m_ttPageNum;
111 }
112 
114 {
115  QMutexLocker lock2(&m_vidExitLock);
116 
117  SetDecoder(nullptr);
118 
119  delete m_decoderThread;
120  m_decoderThread = nullptr;
121 
122  delete m_videoOutput;
123  m_videoOutput = nullptr;
124 }
125 
127 {
128  m_watchingRecording = mode;
129  if (m_decoder)
131 }
132 
134 {
136 }
137 
139 {
140  m_bufferPauseLock.lock();
141  if (m_playerCtx->m_buffer)
142  {
145  }
146  m_bufferPaused = true;
147  m_bufferPauseLock.unlock();
148 }
149 
151 {
152  m_bufferPauseLock.lock();
153  if (m_playerCtx->m_buffer)
155  m_bufferPaused = false;
156  m_bufferPauseLock.unlock();
157 }
158 
160 {
161  while (!m_pauseLock.tryLock(100))
162  {
163  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Waited 100ms to get pause lock.");
165  }
166  bool already_paused = m_allPaused;
167  if (already_paused)
168  {
169  m_pauseLock.unlock();
170  return already_paused;
171  }
172  m_nextPlaySpeed = 0.0;
173  m_nextNormalSpeed = false;
174  PauseVideo();
175  m_audio.Pause(true);
176  PauseDecoder();
177  PauseBuffer();
178  if (!m_decoderPaused)
179  PauseDecoder(); // Retry in case audio only stream
181  {
184  else if (m_videoOutput && !FlagIsSet(kVideoIsNull))
186  }
187  m_pauseLock.unlock();
189  return already_paused;
190 }
191 
192 bool MythPlayer::Play(float speed, bool normal, bool unpauseaudio)
193 {
194  m_pauseLock.lock();
195  LOG(VB_PLAYBACK, LOG_INFO, LOC +
196  QString("Play(%1, normal %2, unpause audio %3)")
197  .arg(speed,5,'f',1).arg(normal).arg(unpauseaudio));
198 
199  if (m_deleteMap.IsEditing())
200  {
201  LOG(VB_GENERAL, LOG_ERR, LOC + "Ignoring Play(), in edit mode.");
202  m_pauseLock.unlock();
203  return false;
204  }
205 
207 
209  UnpauseBuffer();
210  UnpauseDecoder();
211  if (unpauseaudio)
212  m_audio.Pause(false);
213  UnpauseVideo();
214  m_allPaused = false;
215  m_nextPlaySpeed = speed;
216  m_nextNormalSpeed = normal;
217  m_pauseLock.unlock();
219  return true;
220 }
221 
223 {
224  m_videoPauseLock.lock();
225  m_needNewPauseFrame = true;
226  m_videoPaused = true;
227  m_videoPauseLock.unlock();
228 }
229 
231 {
232  m_videoPauseLock.lock();
233  m_videoPaused = false;
234  m_videoPauseLock.unlock();
235 }
236 
238 {
240  if (!m_playerCtx)
241  return;
242 
243  m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
244  m_playerCtx->SetPlayingInfo(&pginfo);
245  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
246 }
247 
248 void MythPlayer::SetPlaying(bool is_playing)
249 {
250  QMutexLocker locker(&m_playingLock);
251 
252  m_playing = is_playing;
253 
254  m_playingWaitCond.wakeAll();
255 }
256 
257 bool MythPlayer::IsPlaying(std::chrono::milliseconds wait_in_msec, bool wait_for) const
258 {
259  QMutexLocker locker(&m_playingLock);
260 
261  if (wait_in_msec != 0ms)
262  return m_playing;
263 
264  MythTimer t;
265  t.start();
266 
267  while ((wait_for != m_playing) && (t.elapsed() < wait_in_msec))
268  {
269  m_playingWaitCond.wait(
270  &m_playingLock, std::max(0ms,wait_in_msec - t.elapsed()).count());
271  }
272 
273  return m_playing;
274 }
275 
277 {
278  if (!m_playerCtx)
279  return false;
280 
281  if (!m_decoder)
282  {
283  LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot create a video renderer without a decoder.");
284  return false;
285  }
286 
289 
290  if (!m_videoOutput)
291  {
292  LOG(VB_GENERAL, LOG_ERR, LOC + "Couldn't create VideoOutput instance. Exiting..");
293  SetErrored(tr("Failed to initialize video output"));
294  return false;
295  }
296 
297  return true;
298 }
299 
300 void MythPlayer::ReinitVideo(bool ForceUpdate)
301 {
302 
303  bool aspect_only = false;
304  {
305  QMutexLocker locker(&m_vidExitLock);
306  m_videoOutput->SetVideoFrameRate(static_cast<float>(m_videoFrameRate));
307  float video_aspect = (m_forcedVideoAspect > 0) ? m_forcedVideoAspect : m_videoAspect;
309  m_decoder->GetVideoCodecID(), aspect_only,
310  m_maxReferenceFrames, ForceUpdate))
311  {
312  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to Reinitialize Video. Exiting..");
313  SetErrored(tr("Failed to reinitialize video output"));
314  return;
315  }
316  }
317 
318  if (!aspect_only)
319  ClearAfterSeek();
320 }
321 
322 void MythPlayer::SetKeyframeDistance(int keyframedistance)
323 {
324  m_keyframeDist = (keyframedistance > 0) ? static_cast<uint>(keyframedistance) : m_keyframeDist;
325 }
326 
327 void MythPlayer::SetVideoParams(int width, int height, double fps,
328  float aspect, bool ForceUpdate,
329  int ReferenceFrames, FrameScanType /*scan*/, const QString& codecName)
330 {
331  bool paramsChanged = ForceUpdate;
332 
333  if (width >= 0 && height >= 0)
334  {
335  paramsChanged = true;
336  m_videoDim = m_videoDispDim = QSize(width, height);
337  m_videoAspect = aspect > 0.0F ? aspect : static_cast<float>(width) / height;
338  }
339 
340  if (!qIsNaN(fps) && fps > 0.0 && fps < 121.0)
341  {
342  paramsChanged = true;
343  m_videoFrameRate = fps;
344  if (m_ffrewSkip != 0 && m_ffrewSkip != 1)
345  {
346  UpdateFFRewSkip();
347  }
348  else
349  {
350  float temp_speed = (m_playSpeed == 0.0F) ?
353  1.0 / (m_videoFrameRate * static_cast<double>(temp_speed)));
354  }
355  }
356 
357  if (!codecName.isEmpty())
358  {
359  m_codecName = codecName;
360  paramsChanged = true;
361  }
362 
363  if (ReferenceFrames > 0)
364  {
365  m_maxReferenceFrames = ReferenceFrames;
366  paramsChanged = true;
367  }
368 
369  if (!paramsChanged)
370  return;
371 
372  if (m_videoOutput)
373  ReinitVideo(ForceUpdate);
374 
375  if (IsErrored())
376  return;
377 }
378 
379 
380 void MythPlayer::SetFrameRate(double fps)
381 {
382  m_videoFrameRate = fps;
383  float temp_speed = (m_playSpeed == 0.0F) ? m_audio.GetStretchFactor() : m_playSpeed;
384  SetFrameInterval(kScan_Progressive, 1.0 / (m_videoFrameRate * static_cast<double>(temp_speed)));
385 }
386 
387 void MythPlayer::SetFileLength(std::chrono::seconds total, int frames)
388 {
389  m_totalLength = total;
390  m_totalFrames = frames;
391 }
392 
393 void MythPlayer::SetDuration(std::chrono::seconds duration)
394 {
395  m_totalDuration = duration;
396 }
397 
399 {
400  m_isDummy = true;
401 
402  if (!m_videoOutput)
403  {
405  SetVideoParams(720, 576, 25.00, 1.25F, false, 2);
406  }
407 
408  m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
409  auto *dec = new DummyDecoder(this, *(m_playerCtx->m_playingInfo));
410  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
411  SetDecoder(dec);
412 }
413 
415 {
418 }
419 
420 int MythPlayer::OpenFile(int Retries)
421 {
422  // Sanity check
423  if (!m_playerCtx || !m_playerCtx->m_buffer)
424  return -1;
425 
426  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Opening '%1'").arg(m_playerCtx->m_buffer->GetSafeFilename()));
427 
428  m_isDummy = false;
430 
431  // Dummy setup for livetv transtions. Can we get rid of this?
432  if (m_playerCtx->m_tvchain)
433  {
434  int currentposition = m_playerCtx->m_tvchain->GetCurPos();
435  if (m_playerCtx->m_tvchain->GetInputType(currentposition) == "DUMMY")
436  {
437  OpenDummy();
438  return 0;
439  }
440  }
441 
442  // Start the RingBuffer read ahead thread
444 
446  TestBufferVec testbuf {};
447  testbuf.reserve(kDecoderProbeBufferSize);
448 
449  UnpauseBuffer();
450 
451  // delete any pre-existing recorder
452  SetDecoder(nullptr);
453  int testreadsize = 2048;
454 
455  // Test the incoming buffer and create a suitable decoder
456  MythTimer bigTimer;
457  bigTimer.start();
458  std::chrono::milliseconds timeout =
459  std::max(500ms * (Retries + 1), 30000ms);
460  while (testreadsize <= kDecoderProbeBufferSize)
461  {
462  testbuf.resize(testreadsize);
463  MythTimer peekTimer;
464  peekTimer.start();
465  while (m_playerCtx->m_buffer->Peek(testbuf) != testreadsize)
466  {
467  // NB need to allow for streams encountering network congestion
468  if (peekTimer.elapsed() > 30s || bigTimer.elapsed() > timeout
470  {
471  LOG(VB_GENERAL, LOG_ERR, LOC +
472  QString("OpenFile(): Could not read first %1 bytes of '%2'")
473  .arg(testreadsize)
474  .arg(m_playerCtx->m_buffer->GetFilename()));
475  SetErrored(tr("Could not read first %1 bytes").arg(testreadsize));
476  return -1;
477  }
478  LOG(VB_GENERAL, LOG_WARNING, LOC + "OpenFile() waiting on data");
479  std::this_thread::sleep_for(50ms);
480  }
481 
482  m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
483  CreateDecoder(testbuf);
484  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
485  if (m_decoder || (bigTimer.elapsed() > timeout))
486  break;
487  testreadsize <<= 1;
488  }
489 
490  // Fail
491  if (!m_decoder)
492  {
493  LOG(VB_GENERAL, LOG_ERR, LOC +
494  QString("Couldn't find an A/V decoder for: '%1'")
495  .arg(m_playerCtx->m_buffer->GetFilename()));
496  SetErrored(tr("Could not find an A/V decoder"));
497 
498  return -1;
499  }
500 
501  if (m_decoder->IsErrored())
502  {
503  LOG(VB_GENERAL, LOG_ERR, LOC + "Could not initialize A/V decoder.");
504  SetDecoder(nullptr);
505  SetErrored(tr("Could not initialize A/V decoder"));
506 
507  return -1;
508  }
509 
510  // Pre-init the decoder
514  // TODO (re)move this into MythTranscode player
516 
517  // Open the decoder
518  int result = m_decoder->OpenFile(m_playerCtx->m_buffer, false, testbuf);
519 
520  if (result < 0)
521  {
522  LOG(VB_GENERAL, LOG_ERR, QString("Couldn't open decoder for: %1")
523  .arg(m_playerCtx->m_buffer->GetFilename()));
524  SetErrored(tr("Could not open decoder"));
525  return -1;
526  }
527 
528  // Disable audio if necessary
530 
531  // Livetv, recording or in-progress
532  if (result > 0)
533  {
534  m_hasFullPositionMap = true;
537  }
538 
539  // Determine the initial bookmark and update it for the cutlist
543 
546  {
547  gCoreContext->SaveSetting("DefaultChanid",
548  static_cast<int>(m_playerCtx->m_playingInfo->GetChanID()));
549  QString callsign = m_playerCtx->m_playingInfo->GetChannelSchedulingID();
550  QString channum = m_playerCtx->m_playingInfo->GetChanNum();
551  gCoreContext->SaveSetting("DefaultChanKeys", callsign + "[]:[]" + channum);
553  {
554  uint cardid = static_cast<uint>(m_playerCtx->m_recorder->GetRecorderNumber());
555  CardUtil::SetStartChannel(cardid, channum);
556  }
557  }
558 
559  return IsErrored() ? -1 : 0;
560 }
561 
562 void MythPlayer::SetFramesPlayed(uint64_t played)
563 {
564  m_framesPlayed = played;
565  if (m_videoOutput)
567 }
568 
573 {
574  if (m_videoOutput)
575  return m_videoOutput->FreeVideoFrames();
576  return 0;
577 }
578 
589 {
590  if (m_videoOutput)
592  return nullptr;
593 }
594 
599  std::chrono::milliseconds timecode,
600  bool wrap)
601 {
602  if (wrap)
603  WrapTimecode(timecode, TC_VIDEO);
604  buffer->m_timecode = timecode;
605  m_latestVideoTimecode = timecode;
606 
607  if (m_videoOutput)
608  m_videoOutput->ReleaseFrame(buffer);
609 
610  // FIXME need to handle this in the correct place in the main thread (DVD stills?)
611  //if (m_allPaused)
612  // CheckAspectRatio(buffer);
613 }
614 
619 {
620  if (m_videoOutput)
621  m_videoOutput->DiscardFrame(buffer);
622 }
623 
637 void MythPlayer::DiscardVideoFrames(bool KeyFrame, bool Flushed)
638 {
639  if (m_videoOutput)
640  m_videoOutput->DiscardFrames(KeyFrame, Flushed);
641 }
642 
644 {
645  EofState eof = GetEof();
646  if (eof != kEofStateNone && !m_allPaused)
647  return true;
648  if (GetEditMode())
649  return false;
650  if (m_liveTV)
651  return false;
653  return true;
654  return false;
655 }
656 
658 {
659  if (m_videoOutput)
660  m_videoOutput->DeLimboFrame(frame);
661 }
662 
664 {
665  if (enable)
667  else
669 }
670 
672 {
673  if (m_decoder)
675  m_frameInterval = microsecondsFromFloat(1000000.0 * frame_period / m_fpsMultiplier);
676 
677  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("SetFrameInterval Interval:%1 Speed:%2 Scan:%3 (Multiplier: %4)")
678  .arg(m_frameInterval.count()).arg(static_cast<double>(m_playSpeed)).arg(ScanTypeToString(scan)).arg(m_fpsMultiplier));
679 }
680 
682 {
683  // try to get preferential scheduling, but ignore if we fail to.
684  myth_nice(-19);
685 }
686 
687 void MythPlayer::SetBuffering(bool new_buffering)
688 {
689  if (!m_buffering && new_buffering)
690  {
691  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Waiting for video buffers...");
692  m_buffering = true;
693  m_bufferingStart = QTime::currentTime();
694  m_bufferingLastMsg = QTime::currentTime();
695  }
696  else if (m_buffering && !new_buffering)
697  {
698  m_buffering = false;
699  }
700 }
701 
702 // For debugging playback set this to increase the timeout so that
703 // playback does not fail if stepping through code.
704 // Set PREBUFFERDEBUG to any value and you will get 30 minutes.
705 static bool preBufferDebug = qEnvironmentVariableIsSet("PREBUFFERDEBUG");
706 
708 {
709  if (!m_videoOutput)
710  return false;
711 
712  if (!(min_buffers
713  ? (m_videoOutput->ValidVideoFrames() >= min_buffers)
714  : (GetEof() != kEofStateNone
716  || (m_ffrewSkip != 0 && m_ffrewSkip != 1))))
717  {
718  SetBuffering(true);
719 
720  // This piece of code is to address the problem, when starting
721  // Live TV, of jerking and stuttering. Without this code
722  // that could go on forever, but is cured by a pause and play.
723  // This code inserts a brief pause and play when the potential
724  // for the jerking is detected.
725 
726  bool watchingTV = IsWatchingInprogress();
727  if ((m_liveTV || watchingTV) && !FlagIsSet(kMusicChoice))
728  {
729  uint64_t frameCount = GetCurrentFrameCount();
730  uint64_t framesLeft = frameCount - m_framesPlayed;
731  auto margin = static_cast<uint64_t>(m_videoFrameRate * 3);
732  if (framesLeft < margin)
733  {
735  {
736  LOG(VB_PLAYBACK, LOG_NOTICE, LOC + "Pause to allow live tv catch up");
737  LOG(VB_PLAYBACK, LOG_NOTICE, LOC + QString("Played: %1 Avail: %2 Buffered: %3 Margin: %4")
738  .arg(m_framesPlayed).arg(frameCount)
739  .arg(m_videoOutput->ValidVideoFrames()).arg(margin));
740  }
741  }
742  }
743 
744  std::this_thread::sleep_for(m_frameInterval / 8);
745  auto waited_for = std::chrono::milliseconds(m_bufferingStart.msecsTo(QTime::currentTime()));
746  auto last_msg = std::chrono::milliseconds(m_bufferingLastMsg.msecsTo(QTime::currentTime()));
747  if (last_msg > 100ms && !FlagIsSet(kMusicChoice))
748  {
749  if (++m_bufferingCounter == 10)
750  LOG(VB_GENERAL, LOG_NOTICE, LOC +
751  "To see more buffering messages use -v playback");
752  if (m_bufferingCounter >= 10)
753  {
754  LOG(VB_PLAYBACK, LOG_NOTICE, LOC +
755  QString("Waited %1ms for video buffers %2")
756  .arg(waited_for.count()).arg(m_videoOutput->GetFrameStatus()));
757  }
758  else
759  {
760  LOG(VB_GENERAL, LOG_NOTICE, LOC +
761  QString("Waited %1ms for video buffers %2")
762  .arg(waited_for.count()).arg(m_videoOutput->GetFrameStatus()));
763  }
764  m_bufferingLastMsg = QTime::currentTime();
766  && gCoreContext->GetBoolSetting("MusicChoiceEnabled", false))
767  {
769  LOG(VB_GENERAL, LOG_NOTICE, LOC + "Music Choice program detected - disabling AV Sync.");
771  }
772  if (waited_for > 7s && m_audio.IsBufferAlmostFull()
773  && !FlagIsSet(kMusicChoice))
774  {
775  // We are likely to enter this condition
776  // if the audio buffer was too full during GetFrame in AVFD
777  LOG(VB_GENERAL, LOG_NOTICE, LOC + "Resetting audio buffer");
778  m_audio.Reset();
779  }
780  // Finish audio pause for sync after 1 second
781  // in case of infrequent video frames (e.g. music choice)
782  if (m_avSync.GetAVSyncAudioPause() && waited_for > 1s)
784  }
785  std::chrono::milliseconds msecs { 500ms };
786  if (preBufferDebug)
787  msecs = 30min;
788  if ((waited_for > msecs) && !m_videoOutput->EnoughFreeFrames())
789  {
790  LOG(VB_GENERAL, LOG_NOTICE, LOC +
791  "Timed out waiting for frames, and"
792  "\n\t\t\tthere are not enough free frames. "
793  "Discarding buffered frames.");
794  // This call will result in some ugly frames, but allows us
795  // to recover from serious problems if frames get leaked.
796  DiscardVideoFrames(true, true);
797  }
798  msecs = 30s;
799  if (preBufferDebug)
800  msecs = 30min;
801  if (waited_for > msecs) // 30 seconds for internet streamed media
802  {
803  LOG(VB_GENERAL, LOG_ERR, LOC +
804  "Waited too long for decoder to fill video buffers. Exiting..");
805  SetErrored(tr("Video frame buffering failed too many times."));
806  }
807  return false;
808  }
809 
811  m_audio.Pause(false);
812  SetBuffering(false);
813  return true;
814 }
815 
817 {
818  m_vidExitLock.lock();
819  delete m_videoOutput;
820  m_videoOutput = nullptr;
821  m_vidExitLock.unlock();
822 }
823 
824 bool MythPlayer::FastForward(float seconds)
825 {
826  if (!m_videoOutput)
827  return false;
828 
829  // Update m_totalFrames so we know how far we can skip
830  if (m_decoder)
832 
833  if (m_ffTime <= 0)
834  {
835  float current = ComputeSecs(m_framesPlayed, true);
836  float dest = current + seconds;
837  float length = ComputeSecs(m_totalFrames, true);
838 
839  if (dest > length)
840  {
841  auto msec = millisecondsFromFloat(seconds * 1000);
842  int64_t pos = TranslatePositionMsToFrame(msec, false);
843  if (CalcMaxFFTime(pos) < 0)
844  return true;
845  // Reach end of recording, go to 1 or 3s before the end
846  dest = (m_liveTV || IsWatchingInprogress()) ? -3.0 : -1.0;
847  }
848  uint64_t target = FindFrame(dest, true);
849  m_ffTime = target - m_framesPlayed;
850  }
851  return m_ffTime > CalcMaxFFTime(m_ffTime, false);
852 }
853 
854 bool MythPlayer::Rewind(float seconds)
855 {
856  if (!m_videoOutput)
857  return false;
858 
859  if (m_rewindTime <= 0)
860  {
861  float current = ComputeSecs(m_framesPlayed, true);
862  float dest = current - seconds;
863  if (dest < 0)
864  {
865  auto msec = millisecondsFromFloat(seconds * 1000);
866  int64_t pos = TranslatePositionMsToFrame(msec, false);
867  if (CalcRWTime(pos) < 0)
868  return true;
869  dest = 0;
870  }
871  uint64_t target = FindFrame(dest, true);
872  m_rewindTime = m_framesPlayed - target;
873  }
874  return (uint64_t)m_rewindTime >= m_framesPlayed;
875 }
876 
877 bool MythPlayer::JumpToFrame(uint64_t frame)
878 {
879  if (!m_videoOutput)
880  return false;
881 
882  bool ret = false;
883  m_ffTime = m_rewindTime = 0;
884  if (frame > m_framesPlayed)
885  {
886  m_ffTime = frame - m_framesPlayed;
887  ret = m_ffTime > CalcMaxFFTime(m_ffTime, false);
888  }
889  else if (frame < m_framesPlayed)
890  {
891  m_rewindTime = m_framesPlayed - frame;
892  ret = m_ffTime > CalcMaxFFTime(m_ffTime, false);
893  }
894  return ret;
895 }
896 
897 
898 void MythPlayer::JumpChapter(int chapter)
899 {
900  if (m_jumpChapter == 0)
901  m_jumpChapter = chapter;
902 }
903 
904 void MythPlayer::ResetPlaying(bool resetframes)
905 {
906  ClearAfterSeek();
907  m_ffrewSkip = 1;
908  if (resetframes)
909  m_framesPlayed = 0;
910  if (m_decoder)
911  {
912  m_decoder->Reset(true, true, true);
913  if (m_decoder->IsErrored())
914  SetErrored("Unable to reset video decoder");
915  }
916 }
917 
919 {
920  bool last = !(m_playerCtx->m_tvchain->HasNext());
921  SetWatchingRecording(last);
922 }
923 
924 // This is called from decoder thread. Set an indicator that will
925 // be checked and actioned in the player thread.
927 {
928  LOG(VB_PLAYBACK, LOG_INFO, LOC + "FileChangedCallback");
929  m_fileChanged = true;
930 }
931 
933 {
934  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("StopPlaying - begin"));
935  m_playerThread->setPriority(QThread::NormalPriority);
936 #ifdef Q_OS_ANDROID
937  setpriority(PRIO_PROCESS, m_playerThreadId, 0);
938 #endif
939 
940  emit CheckCallbacks();
941  DecoderEnd();
942  VideoEnd();
943  AudioEnd();
944 
945  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("StopPlaying - end"));
946 }
947 
949 {
951 }
952 
954 {
955  m_decoderPauseLock.lock();
957  {
958  m_decoderPaused = true;
959  m_decoderThreadPause.wakeAll();
960  m_decoderPauseLock.unlock();
961  return m_decoderPaused;
962  }
963 
964  int tries = 0;
965  m_pauseDecoder = true;
966  while (m_decoderThread && !m_killDecoder && (tries++ < 100) &&
968  {
969  emit CheckCallbacks();
970  LOG(VB_GENERAL, LOG_WARNING, LOC + "Waited 100ms for decoder to pause");
971  }
972  m_pauseDecoder = false;
973  m_decoderPauseLock.unlock();
974  return m_decoderPaused;
975 }
976 
978 {
979  m_decoderPauseLock.lock();
980 
982  {
983  m_decoderPaused = false;
984  m_decoderThreadUnpause.wakeAll();
985  m_decoderPauseLock.unlock();
986  return;
987  }
988 
989  if (!IsInStillFrame())
990  {
991  int tries = 0;
992  m_unpauseDecoder = true;
993  while (m_decoderThread && !m_killDecoder && (tries++ < 100) &&
995  {
996  emit CheckCallbacks();
997  LOG(VB_GENERAL, LOG_WARNING, LOC + "Waited 100ms for decoder to unpause");
998  }
999  m_unpauseDecoder = false;
1000  }
1001  m_decoderPauseLock.unlock();
1002 }
1003 
1004 void MythPlayer::DecoderStart(bool start_paused)
1005 {
1006  if (m_decoderThread)
1007  {
1008  if (m_decoderThread->isRunning())
1009  {
1010  LOG(VB_GENERAL, LOG_ERR, LOC + "Decoder thread already running");
1011  }
1012  delete m_decoderThread;
1013  }
1014 
1015  m_killDecoder = false;
1016  m_decoderPaused = start_paused;
1017  m_decoderThread = new MythDecoderThread(this, start_paused);
1018  if (m_decoderThread)
1020 }
1021 
1023 {
1024  PauseDecoder();
1025  SetPlaying(false);
1026  // Ensure any hardware frames are released (after pausing the decoder) to
1027  // allow the decoder to exit cleanly
1028  DiscardVideoFrames(true, true);
1029 
1030  m_killDecoder = true;
1031  int tries = 0;
1032  while (m_decoderThread && !m_decoderThread->wait(100ms) && (tries++ < 50))
1033  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1034  "Waited 100ms for decoder loop to stop");
1035 
1037  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to stop decoder loop.");
1038  else
1039  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Exited decoder loop.");
1040  SetDecoder(nullptr);
1041 }
1042 
1044 {
1046  {
1047  if (m_pauseDecoder)
1048  PauseDecoder();
1049  if (m_unpauseDecoder)
1050  UnpauseDecoder();
1051  }
1052 }
1053 
1056 {
1059 
1060  if (!m_decoderChangeLock.tryLock(50))
1061  return kEofStateNone;
1062 
1064  m_decoderChangeLock.unlock();
1065  return eof;
1066 }
1067 
1069 {
1071  {
1072  if (m_decoder)
1073  m_decoder->SetEofState(eof);
1074  return;
1075  }
1076 
1077  if (!m_decoderChangeLock.tryLock(50))
1078  return;
1079 
1080  if (m_decoder)
1081  m_decoder->SetEofState(eof);
1082  m_decoderChangeLock.unlock();
1083 }
1085 
1086 void MythPlayer::DecoderLoop(bool pause)
1087 {
1088  if (pause)
1089  PauseDecoder();
1090 
1091  while (!m_killDecoder && !IsErrored())
1092  {
1094 
1096  {
1097  std::this_thread::sleep_for(1ms);
1098  continue;
1099  }
1100 
1102  {
1103  if (!m_decoderChangeLock.tryLock(1))
1104  continue;
1105  if (m_decoder)
1106  {
1107  m_forcePositionMapSync = false;
1109  }
1110  m_decoderChangeLock.unlock();
1111  }
1112 
1113  if (m_decoderSeek >= 0)
1114  {
1115  if (!m_decoderChangeLock.tryLock(1))
1116  continue;
1117  if (m_decoder)
1118  {
1119  m_decoderSeekLock.lock();
1120  if (((uint64_t)m_decoderSeek < m_framesPlayed) && m_decoder)
1122  else if (m_decoder)
1124  m_decoderSeek = -1;
1125  m_decoderSeekLock.unlock();
1126  }
1127  m_decoderChangeLock.unlock();
1128  }
1129 
1130  bool obey_eof = (GetEof() != kEofStateNone) &&
1132  if (m_isDummy || ((m_decoderPaused || m_ffrewSkip == 0 || obey_eof) &&
1133  !m_decodeOneFrame))
1134  {
1135  std::this_thread::sleep_for(1ms);
1136  continue;
1137  }
1138 
1141 
1142  DecoderGetFrame(dt);
1143  m_decodeOneFrame = false;
1144  }
1145 
1146  // Clear any wait conditions
1148  m_decoderSeek = -1;
1149 }
1150 
1151 static float ffrewScaleAdjust = 0.10F;
1152 static float ffrewSkipThresh = 0.60F;
1153 static float ffrewScaleLowest = 1.00F;
1154 static float ffrewScaleHighest = 2.50F;
1155 
1157 {
1158  if (!m_decoder)
1159  return false;
1160 
1161  if (m_ffrewSkip > 0)
1162  {
1163  long long delta = m_decoder->GetFramesRead() - m_framesPlayed;
1164  long long real_skip = CalcMaxFFTime(m_ffrewSkip - m_ffrewAdjust + delta) - delta;
1165  long long target_frame = m_decoder->GetFramesRead() + real_skip;
1166  if (real_skip >= 0)
1167  m_decoder->DoFastForward(target_frame, false);
1168 
1169  long long seek_frame = m_decoder->GetFramesRead();
1170  m_ffrewAdjust = seek_frame - target_frame;
1171  float adjustRatio = float(m_ffrewAdjust) / m_ffrewSkip;
1172  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1173  QString("skip %1, adjust %2, ratio %3")
1174  .arg(m_ffrewSkip).arg(m_ffrewAdjust).arg(adjustRatio));
1175 
1176  // If the needed adjustment is too large either way, adjust
1177  // the scale factor up or down accordingly.
1178  if (adjustRatio > ffrewSkipThresh
1179  && m_ffrewScale < (ffrewScaleHighest - 0.01F))
1181  else if (adjustRatio < -ffrewSkipThresh
1182  && m_ffrewScale > (ffrewScaleLowest + 0.01F))
1184  }
1185  else if (CalcRWTime(-m_ffrewSkip) >= 0)
1186  {
1188  }
1190 }
1191 
1193 {
1194  long long cur_frame = m_decoder->GetFramesPlayed();
1195  bool toBegin = -cur_frame > m_ffrewSkip + m_ffrewAdjust;
1196  long long real_skip = (toBegin) ? -cur_frame : m_ffrewSkip + m_ffrewAdjust;
1197  long long target_frame = cur_frame + real_skip;
1198  bool ret = m_decoder->DoRewind(target_frame, false);
1199 
1200  long long seek_frame = m_decoder->GetFramesPlayed();
1201  m_ffrewAdjust = target_frame - seek_frame;
1202  float adjustRatio = float(m_ffrewAdjust) / m_ffrewSkip;
1203  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1204  QString("skip %1, adjust, %2, ratio %3")
1205  .arg(m_ffrewSkip).arg(m_ffrewAdjust).arg(adjustRatio));
1206 
1207  // If the needed adjustment is too large either way, adjust the
1208  // scale factor up or down accordingly.
1209  if (adjustRatio < -ffrewSkipThresh
1210  && m_ffrewScale < (ffrewScaleHighest - 0.01F))
1212  else if (adjustRatio > ffrewSkipThresh
1213  && m_ffrewScale > (ffrewScaleLowest + 0.01F))
1215  return ret;
1216 }
1217 
1218 bool MythPlayer::DecoderGetFrame(DecodeType decodetype, bool unsafe)
1219 {
1220  bool ret = false;
1221  if (!m_videoOutput)
1222  return false;
1223 
1224  // Wait for frames to be available for decoding onto
1225  int tries = 0;
1226  while (!unsafe && (!m_videoOutput->EnoughFreeFrames() || m_audio.IsBufferAlmostFull()))
1227  {
1229  return false;
1230 
1231  if (++tries > 10)
1232  {
1233  if (++m_videobufRetries >= 2000)
1234  {
1235  LOG(VB_GENERAL, LOG_ERR, LOC +
1236  "Decoder timed out waiting for free video buffers.");
1237  // We've tried for 20 seconds now, give up so that we don't
1238  // get stuck permanently in this state
1239  SetErrored("Decoder timed out waiting for free video buffers.");
1240  }
1241  return false;
1242  }
1243  std::this_thread::sleep_for(1ms);
1244  }
1245  m_videobufRetries = 0;
1246 
1247  if (!m_decoderChangeLock.tryLock(5))
1248  return false;
1250  {
1251  m_decoderChangeLock.unlock();
1252  return false;
1253  }
1254 
1255  if (m_ffrewSkip == 1 || m_decodeOneFrame)
1256  ret = DoGetFrame(decodetype);
1257  else if (m_ffrewSkip != 0)
1258  ret = DecoderGetFrameFFREW();
1259  m_decoderChangeLock.unlock();
1260  return ret;
1261 }
1262 
1277 {
1278  bool ret = false;
1279  QElapsedTimer timeout;
1280  timeout.start();
1281  bool retry = true;
1282  // retry for a maximum of 5 seconds
1283  while (retry && !m_pauseDecoder && !m_killDecoder && !timeout.hasExpired(5000))
1284  {
1285  retry = false;
1286  ret = m_decoder->GetFrame(Type, retry);
1287  if (retry)
1288  {
1289  m_decoderChangeLock.unlock();
1290  QThread::usleep(10000);
1291  m_decoderChangeLock.lock();
1292  }
1293  }
1294 
1295  if (timeout.hasExpired(5000))
1296  return false;
1297  return ret;
1298 }
1299 
1300 void MythPlayer::WrapTimecode(std::chrono::milliseconds &timecode, TCTypes tc_type)
1301 {
1302  timecode += m_tcWrap[tc_type];
1303 }
1304 
1305 bool MythPlayer::PrepareAudioSample(std::chrono::milliseconds &timecode)
1306 {
1307  WrapTimecode(timecode, TC_AUDIO);
1308  return false;
1309 }
1310 
1312 {
1313  uint64_t bookmark = 0;
1314 
1317  bookmark = 0;
1318  else
1319  {
1320  m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
1321  if (const ProgramInfo *pi = m_playerCtx->m_playingInfo)
1322  {
1323  bookmark = pi->QueryBookmark();
1324  // Disable progstart if the program has a cutlist.
1325  if (bookmark == 0 && !pi->HasCutlist())
1326  bookmark = pi->QueryProgStart();
1327  if (bookmark == 0)
1328  bookmark = pi->QueryLastPlayPos();
1329  }
1330  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
1331  }
1332 
1333  return bookmark;
1334 }
1335 
1336 bool MythPlayer::UpdateFFRewSkip(float ffrewScale)
1337 {
1338  bool skip_changed = false;
1339 
1340  float temp_speed = (m_playSpeed == 0.0F) ?
1342  if (m_playSpeed >= 0.0F && m_playSpeed <= 3.0F)
1343  {
1344  skip_changed = (m_ffrewSkip != 1);
1345  if (m_decoder)
1347  m_frameInterval = microsecondsFromFloat((1000000.0 / m_videoFrameRate / static_cast<double>(temp_speed))
1348  / m_fpsMultiplier);
1349  m_ffrewSkip = static_cast<int>(m_playSpeed != 0.0F);
1350  }
1351  else
1352  {
1353  skip_changed = true;
1354  m_ffrewScale = ffrewScale;
1355  if (fabs(m_playSpeed) <= 10.0F)
1356  m_frameInterval = 200000us; // 5.00 fps
1357  else if (fabs(m_playSpeed) <= 20.0F)
1358  m_frameInterval = 160000us; // 6.25 fps
1359  else
1360  m_frameInterval = 133333us; // 7.50 fps
1362  float ffw_fps = fabs(static_cast<double>(m_playSpeed)) * m_videoFrameRate;
1363  float dis_fps = 1000000.0F / m_frameInterval.count();
1364  m_ffrewSkip = (int)ceil(ffw_fps / dis_fps);
1366  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1367  QString("new skip %1, interval %2, scale %3")
1368  .arg(m_ffrewSkip).arg(m_frameInterval.count()).arg(m_ffrewScale));
1369  m_ffrewAdjust = 0;
1370  }
1371 
1372  return skip_changed;
1373 }
1374 
1376 {
1377  float last_speed = m_playSpeed;
1381 
1382  bool skip_changed = UpdateFFRewSkip();
1383 
1384  if (skip_changed && m_videoOutput)
1385  {
1387  if (m_playSpeed != 0.0F && !(last_speed == 0.0F && m_ffrewSkip == 1))
1389  }
1390 
1391  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Play speed: " +
1392  QString("rate: %1 speed: %2 skip: %3 => new interval %4")
1393  .arg(m_videoFrameRate).arg(static_cast<double>(m_playSpeed))
1394  .arg(m_ffrewSkip).arg(m_frameInterval.count()));
1395 
1396  if (m_videoOutput)
1397  m_videoOutput->SetVideoFrameRate(static_cast<float>(m_videoFrameRate));
1398 
1400  {
1403  }
1404 }
1405 
1406 bool MythPlayer::DoRewind(uint64_t frames, double inaccuracy)
1407 {
1409  return false;
1410 
1411  uint64_t number = frames + 1;
1412  uint64_t desiredFrame = (m_framesPlayed > number) ? m_framesPlayed - number : 0;
1413 
1414  m_limitKeyRepeat = false;
1415  if (desiredFrame < m_videoFrameRate)
1416  m_limitKeyRepeat = true;
1417 
1418  uint64_t seeksnap_wanted = UINT64_MAX;
1419  if (inaccuracy != kInaccuracyFull)
1420  seeksnap_wanted = frames * inaccuracy;
1421  ClearBeforeSeek(frames);
1422  WaitForSeek(desiredFrame, seeksnap_wanted);
1423  m_rewindTime = 0;
1424  ClearAfterSeek();
1425  return true;
1426 }
1427 
1433 long long MythPlayer::CalcRWTime(long long rw) const
1434 {
1435  bool hasliveprev = (m_liveTV && m_playerCtx->m_tvchain &&
1437 
1438  if (!hasliveprev || ((int64_t)m_framesPlayed >= rw))
1439  {
1440  return rw;
1441  }
1442 
1443  auto seconds = secondsFromFloat((m_framesPlayed - rw) / m_videoFrameRate);
1444  m_playerCtx->m_tvchain->JumpToNext(false, seconds);
1445 
1446  return -1;
1447 }
1448 
1453 long long MythPlayer::CalcMaxFFTime(long long ffframes, bool setjump) const
1454 {
1455  float maxtime = 1.0;
1456  bool islivetvcur = (m_liveTV && m_playerCtx->m_tvchain &&
1458 
1459  if (m_liveTV || IsWatchingInprogress())
1460  maxtime = 3.0;
1461 
1462  long long ret = ffframes;
1463  float ff = ComputeSecs(ffframes, true);
1464  float secsPlayed = ComputeSecs(m_framesPlayed, true);
1465  float secsWritten = ComputeSecs(m_totalFrames, true);
1466 
1467  m_limitKeyRepeat = false;
1468 
1469  if (m_liveTV && !islivetvcur && m_playerCtx->m_tvchain)
1470  {
1471  // recording has completed, totalFrames will always be up to date
1472  if ((ffframes + m_framesPlayed > m_totalFrames) && setjump)
1473  {
1474  ret = -1;
1475  // Number of frames to be skipped is from the end of the current segment
1476  auto seconds = secondsFromFloat((m_totalFrames - m_framesPlayed - ffframes)
1477  / m_videoFrameRate);
1478  m_playerCtx->m_tvchain->JumpToNext(true, seconds);
1479  }
1480  }
1481  else if (islivetvcur || IsWatchingInprogress())
1482  {
1483  if ((ff + secsPlayed) > secsWritten)
1484  {
1485  // If we attempt to seek past the last known duration,
1486  // check for up to date data
1487  long long framesWritten = m_playerCtx->m_recorder->GetFramesWritten();
1488 
1489  secsWritten = ComputeSecs(framesWritten, true);
1490  }
1491 
1492  float behind = secsWritten - secsPlayed;
1493 
1494  if (behind < maxtime) // if we're close, do nothing
1495  ret = 0;
1496  else if (behind - ff <= maxtime)
1497  {
1498  auto msec = millisecondsFromFloat(1000 * (secsWritten - maxtime));
1499  ret = TranslatePositionMsToFrame(msec, true) - m_framesPlayed;
1500  }
1501 
1502  if (behind < maxtime * 3)
1503  m_limitKeyRepeat = true;
1504  }
1505  else if (IsPaused())
1506  {
1507  uint64_t lastFrame =
1509  if (m_framesPlayed + ffframes >= lastFrame)
1510  ret = lastFrame - 1 - m_framesPlayed;
1511  }
1512  else
1513  {
1514  float secsMax = secsWritten - 2.F * maxtime;
1515  if (secsMax <= 0.F)
1516  ret = 0;
1517  else if (secsMax < secsPlayed + ff)
1518  {
1519  auto msec = millisecondsFromFloat(1000 * secsMax);
1520  ret = TranslatePositionMsToFrame(msec, true) - m_framesPlayed;
1521  }
1522  }
1523 
1524  return ret;
1525 }
1526 
1534 {
1535  if (!m_videoOutput || !m_decoder)
1536  return false;
1537 
1538  return m_playerCtx->m_buffer->IsNearEnd(
1540 }
1541 
1545 {
1546  if (!m_playerCtx)
1547  return false;
1548 
1549  m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
1551  !m_decoder)
1552  {
1553  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
1554  return false;
1555  }
1556  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
1557 
1558  auto margin = (long long)(m_videoFrameRate * 2);
1559  margin = (long long) (margin * m_audio.GetStretchFactor());
1560  bool watchingTV = IsWatchingInprogress();
1561 
1562  uint64_t framesRead = m_framesPlayed;
1563  uint64_t framesLeft = 0;
1564 
1566  {
1567  if (framesRead >= m_deleteMap.GetLastFrame())
1568  return true;
1569  uint64_t frameCount = GetCurrentFrameCount();
1570  framesLeft = (frameCount > framesRead) ? frameCount - framesRead : 0;
1571  return (framesLeft < (uint64_t)margin);
1572  }
1573 
1574  if (!m_liveTV && !watchingTV)
1575  return false;
1576 
1578  return false;
1579 
1580  if (m_playerCtx->m_recorder)
1581  {
1582  framesLeft =
1584 
1585  // if it looks like we are near end, get an updated GetFramesWritten()
1586  if (framesLeft < (uint64_t)margin)
1587  framesLeft = m_playerCtx->m_recorder->GetFramesWritten() - framesRead;
1588  }
1589 
1590  return (framesLeft < (uint64_t)margin);
1591 }
1592 
1593 bool MythPlayer::DoFastForward(uint64_t frames, double inaccuracy)
1594 {
1596  return false;
1597 
1598  uint64_t number = (frames ? frames - 1 : 0);
1599  uint64_t desiredFrame = m_framesPlayed + number;
1600 
1601  if (!m_deleteMap.IsEditing() && IsInDelete(desiredFrame))
1602  {
1603  uint64_t endcheck = m_deleteMap.GetLastFrame();
1604  if (desiredFrame > endcheck)
1605  desiredFrame = endcheck;
1606  }
1607 
1608  uint64_t seeksnap_wanted = UINT64_MAX;
1609  if (inaccuracy != kInaccuracyFull)
1610  seeksnap_wanted = frames * inaccuracy;
1611  ClearBeforeSeek(frames);
1612  WaitForSeek(desiredFrame, seeksnap_wanted);
1613  m_ffTime = 0;
1614  ClearAfterSeek(false);
1615  return true;
1616 }
1617 
1618 void MythPlayer::DoJumpToFrame(uint64_t frame, double inaccuracy)
1619 {
1620  if (frame > m_framesPlayed)
1621  DoFastForward(frame - m_framesPlayed, inaccuracy);
1622  else
1623  DoRewind(m_framesPlayed - frame, inaccuracy);
1624 }
1625 
1626 void MythPlayer::WaitForSeek(uint64_t frame, uint64_t seeksnap_wanted)
1627 {
1628  if (!m_decoder)
1629  return;
1630 
1632  m_decoder->SetSeekSnap(seeksnap_wanted);
1633 
1634  bool islivetvcur = (m_liveTV && m_playerCtx->m_tvchain &&
1636 
1637  uint64_t max = GetCurrentFrameCount();
1638  if (islivetvcur || IsWatchingInprogress())
1639  {
1640  max = (uint64_t)m_playerCtx->m_recorder->GetFramesWritten();
1641  }
1642  if (frame >= max)
1643  frame = max - 1;
1644 
1645  m_decoderSeekLock.lock();
1646  m_decoderSeek = frame;
1647  m_decoderSeekLock.unlock();
1648 
1649  int count = 0;
1650  bool needclear = false;
1651  while (m_decoderSeek >= 0)
1652  {
1653  // Waiting blocks the main UI thread but the decoder may
1654  // have initiated a callback into the UI thread to create
1655  // certain resources. Ensure the callback is processed.
1656  // Ideally MythPlayer should be fully event driven and these
1657  // calls wouldn't be necessary.
1658  emit CheckCallbacks();
1659 
1660  // Wait a little
1661  std::this_thread::sleep_for(50ms);
1662 
1663  // provide some on screen feedback if seeking is slow
1664  count++;
1665  if (!(count % 3) && !m_hasFullPositionMap)
1666  {
1667  emit SeekingSlow(count);
1668  needclear = true;
1669  }
1670  }
1671  if (needclear)
1672  emit SeekingComplete();
1673 }
1674 
1687 void MythPlayer::ClearAfterSeek(bool clearvideobuffers)
1688 {
1689  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ClearAfterSeek(%1)")
1690  .arg(clearvideobuffers));
1691 
1692  if (clearvideobuffers && m_videoOutput)
1694 
1695  std::chrono::milliseconds savedTC = m_tcWrap[TC_AUDIO];
1696 
1697  m_tcWrap.fill(0ms);
1698  m_tcWrap[TC_AUDIO] = savedTC;
1699  m_audio.Reset();
1700 
1701  emit RequestResetCaptions();
1705  m_needNewPauseFrame = true;
1706 
1707  m_avSync.InitAVSync();
1708 }
1709 
1717 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
1718 void MythPlayer::ClearBeforeSeek(uint64_t Frames)
1719 {
1720 #ifdef USING_MEDIACODEC
1721  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("ClearBeforeSeek: decoder %1 frames %2 recording %3 livetv %4")
1722  .arg(m_codecName).arg(Frames).arg(m_watchingRecording).arg(m_liveTV));
1723 
1724  if ((Frames < 2) || !m_videoOutput /*|| !(m_liveTV || m_watchingRecording)*/)
1725  return;
1726 
1727  m_decoderChangeLock.lock();
1729  m_decoderChangeLock.unlock();
1730  if (codec_is_mediacodec(codec))
1731  m_videoOutput->DiscardFrames(true, true);
1732 #else
1733  Q_UNUSED(Frames);
1734 #endif
1735 }
1736 
1737 bool MythPlayer::IsInDelete(uint64_t frame)
1738 {
1739  return m_deleteMap.IsInDelete(frame);
1740 }
1741 
1743 {
1745 }
1746 
1747 QString MythPlayer::GetEncodingType(void) const
1748 {
1749  if (m_decoder)
1751  return QString();
1752 }
1753 
1755 {
1756  if (m_decoder)
1757  return m_decoder->GetRawAudioState();
1758  return false;
1759 }
1760 
1761 QString MythPlayer::GetXDS(const QString &key) const
1762 {
1763  if (!m_decoder)
1764  return QString();
1765  return m_decoder->GetXDS(key);
1766 }
1767 
1769 {
1771  m_forcePositionMapSync = true;
1772 }
1773 
1774 // Returns the total frame count, as totalFrames for a completed
1775 // recording, or the most recent frame count from the recorder for
1776 // live TV or an in-progress recording.
1778 {
1779  uint64_t result = m_totalFrames;
1780  if (IsWatchingInprogress())
1782  return result;
1783 }
1784 
1785 // Finds the frame number associated with the given time offset. A
1786 // positive offset or +0.0F indicate offset from the beginning. A
1787 // negative offset or -0.0F indicate offset from the end. Limit the
1788 // result to within bounds of the video.
1789 uint64_t MythPlayer::FindFrame(float offset, bool use_cutlist) const
1790 {
1791  bool islivetvcur = (m_liveTV && m_playerCtx->m_tvchain &&
1793  std::chrono::milliseconds length_ms = TranslatePositionFrameToMs(m_totalFrames, use_cutlist);
1794  std::chrono::milliseconds position_ms = 0ms;
1795  auto offset_ms = std::chrono::milliseconds(llroundf(fabsf(offset) * 1000));
1796 
1797  if (signbit(offset))
1798  {
1799  // Always get an updated totalFrame value for in progress recordings
1800  if (islivetvcur || IsWatchingInprogress())
1801  {
1802  uint64_t framesWritten = m_playerCtx->m_recorder->GetFramesWritten();
1803 
1804  if (m_totalFrames < framesWritten)
1805  {
1806  // Known duration is less than what the backend reported, use new value
1807  length_ms =
1808  TranslatePositionFrameToMs(framesWritten, use_cutlist);
1809  }
1810  }
1811  position_ms = (offset_ms > length_ms) ? 0ms : length_ms - offset_ms;
1812  }
1813  else
1814  {
1815  position_ms = offset_ms;
1816  if (offset_ms > length_ms)
1817  {
1818  // Make sure we have an updated totalFrames
1819  if ((islivetvcur || IsWatchingInprogress()) &&
1820  (length_ms < offset_ms))
1821  {
1822  long long framesWritten =
1824 
1825  length_ms =
1826  TranslatePositionFrameToMs(framesWritten, use_cutlist);
1827  }
1828  position_ms = std::min(position_ms, length_ms);
1829  }
1830  }
1831  return TranslatePositionMsToFrame(position_ms, use_cutlist);
1832 }
1833 
1834 // If position == -1, it signifies that we are computing the current
1835 // duration of an in-progress recording. In this case, we fetch the
1836 // current frame rate and frame count from the recorder.
1837 std::chrono::milliseconds MythPlayer::TranslatePositionFrameToMs(uint64_t position,
1838  bool use_cutlist) const
1839 {
1840  float frameRate = GetFrameRate();
1841  if (position == UINT64_MAX &&
1843  {
1844  float recorderFrameRate = m_playerCtx->m_recorder->GetFrameRate();
1845  if (recorderFrameRate > 0)
1846  frameRate = recorderFrameRate;
1847  position = m_playerCtx->m_recorder->GetFramesWritten();
1848  }
1849  return m_deleteMap.TranslatePositionFrameToMs(position, frameRate,
1850  use_cutlist);
1851 }
1852 
1854 {
1855  if (m_decoder)
1856  return m_decoder->GetNumChapters();
1857  return 0;
1858 }
1859 
1861 {
1862  if (m_decoder)
1864  return 0;
1865 }
1866 
1867 void MythPlayer::GetChapterTimes(QList<std::chrono::seconds> &times)
1868 {
1869  if (m_decoder)
1870  m_decoder->GetChapterTimes(times);
1871 }
1872 
1873 bool MythPlayer::DoJumpChapter(int chapter)
1874 {
1875  int64_t desiredFrame = -1;
1876  int total = GetNumChapters();
1877  int current = GetCurrentChapter();
1878 
1879  if (chapter < 0 || chapter > total)
1880  {
1881 
1882  if (chapter < 0)
1883  {
1884  chapter = current -1;
1885  if (chapter < 0) chapter = 0;
1886  }
1887  else if (chapter > total)
1888  {
1889  chapter = current + 1;
1890  if (chapter > total) chapter = total;
1891  }
1892  }
1893 
1894  desiredFrame = GetChapter(chapter);
1895  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1896  QString("DoJumpChapter: current %1 want %2 (frame %3)")
1897  .arg(current).arg(chapter).arg(desiredFrame));
1898 
1899  if (desiredFrame < 0)
1900  {
1901  LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("DoJumpChapter failed."));
1902  m_jumpChapter = 0;
1903  return false;
1904  }
1905 
1906  DoJumpToFrame(desiredFrame, kInaccuracyNone);
1907  m_jumpChapter = 0;
1908  return true;
1909 }
1910 
1911 int64_t MythPlayer::GetChapter(int chapter)
1912 {
1913  if (m_decoder)
1914  return m_decoder->GetChapter(chapter);
1915  return 0;
1916 }
1917 
1922 {
1923  m_totalDecoderPause = true;
1924  PauseDecoder();
1925 
1926  {
1927  while (!m_decoderChangeLock.tryLock(10))
1928  LOG(VB_GENERAL, LOG_INFO, LOC + "Waited 10ms for decoder lock");
1929  delete m_decoder;
1930  m_decoder = dec;
1931  if (m_decoder)
1933  m_decoderChangeLock.unlock();
1934  }
1935  // reset passthrough override
1936  m_disablePassthrough = false;
1938  m_totalDecoderPause = false;
1939 }
1940 
1941 bool MythPlayer::PosMapFromEnc(uint64_t start,
1942  frm_pos_map_t &posMap,
1943  frm_pos_map_t &durMap)
1944 {
1945  // Reads only new positionmap entries from encoder
1946  if (!(m_liveTV || (m_playerCtx->m_recorder &&
1948  return false;
1949 
1950  // if livetv, and we're not the last entry, don't get it from the encoder
1951  if (HasTVChainNext())
1952  return false;
1953 
1954  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1955  QString("Filling position map from %1 to %2") .arg(start).arg("end"));
1956 
1957  m_playerCtx->m_recorder->FillPositionMap(start, -1, posMap);
1958  m_playerCtx->m_recorder->FillDurationMap(start, -1, durMap);
1959 
1960  return true;
1961 }
1962 
1963 void MythPlayer::SetErrored(const QString &reason)
1964 {
1965  QMutexLocker locker(&m_errorLock);
1966 
1967  if (m_videoOutput)
1969 
1970  if (m_errorMsg.isEmpty())
1971  {
1972  m_errorMsg = reason;
1973  }
1974  else
1975  {
1976  LOG(VB_GENERAL, LOG_ERR, LOC + QString("%1").arg(reason));
1977  }
1978 }
1979 
1981 {
1982  QMutexLocker locker(&m_errorLock);
1983 
1984  m_errorMsg = QString();
1985 }
1986 
1987 bool MythPlayer::IsErrored(void) const
1988 {
1989  QMutexLocker locker(&m_errorLock);
1990  return !m_errorMsg.isEmpty();
1991 }
1992 
1993 QString MythPlayer::GetError(void) const
1994 {
1995  QMutexLocker locker(&m_errorLock);
1996  return m_errorMsg;
1997 }
1998 
2000 {
2001  if (!m_decoder)
2002  return;
2003 
2005 }
2006 
2008 {
2009  if (!m_decoder)
2010  return;
2011 
2013 }
2014 
2016 {
2017  if (!m_decoder)
2018  return;
2019 
2021 }
2022 
2024 {
2025  if (m_decoder && m_audio.HasAudioOut())
2026  {
2027  float stretch = m_audio.GetStretchFactor();
2028  m_disablePassthrough |= (stretch < 0.99F) || (stretch > 1.01F);
2029  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2030  QString("Stretch Factor %1, %2 passthru ")
2031  .arg(m_audio.GetStretchFactor())
2032  .arg((m_disablePassthrough) ? "disable" : "allow"));
2034  }
2035 }
2036 
2038 {
2039  if (m_decoder && m_audio.HasAudioOut())
2041 }
2042 
2044 {
2045  if (m_decoder && m_audio.HasAudioOut())
2047 }
2048 
2049 static unsigned dbg_ident(const MythPlayer *player)
2050 {
2051  static QMutex s_dbgLock;
2052  static unsigned s_dbgNextIdent = 0;
2053  using DbgMapType = QHash<const MythPlayer*, unsigned>;
2054  static DbgMapType s_dbgIdent;
2055 
2056  QMutexLocker locker(&s_dbgLock);
2057  DbgMapType::iterator it = s_dbgIdent.find(player);
2058  if (it != s_dbgIdent.end())
2059  return *it;
2060  return s_dbgIdent[player] = s_dbgNextIdent++;
2061 }
MythPlayer::IsNearEnd
bool IsNearEnd(void)
Returns true iff near end of recording.
Definition: mythplayer.cpp:1544
DeleteMap::SetPlayerContext
void SetPlayerContext(PlayerContext *ctx)
Definition: deletemap.h:31
DecoderBase::GetCurrentChapter
virtual int GetCurrentChapter(long long)
Definition: decoderbase.h:155
kLiveTVAutoExpire
@ kLiveTVAutoExpire
Definition: programtypes.h:198
kDecodeAV
@ kDecodeAV
Definition: decoderbase.h:52
MythPlayer::m_buffering
bool m_buffering
Definition: mythplayer.h:456
DecoderBase::DoFastForward
virtual bool DoFastForward(long long desiredFrame, bool discardFrames=true)
Skips ahead or rewinds to desiredFrame.
Definition: decoderbase.cpp:710
secondsFromFloat
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::seconds > secondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:80
MythTimer::elapsed
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:91
build_compdb.dest
dest
Definition: build_compdb.py:9
dbg_ident
static unsigned dbg_ident(const MythPlayer *)
Definition: mythplayer.cpp:2049
PlayerContext::GetState
TVState GetState(void) const
Definition: playercontext.cpp:333
MythPlayer::m_enableForcedSubtitles
bool m_enableForcedSubtitles
Definition: mythplayer.h:471
LiveTVChain::GetCurPos
int GetCurPos(void) const
Definition: livetvchain.h:57
MythPlayer::m_errorLock
QMutex m_errorLock
Definition: mythplayer.h:407
MThread::start
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:286
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
kDecoderProbeBufferSize
const int kDecoderProbeBufferSize
Definition: decoderbase.h:22
MythPlayer::m_videoPaused
bool m_videoPaused
Definition: mythplayer.h:400
MythPlayer::m_decoderChangeLock
QRecursiveMutex m_decoderChangeLock
Definition: mythplayer.h:370
MythVideoOutput::InputChanged
virtual bool InputChanged(QSize VideoDim, QSize VideoDispDim, float VideoAspect, MythCodecID CodecID, bool &AspectChanged, int ReferenceFrames, bool ForceChange)
Tells video output to discard decoded frames and wait for new ones.
Definition: mythvideoout.cpp:186
DecoderBase::GetFramesPlayed
long long GetFramesPlayed(void) const
Definition: decoderbase.h:204
MythPlayer::SetFileLength
void SetFileLength(std::chrono::seconds total, int frames)
Definition: mythplayer.cpp:387
PlayerContext::UnlockPlayingInfo
void UnlockPlayingInfo(const char *file, int line) const
Definition: playercontext.cpp:245
MythPlayer::m_watchingRecording
bool m_watchingRecording
Definition: mythplayer.h:411
MythVideoOutputNull::Create
static MythVideoOutputNull * Create(QSize VideoDim, QSize VideoDispDim, float VideoAspect, MythCodecID CodecID)
Definition: mythvideooutnull.cpp:52
LiveTVChain::JumpToNext
void JumpToNext(bool up, std::chrono::seconds pos)
jump to the next (up == true) or previous (up == false) liveTV program If pos > 0: indicate the absol...
Definition: livetvchain.cpp:616
RemoteEncoder::GetRecorderNumber
int GetRecorderNumber(void) const
Definition: remoteencoder.cpp:61
MythPlayer::SetEof
void SetEof(EofState eof)
Definition: mythplayer.cpp:1068
MythPlayer::m_inJumpToProgramPause
bool m_inJumpToProgramPause
Definition: mythplayer.h:393
AudioPlayer::Reset
void Reset(void)
Definition: audioplayer.cpp:83
MythPlayer::m_bufferPaused
bool m_bufferPaused
Definition: mythplayer.h:399
MythPlayer::m_commBreakMap
CommBreakMap m_commBreakMap
Definition: mythplayer.h:483
DecoderBase::GetEof
EofState GetEof(void)
Definition: decoderbase.h:135
MythPlayer::ChangeSpeed
virtual void ChangeSpeed(void)
Definition: mythplayer.cpp:1375
MythPlayer::m_decoderThread
MythDecoderThread * m_decoderThread
Definition: mythplayer.h:375
MythPlayer::m_cc608
CC608Reader m_cc608
Definition: mythplayer.h:476
DeleteMap::TrackerReset
void TrackerReset(uint64_t frame)
Resets the internal state tracker.
Definition: deletemap.cpp:806
kEofStateNone
@ kEofStateNone
Definition: decoderbase.h:69
MythPlayer::m_bufferingCounter
int m_bufferingCounter
Definition: mythplayer.h:515
PlayerContext::SetPlayingInfo
void SetPlayingInfo(const ProgramInfo *info)
assign programinfo to the context
Definition: playercontext.cpp:507
MythTimer
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
MythPlayer::kNightModeContrastAdjustment
static const int kNightModeContrastAdjustment
Definition: mythplayer.h:243
LiveTVChain::HasNext
bool HasNext(void) const
Definition: livetvchain.cpp:405
MythPlayer::CheckCallbacks
void CheckCallbacks()
MythPlayer::m_ffrewAdjust
int m_ffrewAdjust
offset after last skip
Definition: mythplayer.h:501
MythPlayer::m_decoderThreadUnpause
QWaitCondition m_decoderThreadUnpause
Definition: mythplayer.h:384
kCodec_NONE
@ kCodec_NONE
Definition: mythcodecid.h:14
MythPlayer::UnpauseBuffer
void UnpauseBuffer(void)
Definition: mythplayer.cpp:150
MythPlayer::SeekingSlow
void SeekingSlow(int Count)
MythPlayer::m_avSync
MythPlayerAVSync m_avSync
Definition: mythplayer.h:438
MythPlayer::DecoderPauseCheck
virtual void DecoderPauseCheck(void)
Definition: mythplayer.cpp:1043
MythPlayer::m_playSpeed
float m_playSpeed
Definition: mythplayer.h:496
MythVideoOutput::FreeVideoFrames
int FreeVideoFrames()
Returns number of frames available for decoding onto.
Definition: mythvideoout.cpp:283
MythPlayer::m_frameInterval
std::chrono::microseconds m_frameInterval
always adjusted for play_speed
Definition: mythplayer.h:498
kMusicChoice
@ kMusicChoice
Definition: mythplayer.h:77
RemoteEncoder::FillDurationMap
void FillDurationMap(int64_t start, int64_t end, frm_pos_map_t &durationMap)
Definition: remoteencoder.cpp:293
MythVideoOutput::GetError
VideoErrorState GetError() const
Definition: mythvideoout.cpp:259
MThread::wait
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:303
ffrewSkipThresh
static float ffrewSkipThresh
Definition: mythplayer.cpp:1152
MythPlayer::CheckTVChain
void CheckTVChain()
Definition: mythplayer.cpp:918
MythPlayer::m_totalDecoderPause
bool m_totalDecoderPause
Definition: mythplayer.h:391
MythPlayer::OpenFile
virtual int OpenFile(int Retries=4)
Definition: mythplayer.cpp:420
DeleteMap::TranslatePositionFrameToMs
std::chrono::milliseconds TranslatePositionFrameToMs(uint64_t position, float fallback_framerate, bool use_cutlist) const
Definition: deletemap.cpp:895
MythPlayer::m_nextNormalSpeed
bool m_nextNormalSpeed
Definition: mythplayer.h:504
CardUtil::SetStartChannel
static bool SetStartChannel(uint inputid, const QString &channum)
Definition: cardutil.cpp:1607
MythPlayer::PrebufferEnoughFrames
virtual bool PrebufferEnoughFrames(int min_buffers=0)
Definition: mythplayer.cpp:707
MythPlayer::m_totalDuration
std::chrono::seconds m_totalDuration
Definition: mythplayer.h:435
CommBreakMap::SetTracker
void SetTracker(uint64_t framesPlayed)
Definition: commbreakmap.cpp:66
MythPlayer::PrepareAudioSample
virtual bool PrepareAudioSample(std::chrono::milliseconds &timecode)
Definition: mythplayer.cpp:1305
DetectLetterbox.h
MythPlayer::m_videobufRetries
int m_videobufRetries
How often we have tried to wait for a video output buffer and failed.
Definition: mythplayer.h:431
MythPlayer::IsPaused
bool IsPaused(void) const
Definition: mythplayer.h:154
MythPlayer::m_decoderSeekLock
QMutex m_decoderSeekLock
Definition: mythplayer.h:386
ProgramInfo::GetChanNum
QString GetChanNum(void) const
This is the channel "number", in the form 1, 1_2, 1-2, 1#1, etc.
Definition: programinfo.h:376
MythPlayer::m_forcePositionMapSync
bool m_forcePositionMapSync
Definition: mythplayer.h:484
chronomult
static constexpr T chronomult(T duration, double f)
Multiply a duration by a float, returning a duration.
Definition: mythchrono.h:199
MythPlayer::HasReachedEof
virtual bool HasReachedEof(void) const
Definition: mythplayer.cpp:643
MythPlayer::AudioEnd
virtual void AudioEnd(void)
Definition: mythplayer.cpp:948
TC_VIDEO
@ TC_VIDEO
Definition: mythplayer.h:57
MythCoreContext::IsDatabaseIgnored
bool IsDatabaseIgnored(void) const
/brief Returns true if database is being ignored.
Definition: mythcorecontext.cpp:900
ffrewScaleAdjust
static float ffrewScaleAdjust
Definition: mythplayer.cpp:1151
microsecondsFromFloat
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::microseconds > microsecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:102
ProgramInfo::GetChannelSchedulingID
QString GetChannelSchedulingID(void) const
This is the unique programming identifier of a channel.
Definition: programinfo.h:383
AudioPlayer::SetStretchFactor
void SetStretchFactor(float factor)
Definition: audioplayer.cpp:369
MythPlayer::m_ffrewSkip
int m_ffrewSkip
Definition: mythplayer.h:500
frm_dir_map_t
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
Definition: programtypes.h:119
FrameScanType
FrameScanType
Definition: videoouttypes.h:94
MythPlayer::syncWithAudioStretch
void syncWithAudioStretch()
Definition: mythplayer.cpp:2023
MythPlayer::m_errorMsg
QString m_errorMsg
Reason why NVP exited with a error.
Definition: mythplayer.h:408
MythPlayer::m_bufferPauseLock
QMutex m_bufferPauseLock
Definition: mythplayer.h:387
AudioPlayer::CheckFormat
void CheckFormat(void)
Definition: audioplayer.cpp:172
DecoderBase::IsErrored
bool IsErrored() const
Definition: decoderbase.h:225
AudioPlayer::IsBufferAlmostFull
bool IsBufferAlmostFull(void)
Definition: audioplayer.cpp:493
MythPlayer::SaveTotalFrames
void SaveTotalFrames(void)
Definition: mythplayer.cpp:2015
MythPlayer::IsErrored
bool IsErrored(void) const
Definition: mythplayer.cpp:1987
MythPlayer::m_normalSpeed
bool m_normalSpeed
Definition: mythplayer.h:505
RemoteEncoder::GetFramesWritten
long long GetFramesWritten(void)
Returns number of frames written to disk by TVRec's RecorderBase instance.
Definition: remoteencoder.cpp:193
CC608Reader::SetTTPageNum
void SetTTPageNum(int page)
Definition: cc608reader.h:85
MythPlayer::GetFrameRate
float GetFrameRate(void) const
Definition: mythplayer.h:136
MythTimer::start
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
MythMediaBuffer::Unpause
void Unpause(void)
Unpauses the read-ahead thread. Calls StartReads(void).
Definition: mythmediabuffer.cpp:697
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythMediaBuffer::GetSafeFilename
QString GetSafeFilename(void)
Definition: mythmediabuffer.cpp:1747
MythPlayer::GetCurrentFrameCount
uint64_t GetCurrentFrameCount(void) const
Definition: mythplayer.cpp:1777
MythPlayer::IsPlaying
bool IsPlaying(std::chrono::milliseconds wait_in_msec=0ms, bool wait_for=true) const
Definition: mythplayer.cpp:257
AudioPlayer::HasAudioOut
bool HasAudioOut(void) const
Definition: audioplayer.h:58
VBIMode::Parse
static uint Parse(const QString &vbiformat)
Definition: tv.h:16
DeleteMap::IsEmpty
bool IsEmpty(void) const
Definition: deletemap.cpp:259
is_current_thread
bool is_current_thread(MThread *thread)
Use this to determine if you are in the named thread.
Definition: mthread.cpp:40
mythplayer.h
MythPlayer::m_pauseLock
QMutex m_pauseLock
Definition: mythplayer.h:389
MythVideoOutput::SetFramesPlayed
virtual void SetFramesPlayed(long long FramesPlayed)
Definition: mythvideoout.cpp:244
MythPlayer::CalcRWTime
long long CalcRWTime(long long rw) const
CalcRWTime(rw): rewind rw frames back.
Definition: mythplayer.cpp:1433
PlayerFlags
PlayerFlags
Definition: mythplayer.h:65
MythPlayer::GetEof
EofState GetEof(void) const
Definition: mythplayer.cpp:1055
MythPlayer::Pause
bool Pause(void)
Definition: mythplayer.cpp:159
MythPlayer
Definition: mythplayer.h:86
RemoteEncoder::IsValidRecorder
bool IsValidRecorder(void) const
Definition: remoteencoder.cpp:56
ffrewScaleHighest
static float ffrewScaleHighest
Definition: mythplayer.cpp:1154
MythPlayer::GetBookmark
virtual uint64_t GetBookmark(void)
Definition: mythplayer.cpp:1311
DecoderBase::GetVideoCodecID
virtual MythCodecID GetVideoCodecID(void) const =0
MythPlayer::m_nextPlaySpeed
float m_nextPlaySpeed
Definition: mythplayer.h:495
MythPlayer::m_bufferingLastMsg
QTime m_bufferingLastMsg
Definition: mythplayer.h:458
MythPlayer::SeekingComplete
void SeekingComplete()
CommBreakMap::SetMap
void SetMap(const frm_dir_map_t &newMap, uint64_t framesPlayed)
Definition: commbreakmap.cpp:130
hardwareprofile.scan.scan
def scan(profile, smoonURL, gate)
Definition: scan.py:57
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
MythPlayer::m_videoPauseLock
QMutex m_videoPauseLock
Definition: mythplayer.h:388
MythPlayer::SetErrored
void SetErrored(const QString &reason)
Definition: mythplayer.cpp:1963
MythPlayer::GetEncodingType
QString GetEncodingType(void) const
Definition: mythplayer.cpp:1747
MythPlayer::DiscardVideoFrames
void DiscardVideoFrames(bool KeyFrame, bool Flushed)
Places frames in the available frames queue.
Definition: mythplayer.cpp:637
MythPlayer::m_needNewPauseFrame
bool m_needNewPauseFrame
Definition: mythplayer.h:398
MythMediaBuffer::GetStopReads
bool GetStopReads(void) const
Definition: mythmediabuffer.cpp:1778
DeleteMap::TrackerWantsToJump
bool TrackerWantsToJump(uint64_t frame, uint64_t &to) const
Returns true if the given frame has passed the last cut point start and provides the frame number of ...
Definition: deletemap.cpp:840
MythPlayer::SetDecoder
void SetDecoder(DecoderBase *dec)
Sets the stream decoder, deleting any existing recorder.
Definition: mythplayer.cpp:1921
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
MythPlayer::kInaccuracyNone
static const double kInaccuracyNone
Definition: mythplayer.h:244
MythVideoOutput::SetPrebuffering
void SetPrebuffering(bool Normal)
Sets whether to use a normal number of buffers or fewer buffers.
Definition: mythvideoout.cpp:265
MythPlayerAVSync::ResetAVSyncForLiveTV
bool ResetAVSyncForLiveTV(AudioPlayer *Audio)
Definition: mythplayeravsync.cpp:55
MythPlayer::ResetErrored
void ResetErrored(void)
Definition: mythplayer.cpp:1980
DecoderBase::GetChapter
virtual long long GetChapter(int)
Definition: decoderbase.h:157
MythPlayer::HasTVChainNext
bool HasTVChainNext(void) const
Definition: mythplayer.cpp:1742
MythPlayer::GetRawAudioState
bool GetRawAudioState(void) const
Definition: mythplayer.cpp:1754
MythPlayer::~MythPlayer
~MythPlayer() override
Definition: mythplayer.cpp:113
EofState
EofState
Definition: decoderbase.h:67
mythdecoderthread.h
MythPlayer::m_audio
AudioPlayer m_audio
Definition: mythplayer.h:480
DecoderBase::GetChapterTimes
virtual void GetChapterTimes(QList< std::chrono::seconds > &)
Definition: decoderbase.h:156
MythCodecID
MythCodecID
Definition: mythcodecid.h:10
MythPlayer::PauseChanged
void PauseChanged(bool Paused)
DecoderBase::SaveTotalDuration
void SaveTotalDuration(void)
Definition: decoderbase.cpp:1241
MythMediaBuffer::GetFilename
QString GetFilename(void) const
Definition: mythmediabuffer.cpp:1739
MythPlayer::UnpauseVideo
void UnpauseVideo(void)
Definition: mythplayer.cpp:230
MythPlayer::m_decoder
DecoderBase * m_decoder
Definition: mythplayer.h:366
MythPlayer::ComputeSecs
float ComputeSecs(uint64_t position, bool use_cutlist) const
Definition: mythplayer.h:276
RemoteEncoder::GetCachedFramesWritten
long long GetCachedFramesWritten(void) const
Return value last returned by GetFramesWritten().
Definition: remoteencoder.h:40
MythPlayer::m_framesPlayed
uint64_t m_framesPlayed
Definition: mythplayer.h:432
MythPlayer::m_rewindTime
long long m_rewindTime
Definition: mythplayer.h:436
DecoderBase::ForceSetupAudioStream
virtual void ForceSetupAudioStream(void)
Definition: decoderbase.h:147
MythPlayer::kNightModeBrightenssAdjustment
static const int kNightModeBrightenssAdjustment
Definition: mythplayer.h:242
programinfo.h
mythvideooutnull.h
MythPlayer::GetChapter
virtual int64_t GetChapter(int chapter)
Definition: mythplayer.cpp:1911
mythlogging.h
codec_is_mediacodec
#define codec_is_mediacodec(id)
Definition: mythcodecid.h:323
MythVideoOutput::ValidVideoFrames
virtual int ValidVideoFrames() const
Returns number of frames that are fully decoded.
Definition: mythvideoout.cpp:277
CommBreakMap::ResetLastSkip
void ResetLastSkip(void)
Definition: commbreakmap.cpp:26
MythPlayer::m_ffTime
long long m_ffTime
If m_ffTime>0, number of frames to seek forward.
Definition: mythplayer.h:427
MythMediaBuffer::WaitForPause
void WaitForPause(void)
Waits for Pause(void) to take effect.
Definition: mythmediabuffer.cpp:711
AudioPlayer::DeleteOutput
void DeleteOutput(void)
Definition: audioplayer.cpp:92
kScan_Progressive
@ kScan_Progressive
Definition: videoouttypes.h:100
MythPlayer::ClearBeforeSeek
void ClearBeforeSeek(uint64_t Frames)
Discard video frames prior to seeking.
Definition: mythplayer.cpp:1718
PlayerContext::m_playingInfo
ProgramInfo * m_playingInfo
Currently playing info.
Definition: playercontext.h:120
tv_actions.h
MythPlayer::m_tcWrap
tctype_arr m_tcWrap
Definition: mythplayer.h:508
MythPlayer::DecoderGetFrame
bool DecoderGetFrame(DecodeType decodetype, bool unsafe=false)
Definition: mythplayer.cpp:1218
MythPlayer::SetPlayingInfo
void SetPlayingInfo(const ProgramInfo &pginfo)
Definition: mythplayer.cpp:237
MythVideoOutput::ClearAfterSeek
virtual void ClearAfterSeek()
Tells video output to toss decoded buffers due to a seek.
Definition: mythvideoout.cpp:271
MythPlayer::m_captionsEnabledbyDefault
bool m_captionsEnabledbyDefault
This allows us to enable captions/subtitles later if the streams are not immediately available when t...
Definition: mythplayer.h:470
MythVideoOutput::DeLimboFrame
virtual void DeLimboFrame(MythVideoFrame *Frame)
Releases a frame for reuse if it is in limbo.
Definition: mythvideoout.cpp:402
RemoteEncoder::GetFrameRate
float GetFrameRate(void)
Returns recordering frame rate set by nvr.
Definition: remoteencoder.cpp:158
hardwareprofile.i18n.t
t
Definition: i18n.py:36
PlayerContext::LockPlayingInfo
void LockPlayingInfo(const char *file, int line) const
Definition: playercontext.cpp:233
MythPlayer::FindFrame
uint64_t FindFrame(float offset, bool use_cutlist) const
Definition: mythplayer.cpp:1789
MythPlayer::m_bookmarkSeek
uint64_t m_bookmarkSeek
Definition: mythplayer.h:420
MythVideoFrame::m_timecode
std::chrono::milliseconds m_timecode
Definition: mythframe.h:131
DecoderBase::GetfpsMultiplier
int GetfpsMultiplier(void) const
Definition: decoderbase.h:262
MythPlayer::DoJumpChapter
virtual bool DoJumpChapter(int chapter)
Definition: mythplayer.cpp:1873
MythVideoOutput::GetFrameStatus
QString GetFrameStatus() const
Returns string with status of each frame for debugging.
Definition: mythvideoout.cpp:308
MythPlayer::SetDuration
void SetDuration(std::chrono::seconds duration)
Definition: mythplayer.cpp:393
MythPlayer::m_videoOutput
MythVideoOutput * m_videoOutput
Definition: mythplayer.h:372
MythPlayer::m_hasFullPositionMap
bool m_hasFullPositionMap
Definition: mythplayer.h:413
MythPlayer::IsInDelete
bool IsInDelete(uint64_t frame)
Definition: mythplayer.cpp:1737
MythPlayer::m_clearSavedPosition
int m_clearSavedPosition
Definition: mythplayer.h:421
PlayerContext::m_buffer
MythMediaBuffer * m_buffer
Definition: playercontext.h:119
MythPlayer::MythDecoderThread
friend class MythDecoderThread
Definition: mythplayer.h:94
MythPlayer::MythPlayer
MythPlayer(PlayerContext *Context, PlayerFlags Flags=kNoFlags)
Definition: mythplayer.cpp:85
ScanTypeToString
QString ScanTypeToString(FrameScanType Scan)
Definition: videoouttypes.h:211
DecodeType
DecodeType
Definition: decoderbase.h:47
MythPlayer::m_decoderPauseLock
QMutex m_decoderPauseLock
Definition: mythplayer.h:385
MythPlayerAVSync::GetAVSyncAudioPause
bool GetAVSyncAudioPause() const
Definition: mythplayeravsync.cpp:45
MythVideoOutput::GetNextFreeFrame
virtual MythVideoFrame * GetNextFreeFrame()
Blocks until it is possible to return a frame for decoding onto.
Definition: mythvideoout.cpp:389
MythPlayer::InitVideo
virtual bool InitVideo(void)
Definition: mythplayer.cpp:276
MythPlayer::WrapTimecode
void WrapTimecode(std::chrono::milliseconds &timecode, TCTypes tc_type)
Definition: mythplayer.cpp:1300
MythPlayer::PauseVideo
void PauseVideo(void)
Definition: mythplayer.cpp:222
DeleteMap::IsInDelete
bool IsInDelete(uint64_t frame) const
Returns true if the given frame is deemed to be within a region that should be cut.
Definition: deletemap.cpp:570
DecoderBase::ResetTotalDuration
void ResetTotalDuration(void)
Definition: decoderbase.h:259
MythPlayer::ClearAfterSeek
void ClearAfterSeek(bool clearvideobuffers=true)
This is to support seeking...
Definition: mythplayer.cpp:1687
MythPlayer::m_bufferingStart
QTime m_bufferingStart
Definition: mythplayer.h:457
MythPlayer::m_ttPageNum
int m_ttPageNum
VBI page to display when in PAL vbimode.
Definition: mythplayer.h:463
MythPlayer::SetBuffering
void SetBuffering(bool new_buffering)
Definition: mythplayer.cpp:687
MythPlayer::PauseDecoder
bool PauseDecoder(void)
Definition: mythplayer.cpp:953
DeleteMap::LoadMap
void LoadMap(const QString &undoMessage="")
Loads the delete map from the database.
Definition: deletemap.cpp:737
TCTypes
TCTypes
Timecode types.
Definition: mythplayer.h:55
MythPlayer::m_totalFrames
uint64_t m_totalFrames
Definition: mythplayer.h:433
hardwareprofile.smolt.long
long
Definition: smolt.py:76
MythPlayer::ResetPlaying
virtual void ResetPlaying(bool resetframes=true)
Definition: mythplayer.cpp:904
MythPlayerAVSync::SetAVSyncMusicChoice
void SetAVSyncMusicChoice(AudioPlayer *Audio)
Definition: mythplayeravsync.cpp:64
MythPlayer::m_videoFrameRate
double m_videoFrameRate
Video (input) Frame Rate (often inaccurate)
Definition: mythplayer.h:443
MythPlayer::UpdateFFRewSkip
bool UpdateFFRewSkip(float ffrewScale=1.0F)
Definition: mythplayer.cpp:1336
get_encoding_type
QString get_encoding_type(MythCodecID codecid)
Definition: mythcodecid.cpp:475
MythVideoOutput::GetFramesPlayed
virtual long long GetFramesPlayed()
Definition: mythvideoout.cpp:249
TestBufferVec
std::vector< char > TestBufferVec
Definition: decoderbase.h:23
DecoderBase::GetXDS
virtual QString GetXDS(const QString &) const
Definition: decoderbase.h:249
jitterometer.h
MythPlayer::m_playerCtx
PlayerContext * m_playerCtx
Definition: mythplayer.h:374
DecoderBase::GetFPS
virtual double GetFPS(void) const
Definition: decoderbase.h:198
MythPlayer::m_forcedVideoAspect
float m_forcedVideoAspect
Definition: mythplayer.h:450
MythPlayer::m_videoDispDim
QSize m_videoDispDim
Video (input) width & height.
Definition: mythplayer.h:446
MythPlayer::DeLimboFrame
void DeLimboFrame(MythVideoFrame *frame)
Definition: mythplayer.cpp:657
MythVideoOutput::DiscardFrames
virtual void DiscardFrames(bool KeyFrame, bool Flushed)
Releases all frames not being actively displayed from any queue onto the queue of frames ready for de...
Definition: mythvideoout.cpp:430
MythPlayer::m_codecName
QString m_codecName
Codec Name - used by playback profile.
Definition: mythplayer.h:445
AvFormatDecoder
A decoder for media files.
Definition: avformatdecoder.h:82
MythPlayer::PosMapFromEnc
bool PosMapFromEnc(uint64_t start, frm_pos_map_t &posMap, frm_pos_map_t &durMap)
Definition: mythplayer.cpp:1941
MythPlayer::m_latestVideoTimecode
std::chrono::milliseconds m_latestVideoTimecode
Definition: mythplayer.h:437
MythPlayer::m_disableForcedSubtitles
bool m_disableForcedSubtitles
Definition: mythplayer.h:472
MythMediaBuffer::LiveMode
bool LiveMode(void) const
Returns true if this RingBuffer has been assigned a LiveTVChain.
Definition: mythmediabuffer.cpp:1798
MythPlayer::m_keyframeDist
uint m_keyframeDist
Video (input) Number of frames between key frames (often inaccurate)
Definition: mythplayer.h:453
preBufferDebug
static bool preBufferDebug
Definition: mythplayer.cpp:705
MythPlayer::RequestResetCaptions
void RequestResetCaptions()
MythPlayer::m_pauseDecoder
bool m_pauseDecoder
Definition: mythplayer.h:394
MythPlayer::GetEditMode
bool GetEditMode(void) const
Definition: mythplayer.h:319
MythPlayer::EnableForcedSubtitles
void EnableForcedSubtitles(bool enable)
Definition: mythplayer.cpp:663
MythPlayer::GetChapterTimes
virtual void GetChapterTimes(QList< std::chrono::seconds > &times)
Definition: mythplayer.cpp:1867
MythPlayer::m_fpsMultiplier
int m_fpsMultiplier
used to detect changes
Definition: mythplayer.h:499
uint
unsigned int uint
Definition: compat.h:144
MythPlayer::m_endExitPrompt
int m_endExitPrompt
Definition: mythplayer.h:422
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
MythPlayer::m_unpauseDecoder
bool m_unpauseDecoder
Definition: mythplayer.h:395
MythPlayer::m_playerFlags
PlayerFlags m_playerFlags
Definition: mythplayer.h:380
MythPlayer::UnpauseDecoder
void UnpauseDecoder(void)
Definition: mythplayer.cpp:977
MythPlayer::m_playingLock
QMutex m_playingLock
Definition: mythplayer.h:406
MythPlayer::PauseBuffer
void PauseBuffer(void)
Definition: mythplayer.cpp:138
MythPlayer::m_deleteMap
DeleteMap m_deleteMap
Definition: mythplayer.h:486
PlayerContext::m_tvchain
LiveTVChain * m_tvchain
Definition: playercontext.h:118
DecoderBase::GetRawAudioState
virtual bool GetRawAudioState(void) const
Definition: decoderbase.h:192
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:936
MythPlayer::m_vbiMode
uint m_vbiMode
VBI decoder to use.
Definition: mythplayer.h:462
MythPlayer::VideoEnd
virtual void VideoEnd(void)
Definition: mythplayer.cpp:816
MythPlayer::DoFastForward
bool DoFastForward(uint64_t frames, double inaccuracy)
Definition: mythplayer.cpp:1593
MythPlayer::m_playerThread
QThread * m_playerThread
Definition: mythplayer.h:376
MythPlayer::m_limitKeyRepeat
bool m_limitKeyRepeat
Definition: mythplayer.h:414
MythPlayer::DecoderGetFrameREW
virtual bool DecoderGetFrameREW(void)
Definition: mythplayer.cpp:1192
MythPlayer::DecoderEnd
virtual void DecoderEnd(void)
Definition: mythplayer.cpp:1022
mythmediabuffer.h
DecoderBase::SyncPositionMap
virtual bool SyncPositionMap(void)
Updates the position map used for skipping frames.
Definition: decoderbase.cpp:322
MythPlayer::ReinitVideo
virtual void ReinitVideo(bool ForceUpdate)
Definition: mythplayer.cpp:300
frm_pos_map_t
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:46
MythPlayer::TranslatePositionFrameToMs
std::chrono::milliseconds TranslatePositionFrameToMs(uint64_t position, bool use_cutlist) const
Definition: mythplayer.cpp:1837
MythVideoOutput::EnoughFreeFrames
bool EnoughFreeFrames()
Returns true iff enough frames are available to decode onto.
Definition: mythvideoout.cpp:289
MythPlayer::m_decoderPaused
bool m_decoderPaused
Definition: mythplayer.h:392
MythPlayer::DoJumpToFrame
void DoJumpToFrame(uint64_t frame, double inaccuracy)
Definition: mythplayer.cpp:1618
MythPlayer::SetVideoParams
virtual void SetVideoParams(int w, int h, double fps, float aspect, bool ForceUpdate, int ReferenceFrames, FrameScanType=kScan_Ignore, const QString &codecName=QString())
Definition: mythplayer.cpp:327
MythPlayer::JumpChapter
void JumpChapter(int chapter)
Definition: mythplayer.cpp:898
MythVideoOutput::ReleaseFrame
virtual void ReleaseFrame(MythVideoFrame *Frame)
Releases a frame from the ready for decoding queue onto the queue of frames ready for display.
Definition: mythvideoout.cpp:396
DecoderBase::SetSeekSnap
void SetSeekSnap(uint64_t snap)
Definition: decoderbase.h:137
MythPlayer::GetNumChapters
virtual int GetNumChapters(void)
Definition: mythplayer.cpp:1853
DecoderBase::GetNumChapters
virtual int GetNumChapters(void)
Definition: decoderbase.h:154
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:930
MythPlayer::m_jumpChapter
int m_jumpChapter
Definition: mythplayer.h:417
MythPlayer::InitFrameInterval
virtual void InitFrameInterval()
Definition: mythplayer.cpp:681
MythPlayer::GetError
QString GetError(void) const
Definition: mythplayer.cpp:1993
DecoderBase::SetWatchingRecording
virtual void SetWatchingRecording(bool mode)
Definition: decoderbase.cpp:82
kState_WatchingPreRecorded
@ kState_WatchingPreRecorded
Watching Pre-recorded is a TV only state for when we are watching a pre-existing recording.
Definition: tv.h:67
DecoderBase::SetTranscoding
void SetTranscoding(bool value)
Definition: decoderbase.h:223
DecoderBase::GetFrame
virtual bool GetFrame(DecodeType Type, bool &Retry)=0
Demux, preprocess and possibly decode a frame of video/audio.
MythPlayerAVSync::ResetAVSyncClockBase
void ResetAVSyncClockBase()
Definition: mythplayeravsync.cpp:40
MythPlayerAVSync::InitAVSync
void InitAVSync()
Definition: mythplayeravsync.cpp:17
kDecodeVideo
@ kDecodeVideo
Definition: decoderbase.h:50
MythPlayer::CreateDecoder
virtual void CreateDecoder(TestBufferVec &TestBuffer)
Definition: mythplayer.cpp:414
LiveTVChain::GetInputType
QString GetInputType(int pos=-1) const
Definition: livetvchain.cpp:695
MythPlayer::CalcMaxFFTime
virtual long long CalcMaxFFTime(long long ff, bool setjump=true) const
CalcMaxFFTime(ffframes): forward ffframes forward.
Definition: mythplayer.cpp:1453
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:372
livetvchain.h
ProgramInfo::QueryAutoExpire
AutoExpireType QueryAutoExpire(void) const
Returns "autoexpire" field from "recorded" table.
Definition: programinfo.cpp:3376
kVideoIsNull
@ kVideoIsNull
Definition: mythplayer.h:74
MythPlayer::SetKeyframeDistance
void SetKeyframeDistance(int keyframedistance)
Definition: mythplayer.cpp:322
MythMediaBuffer::IsBookmarkAllowed
virtual bool IsBookmarkAllowed(void)
Definition: mythmediabuffer.h:127
DecoderBase::UpdateFramesPlayed
virtual void UpdateFramesPlayed(void)
Definition: decoderbase.cpp:876
MythVideoOutput::DiscardFrame
virtual void DiscardFrame(MythVideoFrame *Frame)
Releases frame from any queue onto the queue of frames ready for decoding onto.
Definition: mythvideoout.cpp:423
MythPlayer::SetWatchingRecording
void SetWatchingRecording(bool mode)
Definition: mythplayer.cpp:126
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
MythPlayer::m_liveTV
bool m_liveTV
Definition: mythplayer.h:410
kEofStateImmediate
@ kEofStateImmediate
Definition: decoderbase.h:71
assert
#define assert(x)
Definition: audiooutputalsa.cpp:18
mythmiscutil.h
MythPlayer::IsReallyNearEnd
bool IsReallyNearEnd(void) const
Returns true iff really near end of recording.
Definition: mythplayer.cpp:1533
MythPlayer::IsWatchingInprogress
bool IsWatchingInprogress(void) const
Definition: mythplayer.cpp:133
MythPlayer::m_decoderThreadPause
QWaitCondition m_decoderThreadPause
Definition: mythplayer.h:383
mythcorecontext.h
MythPlayer::m_fileChanged
bool m_fileChanged
Definition: mythplayer.h:503
MythPlayer::SetFramesPlayed
void SetFramesPlayed(uint64_t played)
Definition: mythplayer.cpp:562
MythPlayer::FileChangedCallback
void FileChangedCallback()
Definition: mythplayer.cpp:926
MythPlayer::m_maxReferenceFrames
int m_maxReferenceFrames
Number of reference frames used in the video stream.
Definition: mythplayer.h:448
cardutil.h
MythPlayer::WaitForSeek
void WaitForSeek(uint64_t frame, uint64_t seeksnap_wanted)
Definition: mythplayer.cpp:1626
MythPlayer::GetFreeVideoFrames
int GetFreeVideoFrames(void) const
Returns the number of frames available for decoding onto.
Definition: mythplayer.cpp:572
DecoderBase::SetRenderFormats
void SetRenderFormats(const VideoFrameTypes *RenderFormats)
Definition: decoderbase.cpp:36
MythPlayer::m_errorType
int m_errorType
Definition: mythplayer.h:409
avformatdecoder.h
setpriority
#define setpriority(x, y, z)
Definition: compat.h:206
TC_AUDIO
@ TC_AUDIO
Definition: mythplayer.h:58
MythPlayer::SetDisablePassThrough
void SetDisablePassThrough(bool disabled)
Definition: mythplayer.cpp:2037
MythPlayer::kInaccuracyEditor
static const double kInaccuracyEditor
Definition: mythplayer.h:246
MythPlayer::TranslatePositionMsToFrame
uint64_t TranslatePositionMsToFrame(std::chrono::milliseconds position, bool use_cutlist) const
Definition: mythplayer.h:261
MythPlayer::m_decodeOneFrame
bool m_decodeOneFrame
Definition: mythplayer.h:397
MythPlayer::SetPlaying
void SetPlaying(bool is_playing)
Definition: mythplayer.cpp:248
audiooutput.h
MythPlayer::m_transcoding
bool m_transcoding
Definition: mythplayer.h:412
ProgramInfo::IsVideo
bool IsVideo(void) const
Definition: programinfo.h:486
dummydecoder.h
mythavutil.h
MythPlayer::GetNextVideoFrame
MythVideoFrame * GetNextVideoFrame(void)
Removes a frame from the available queue for decoding onto.
Definition: mythplayer.cpp:588
MythPlayer::m_ffrewScale
float m_ffrewScale
scale skip for large gops
Definition: mythplayer.h:502
RemoteEncoder::FillPositionMap
void FillPositionMap(int64_t start, int64_t end, frm_pos_map_t &positionMap)
Definition: remoteencoder.cpp:267
MythMediaBuffer::Start
void Start(void)
Starts the read-ahead thread.
Definition: mythmediabuffer.cpp:610
AvFormatDecoder::CanHandle
static bool CanHandle(TestBufferVec &testbuf, const QString &filename)
Perform an av_probe_input_format on the passed data to see if we can decode it with this class.
Definition: avformatdecoder.cpp:873
MythPlayer::SetFrameRate
void SetFrameRate(double fps)
Definition: mythplayer.cpp:380
MythPlayer::ResetTotalDuration
void ResetTotalDuration(void)
Definition: mythplayer.cpp:2007
MythPlayer::m_totalLength
std::chrono::seconds m_totalLength
Definition: mythplayer.h:434
MythPlayer::SetFrameInterval
void SetFrameInterval(FrameScanType scan, double frame_period)
Definition: mythplayer.cpp:671
MythPlayer::m_decoderSeek
int64_t m_decoderSeek
Definition: mythplayer.h:390
mthread.h
kAudioMuted
@ kAudioMuted
Definition: mythplayer.h:75
MThread::isRunning
bool isRunning(void) const
Definition: mthread.cpp:266
MythPlayer::SetCommBreakMap
void SetCommBreakMap(const frm_dir_map_t &NewMap)
Definition: mythplayer.cpp:1768
PlayerContext
Definition: playercontext.h:52
MythPlayer::m_isDummy
bool m_isDummy
Definition: mythplayer.h:512
MythPlayer::m_videoDim
QSize m_videoDim
Video (input) buffer width & height.
Definition: mythplayer.h:447
MythPlayer::m_vidExitLock
QMutex m_vidExitLock
Definition: mythplayer.h:405
remoteencoder.h
AudioPlayer::GetStretchFactor
float GetStretchFactor(void) const
Definition: audioplayer.h:70
audioplayer.h
DecoderBase::SetDisablePassThrough
virtual void SetDisablePassThrough(bool disable)
Disables AC3/DTS pass through.
Definition: decoderbase.h:145
mythtimer.h
MythPlayer::m_videoAspect
float m_videoAspect
Video (input) Apect Ratio.
Definition: mythplayer.h:449
AudioPlayer::Pause
bool Pause(bool pause)
Definition: audioplayer.cpp:178
MythPlayer::ForceSetupAudioStream
void ForceSetupAudioStream(void)
Definition: mythplayer.cpp:2043
MythPlayer::DecoderGetFrameFFREW
virtual bool DecoderGetFrameFFREW(void)
Definition: mythplayer.cpp:1156
mythcodeccontext.h
MythPlayer::kInaccuracyFull
static const double kInaccuracyFull
Definition: mythplayer.h:247
MythPlayer::JumpToFrame
virtual bool JumpToFrame(uint64_t frame)
Definition: mythplayer.cpp:877
MythPlayer::StopPlaying
virtual void StopPlaying(void)
Definition: mythplayer.cpp:932
MythPlayer::m_allPaused
bool m_allPaused
Definition: mythplayer.h:401
mythuiactions.h
MythPlayer::SaveTotalDuration
void SaveTotalDuration(void)
Definition: mythplayer.cpp:1999
DecoderBase::OpenFile
virtual int OpenFile(MythMediaBuffer *Buffer, bool novideo, TestBufferVec &testbuf)=0
ffrewScaleLowest
static float ffrewScaleLowest
Definition: mythplayer.cpp:1153
MythPlayer::IsInStillFrame
virtual bool IsInStillFrame() const
Definition: mythplayer.h:234
LiveTVChain::HasPrev
bool HasPrev(void) const
Definition: livetvchain.h:64
MythPlayer::GetXDS
QString GetXDS(const QString &key) const
Definition: mythplayer.cpp:1761
myth_nice
bool myth_nice(int val)
Definition: mythmiscutil.cpp:707
PRIO_PROCESS
#define PRIO_PROCESS
Definition: compat.h:205
MythMediaBuffer::Peek
int Peek(void *Buffer, int Count)
Definition: mythmediabuffer.cpp:1164
MythVideoFrame
Definition: mythframe.h:88
MythPlayer::OpenDummy
void OpenDummy(void)
Definition: mythplayer.cpp:398
MythPlayer::m_playing
bool m_playing
Definition: mythplayer.h:402
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:905
PlayerContext::m_recorder
RemoteEncoder * m_recorder
Definition: playercontext.h:117
DecoderBase::Reset
virtual void Reset(bool reset_video_data, bool seek_reset, bool reset_file)
Definition: decoderbase.cpp:48
MythMediaBuffer::IsNearEnd
bool IsNearEnd(double Framerate, uint Frames) const
Definition: mythmediabuffer.cpp:405
DeleteMap::GetLastFrame
uint64_t GetLastFrame(void) const
Returns the number of the last frame in the video that is not in a cut sequence.
Definition: deletemap.cpp:855
MythVideoOutput::EnoughDecodedFrames
bool EnoughDecodedFrames()
Returns true iff there are plenty of decoded frames ready for display.
Definition: mythvideoout.cpp:296
LOC
#define LOC
Definition: mythplayer.cpp:64
MythPlayer::DecoderLoop
virtual void DecoderLoop(bool pause)
Definition: mythplayer.cpp:1086
DecoderBase::SetEofState
virtual void SetEofState(EofState eof)
Definition: decoderbase.h:131
MythPlayer::m_disablePassthrough
bool m_disablePassthrough
Definition: mythplayer.h:520
DummyDecoder
Definition: dummydecoder.h:9
mythmainwindow.h
DecoderBase::SetLiveTVMode
void SetLiveTVMode(bool live)
Definition: decoderbase.h:139
FlagIsSet
#define FlagIsSet(arg)
Definition: mythplayer.h:80
MythMediaBuffer::IsSeekingAllowed
virtual bool IsSeekingAllowed(void)
Definition: mythmediabuffer.h:126
MythPlayer::DoRewind
bool DoRewind(uint64_t frames, double inaccuracy)
Definition: mythplayer.cpp:1406
MythPlayer::kInaccuracyDefault
static const double kInaccuracyDefault
Definition: mythplayer.h:245
MythPlayer::FastForward
virtual bool FastForward(float seconds)
Definition: mythplayer.cpp:824
DecoderBase::GetFramesRead
long long GetFramesRead(void) const
Definition: decoderbase.h:203
MythMediaBuffer::Pause
void Pause(void)
Pauses the read-ahead thread. Calls StopReads(void).
Definition: mythmediabuffer.cpp:683
DecoderBase::DoRewind
virtual bool DoRewind(long long desiredFrame, bool discardFrames=true)
Definition: decoderbase.cpp:555
DeleteMap::IsEditing
bool IsEditing(void) const
Definition: deletemap.h:40
MythPlayer::DoGetFrame
bool DoGetFrame(DecodeType DecodeType)
Get one frame from the decoder.
Definition: mythplayer.cpp:1276
MythPlayer::Play
bool Play(float speed=1.0, bool normal=true, bool unpauseaudio=true)
Definition: mythplayer.cpp:192
MythPlayer::m_playingWaitCond
QWaitCondition m_playingWaitCond
Definition: mythplayer.h:404
DecoderBase
Definition: decoderbase.h:120
MythVideoOutput::SetVideoFrameRate
virtual void SetVideoFrameRate(float VideoFrameRate)
Definition: mythvideoout.cpp:134
MythPlayer::m_renderFormats
const VideoFrameTypes * m_renderFormats
Definition: mythplayer.h:373
MythPlayer::m_killDecoder
bool volatile m_killDecoder
Definition: mythplayer.h:396
MythPlayer::ReleaseNextVideoFrame
virtual void ReleaseNextVideoFrame(MythVideoFrame *buffer, std::chrono::milliseconds timecode, bool wrap=true)
Places frame on the queue of frames ready for display.
Definition: mythplayer.cpp:598
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:922
millisecondsFromFloat
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::milliseconds > millisecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:91
tv_play.h
MythPlayer::DecoderStart
virtual void DecoderStart(bool start_paused)
Definition: mythplayer.cpp:1004
DecoderBase::SaveTotalFrames
void SaveTotalFrames(void)
Definition: decoderbase.cpp:1249
MythPlayer::Rewind
virtual bool Rewind(float seconds)
Definition: mythplayer.cpp:854
MythPlayer::GetCurrentChapter
virtual int GetCurrentChapter(void)
Definition: mythplayer.cpp:1860
MythPlayer::DiscardVideoFrame
void DiscardVideoFrame(MythVideoFrame *buffer)
Places frame in the available frames queue.
Definition: mythplayer.cpp:618