MythTV master
mythplayerui.cpp
Go to the documentation of this file.
1#include <algorithm>
2
3// MythTV
8
11#include "livetvchain.h"
13#include "mheg/interactivetv.h"
14#include "mythplayerui.h"
15#include "mythsystemevent.h"
16#include "osd.h"
17#include "tv_play.h"
18
19#define LOC QString("PlayerUI: ")
20
22 PlayerContext *Context, PlayerFlags Flags)
23 : MythPlayerEditorUI(MainWindow, Tv, Context, Flags),
25 m_display(MainWindow->GetDisplay())
26{
27 // Finish setting up the overlays
28 m_osd.SetPlayer(this);
30
31 // User feedback during slow seeks
32 connect(this, &MythPlayerUI::SeekingSlow, [&](int Count)
33 {
34 UpdateOSDMessage(tr("Searching") + QString().fill('.', Count % 3), kOSDTimeout_Short);
36 });
37
38 // Seeking has finished; remove slow seek user feedback window
39 connect(this, &MythPlayerUI::SeekingComplete, [&]()
40 {
41 m_osdLock.lock();
43 m_osdLock.unlock();
44 });
45
46 // Seeking has finished; update position on OSD
47 connect(this, &MythPlayerUI::SeekingDone, [&]()
48 {
50 });
51
52 // Setup OSD debug
53 m_osdDebugTimer.setInterval(1s);
56
57 // Other connections
61
62 // Setup refresh interval.
65}
66
68{
69 LOG(VB_GENERAL, LOG_INFO, LOC + "Initialising player state");
71}
72
74{
75 if (OpenFile() < 0)
76 {
77 LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to open video file.");
78 return false;
79 }
80
84 m_jumpChapter = 0;
87
88 if (!InitVideo())
89 {
90 LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to initialize video.");
92 return false;
93 }
94
95 EventStart();
96 DecoderStart(true);
98 VideoStart();
99
100 m_playerThread->setPriority(QThread::TimeCriticalPriority);
101#ifdef Q_OS_ANDROID
102 setpriority(PRIO_PROCESS, m_playerThreadId, -20);
103#endif
106 return !IsErrored();
107}
108
110{
111 // TODO handle initial commskip and/or cutlist skip as well
112 if (m_bookmarkSeek > 30)
114}
115
117{
118 // Handle decoder callbacks
120
121 // Live TV program change
122 if (m_fileChanged)
123 FileChanged();
124
125 // Check if visualiser is wanted on first start and after video change
127 AutoVisualise(!m_videoDim.isEmpty());
128
129 // recreate the osd if a reinit was triggered by another thread
130 if (m_reinitOsd)
131 ReinitOSD();
132
133 // enable/disable forced subtitles if signalled by the decoder
138
139 // reset the scan (and hence deinterlacers) if triggered by the decoder
141
142 // refresh the position map for an in-progress recording while editing
144 {
145 if (m_editUpdateTimer.hasExpired(2000))
146 {
147 // N.B. the positionmap update and osd refresh are asynchronous
149 m_osdLock.lock();
151 m_osdLock.unlock();
152 m_editUpdateTimer.start();
153 }
154 }
155
156 // Refresh the programinfo in use status
157 m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
160 m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
161
162 // Disable timestretch if we are too close to the end of the buffer
163 if (m_ffrewSkip == 1 && (m_playSpeed > 1.0F) && IsNearEnd())
164 {
165 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Near end, Slowing down playback.");
166 Play(1.0F, true, true);
167 }
168
170 {
171 // Switch from the dummy recorder to the tuned program in livetv
172 m_playerCtx->m_tvchain->JumpToNext(true, 0s);
174 }
175 else if ((!m_allPaused || GetEof() != kEofStateNone) &&
178 {
179 // Switch to the next program in livetv
182 }
183
184 // Jump to the next program in livetv
186 {
188 }
189
190 // Change interactive stream if requested
191 if (!m_newStream.isEmpty())
192 {
194 m_newStream = QString();
195 }
196
197 // Disable fastforward if we are too close to the end of the buffer
198 if (m_ffrewSkip > 1 && (CalcMaxFFTime(100, false) < 100))
199 {
200 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Near end, stopping fastforward.");
201 Play(1.0F, true, true);
202 }
203
204 // Disable rewind if we are too close to the beginning of the buffer
205 if (m_ffrewSkip < 0 && CalcRWTime(-m_ffrewSkip) >= 0 &&
207 {
208 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Near start, stopping rewind.");
209 float stretch = (m_ffrewSkip > 0) ? 1.0F : m_audio.GetStretchFactor();
210 Play(stretch, true, true);
211 }
212
213 // Check for error
215 {
216 LOG(VB_GENERAL, LOG_ERR, LOC + "Unknown recorder error, exiting decoder");
217 if (!IsErrored())
218 SetErrored(tr("Irrecoverable recorder error"));
219 m_killDecoder = true;
220 return;
221 }
222
223 // Handle speed change
224 if (!qFuzzyCompare(m_playSpeed + 1.0F, m_nextPlaySpeed + 1.0F) &&
226 {
227 ChangeSpeed();
228 return;
229 }
230
231 // Check if we got a communication error, and if so pause playback
233 {
234 Pause();
236 }
237
238 // Handle end of file
239 EofState eof = GetEof();
240 if (HasReachedEof())
241 {
242#if CONFIG_MHEG
243 if (m_interactiveTV && m_interactiveTV->StreamStarted(false))
244 {
245 Pause();
246 return;
247 }
248#endif
250 {
251 LOG(VB_GENERAL, LOG_NOTICE, LOC + "LiveTV forcing JumpTo 1");
252 m_playerCtx->m_tvchain->JumpToNext(true, 0s);
253 return;
254 }
255
256 bool drained = false;
258 {
259 // We have audio only or mostly audio content. Exit when
260 // the audio is drained.
261 drained =
263 m_audio.IsPaused() ||
265 }
266 else
267 {
268 // We have normal or video only content. Exit when the
269 // video is drained.
271 }
272 if (eof != kEofStateDelayed || drained)
273 {
274 if (eof == kEofStateDelayed)
275 {
276 LOG(VB_PLAYBACK, LOG_INFO,
277 QString("waiting for no video frames %1")
279 }
280 LOG(VB_PLAYBACK, LOG_INFO,
281 QString("HasReachedEof() at framesPlayed=%1 totalFrames=%2")
283 Pause();
284 SetPlaying(false);
285 return;
286 }
287 }
288
289 // Handle rewind
290 if (m_rewindTime > 0 && (m_ffrewSkip == 1 || m_ffrewSkip == 0))
291 {
293 if (m_rewindTime > 0)
294 DoRewind(static_cast<uint64_t>(m_rewindTime), kInaccuracyDefault);
295 }
296
297 // Handle fast forward
298 if (m_ffTime > 0 && (m_ffrewSkip == 1 || m_ffrewSkip == 0))
299 {
301 if (m_ffTime > 0)
302 {
303 DoFastForward(static_cast<uint64_t>(m_ffTime), kInaccuracyDefault);
304 if (GetEof() != kEofStateNone)
305 return;
306 }
307 }
308
309 // Handle chapter jump
310 if (m_jumpChapter != 0)
312
313 // Handle commercial skipping
314 if (m_commBreakMap.GetSkipCommercials() != 0 && (m_ffrewSkip == 1))
315 {
316 if (!m_commBreakMap.HasMap())
317 {
318 //: The commercials/adverts have not been flagged
319 SetOSDStatus(tr("Not Flagged"), kOSDTimeout_Med);
320 QString message = "COMMFLAG_REQUEST ";
321 m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
322 message += QString("%1").arg(m_playerCtx->m_playingInfo->GetChanID()) +
324 m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
325 gCoreContext->SendMessage(message);
326 }
327 else
328 {
329 QString msg;
330 uint64_t jumpto = 0;
331 uint64_t frameCount = GetCurrentFrameCount();
332 // XXX CommBreakMap should use duration map not m_videoFrameRate
335 frameCount, msg);
336 if (!msg.isEmpty())
338 if (jump)
340 }
342 return;
343 }
344
345 // Handle automatic commercial skipping
346 uint64_t jumpto = 0;
347 if (m_deleteMap.IsEmpty() && (m_ffrewSkip == 1) &&
350 {
351 QString msg;
352 uint64_t frameCount = GetCurrentFrameCount();
353 // XXX CommBreakMap should use duration map not m_videoFrameRate
356 frameCount, msg);
357 if (!msg.isEmpty())
359 if (jump)
361 }
362
363 // Handle cutlist skipping
364 if (!m_allPaused && (m_ffrewSkip == 1) &&
366 {
367 if (jumpto == m_totalFrames)
368 {
371 }
372 else
373 {
375 }
376 }
377}
378
380{
381#if CONFIG_MHEG
382 // handle Interactive TV
383 if (GetInteractiveTV())
384 {
385 m_osdLock.lock();
386 m_itvLock.lock();
387 auto *window = qobject_cast<InteractiveScreen *>(m_captionsOverlay.GetWindow(OSD_WIN_INTERACT));
388 if ((m_interactiveTV->ImageHasChanged() || !m_itvVisible) && window)
389 {
390 m_interactiveTV->UpdateOSD(window, m_painter);
391 m_itvVisible = true;
392 }
393 m_itvLock.unlock();
394 m_osdLock.unlock();
395 }
396#endif // CONFIG_MHEG
397}
398
400{
402 // ensure we re-check double rate support following a speed change
403 UnlockScan();
404}
405
406void MythPlayerUI::ReinitVideo(bool ForceUpdate)
407{
408 MythPlayer::ReinitVideo(ForceUpdate);
409
410 // Signal to the main thread to reinit OSD
411 m_reinitOsd = true;
412
413 // Signal to main thread to reinit subtitles
415 emit EnableSubtitles(true);
416
417 // Signal to the main thread to check auto visualise
419}
420
422{
423 QRect visible;
424 QRect total;
425 float aspect = NAN;
426 float scaling = NAN;
427
428 m_osdLock.lock();
429 m_videoOutput->GetOSDBounds(total, visible, aspect, scaling, 1.0F);
430 m_osd.Init(visible, aspect);
431 m_captionsOverlay.Init(visible, aspect);
433
434#if CONFIG_MHEG
435 if (GetInteractiveTV())
436 {
437 QMutexLocker locker(&m_itvLock);
438 m_interactiveTV->Reinit(total, visible, aspect);
439 }
440#endif // CONFIG_MHEG
441
442 // If there is a forced text subtitle track (which is possible
443 // in e.g. a .mkv container), and forced subtitles are
444 // allowed, then start playback with that subtitle track
445 // selected. Otherwise, use the frontend settings to decide
446 // which captions/subtitles (if any) to enable at startup.
447 // TODO: modify the fix to #10735 to use this approach
448 // instead.
449 bool hasForcedTextTrack = false;
450 uint forcedTrackNumber = 0;
452 {
454 for (uint i = 0; !hasForcedTextTrack && i < numTextTracks; ++i)
455 {
457 {
458 hasForcedTextTrack = true;
459 forcedTrackNumber = i;
460 }
461 }
462 }
463 if (hasForcedTextTrack)
464 SetTrack(kTrackTypeRawText, forcedTrackNumber);
465 else
467
468 m_osdLock.unlock();
469
470 SetPlaying(true);
471 ClearAfterSeek(false);
474
477 AutoVisualise(!m_videoDim.isEmpty());
478}
479
481{
482 m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
483 {
485 {
486 // When initial playback gets underway, we override the ProgramInfo
487 // flags such that future calls to GetBookmark() will consider only
488 // an actual bookmark and not progstart or lastplaypos information.
492 }
493 }
494 m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
496}
497
499{
501
504 else if (DisplayNormalFrame())
505 {
508 else if (m_decoder && m_decoder->GetEof() != kEofStateNone)
510 else
511 m_framesPlayed = static_cast<uint64_t>(
513 }
514
515 return !IsErrored();
516}
517
519{
520 SetFrameInterval(GetScanType(), 1.0 / (m_videoFrameRate * static_cast<double>(m_playSpeed)));
522 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Display Refresh Rate: %1 Video Frame Rate: %2")
523 .arg(1000000.0 / m_refreshInterval.count(), 0, 'f', 3)
524 .arg(1000000.0 / m_frameInterval.count(), 0, 'f', 3));
525}
526
527void MythPlayerUI::RenderVideoFrame(MythVideoFrame *Frame, FrameScanType Scan, bool Prepare, std::chrono::microseconds Wait)
528{
529 if (!m_videoOutput)
530 return;
531
532 if (Prepare)
537 LOG(VB_PLAYBACK, LOG_DEBUG, QString("Clearing render one"));
538 m_renderOneFrame = false;
541 m_osd.Draw();
543
544 if (Wait > 0us)
546
548}
549
551{
552 m_fileChanged = false;
553 LOG(VB_PLAYBACK, LOG_INFO, LOC + "FileChanged");
554
555 Pause();
556 ChangeSpeed();
557 if (dynamic_cast<AvFormatDecoder *>(m_decoder))
558 m_playerCtx->m_buffer->Reset(false, true);
559 else
560 m_playerCtx->m_buffer->Reset(false, true, true);
562 Play();
563
565
566 m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
568 if (m_decoder)
570 m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
571
572 CheckTVChain();
574}
575
577{
579 {
581 {
583 m_needNewPauseFrame = false;
584
586 {
587 m_osdLock.lock();
589 m_osdLock.unlock();
590 }
591 }
592 else
593 {
594 m_decodeOneFrame = true;
595 }
596 }
597}
598
599void MythPlayerUI::DoDisplayVideoFrame(MythVideoFrame* Frame, std::chrono::microseconds Due)
600{
601 if (Due < 0us)
602 {
603 m_videoOutput->SetFramesPlayed(static_cast<long long>(++m_framesPlayed));
605 LOG(VB_PLAYBACK, LOG_DEBUG, QString("Clearing render one"));
606 m_renderOneFrame = false;
607 }
608 else if (!FlagIsSet(kVideoIsNull) && Frame)
609 {
610
611 // Check scan type
612 bool showsecondfield = false;
613 FrameScanType ps = GetScanForDisplay(Frame, showsecondfield);
614
615 // if we get here, we're actually going to do video output
616 RenderVideoFrame(Frame, ps, true, Due);
617
618 // Only double rate CPU deinterlacers require an extra call to PrepareFrame
619 bool secondprepare = Frame->GetDoubleRateOption(DEINT_CPU) && !Frame->GetDoubleRateOption(DEINT_SHADER);
620 // and the first deinterlacing pass will have marked the frame as already deinterlaced
621 // which will break GetScanForDisplay below and subsequent deinterlacing
622 bool olddeinterlaced = Frame->m_alreadyDeinterlaced;
623 if (secondprepare)
624 Frame->m_alreadyDeinterlaced = false;
625 // Update scan settings now that deinterlacer has been set and we know
626 // whether we need a second field
627 ps = GetScanForDisplay(Frame, showsecondfield);
628
629 // Reset olddeinterlaced if necessary (pause frame etc)
630 if (!showsecondfield && secondprepare)
631 {
632 Frame->m_alreadyDeinterlaced = olddeinterlaced;
633 }
634 else if (showsecondfield)
635 {
636 // Second field
637 if (kScan_Interlaced == ps)
639 RenderVideoFrame(Frame, ps, secondprepare, Due + m_frameInterval / 2);
640 }
641 }
642 else
643 {
645 }
646}
647
649{
650 if (!m_videoOutput)
651 return;
652
654 {
655 SetErrored(tr("Serious error detected in Video Output"));
656 return;
657 }
658
659 // clear the buffering state
660 SetBuffering(false);
661
663 PreProcessNormalFrame(); // Allow interactiveTV to draw on pause frame
664
667 RenderVideoFrame(nullptr, scan, true, 0ms);
668}
669
670bool MythPlayerUI::DisplayNormalFrame(bool CheckPrebuffer)
671{
672 if (m_allPaused)
673 return false;
674
675 if (CheckPrebuffer && !PrebufferEnoughFrames())
676 return false;
677
678 // clear the buffering state
679 SetBuffering(false);
680
681 // retrieve the next frame
684
685 // Check aspect ratio
686 CheckAspectRatio(frame);
687
690
691 // Player specific processing (dvd, bd, mheg etc)
693
694 // handle scan type changes
696
697 // Detect letter boxing
698 // FIXME this is temporarily moved entirely into the main thread as there are
699 // too many threading issues and the decoder thread is not yet ready to handle
700 // QObject signals and slots.
701 // When refactoring is complete, move it into the decoder thread and
702 // signal switches via a new field in MythVideoFrame
705 {
707 ReinitOSD();
708 }
709
710 // When is the next frame due
711 std::chrono::microseconds due = m_avSync.AVSync(&m_audio, frame, m_frameInterval, m_playSpeed, !m_videoDim.isEmpty(),
713 // Display it
714 DoDisplayVideoFrame(frame, due);
717
718 return true;
719}
720
721void MythPlayerUI::SetVideoParams(int Width, int Height, double FrameRate, float Aspect,
722 bool ForceUpdate, int ReferenceFrames,
723 FrameScanType Scan, const QString &CodecName)
724{
725 MythPlayer::SetVideoParams(Width, Height, FrameRate, Aspect, ForceUpdate, ReferenceFrames,
726 Scan, CodecName);
727
728 // ensure deinterlacers are correctly reset after a change
729 UnlockScan();
730 FrameScanType newscan = DetectInterlace(Scan, static_cast<float>(m_videoFrameRate), m_videoDispDim.height());
732 ResetTracker();
733}
734
749void MythPlayerUI::SetWatched(bool ForceWatched)
750{
751 m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
753 {
754 m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
755 return;
756 }
757
758 uint64_t numFrames = GetCurrentFrameCount();
759
760 // For recordings we want to ignore the post-roll and account for
761 // in-progress recordings where totalFrames doesn't represent
762 // the full length of the recording. For videos we can only rely on
763 // totalFrames as duration metadata can be wrong
766 {
767
768 // If the recording is stopped early we need to use the recording end
769 // time, not the programme end time
771 qint64 starttime = pi->GetRecordingStartTime().toSecsSinceEpoch();
772 qint64 endactual = pi->GetRecordingEndTime().toSecsSinceEpoch();
773 qint64 endsched = pi->GetScheduledEndTime().toSecsSinceEpoch();
774 qint64 endtime = std::min(endactual, endsched);
775 numFrames = static_cast<uint64_t>((endtime - starttime) * m_videoFrameRate);
776 }
777
778 // 4 minutes min, 12 minutes max
779 auto offset = std::chrono::seconds(lround(0.14 * (numFrames / m_videoFrameRate)));
780 offset = std::clamp(offset, 240s, 720s);
781
782 if (ForceWatched || (m_framesPlayed > (numFrames - (offset.count() * m_videoFrameRate))))
783 {
785 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Marking recording as watched using offset %1 minutes")
786 .arg(offset.count()/60));
787 }
788
789 m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
790}
791
793{
794 m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
797 m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
798}
799
801{
802 m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
805 m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
806}
807
809{
810 // At this point we may not have the correct frame rate.
811 // Since interlaced is always at 25 or 30 fps, if the interval
812 // is less than 30000 (33fps) it must be representing one
813 // field and not one frame, so multiply by 2.
814 std::chrono::microseconds realfi = m_frameInterval;
815 if (m_frameInterval < 30ms)
816 realfi = m_frameInterval * 2;
817 return (duration_cast<floatusecs>(realfi) / 2.0) > (duration_cast<floatusecs>(m_refreshInterval) * 0.995);
818}
819
821{
822 QString samplerate = MythMediaBuffer::BitrateToString(static_cast<uint64_t>(m_audio.GetSampleRate()), true);
823 Map.insert("samplerate", samplerate);
824 Map.insert("filename", m_playerCtx->m_buffer->GetSafeFilename());
825 Map.insert("decoderrate", m_playerCtx->m_buffer->GetDecoderRate());
826 Map.insert("storagerate", m_playerCtx->m_buffer->GetStorageRate());
827 Map.insert("bufferavail", m_playerCtx->m_buffer->GetAvailableBuffer());
828 Map.insert("buffersize", QString::number(m_playerCtx->m_buffer->GetBufferSize() >> 20));
830
831 if (m_videoOutput)
832 {
833 QString frames = QString("%1/%2").arg(m_videoOutput->ValidVideoFrames())
835 Map.insert("videoframes", frames);
836 }
837 if (m_decoder)
838 Map["videodecoder"] = m_decoder->GetCodecDecoderName();
839
840 Map["framerate"] = QString("%1%2%3")
841 .arg(static_cast<double>(m_outputJmeter.GetLastFPS()), 0, 'f', 2).arg(QChar(0xB1, 0))
842 .arg(static_cast<double>(m_outputJmeter.GetLastSD()), 0, 'f', 2);
843 Map["load"] = m_outputJmeter.GetLastCPUStats();
844
846
847 QString displayfps = QString("%1x%2@%3Hz")
848 .arg(m_display->GetResolution().width())
849 .arg(m_display->GetResolution().height())
850 .arg(m_display->GetRefreshRate(), 0, 'f', 2);
851 Map["displayfps"] = displayfps;
852}
853
855{
856 Map["audiocodec"] = avcodec_get_name(m_audio.GetCodec());
857 Map["audiochannels"] = QString::number(m_audio.GetOrigChannels());
858
859 int width = m_videoDispDim.width();
860 int height = m_videoDispDim.height();
861 Map["videocodec"] = GetEncodingType();
862 if (m_decoder)
863 Map["videocodecdesc"] = m_decoder->GetRawEncodingType();
864 Map["videowidth"] = QString::number(width);
865 Map["videoheight"] = QString::number(height);
866 Map["videoframerate"] = QString::number(m_videoFrameRate, 'f', 2);
867 Map["deinterlacer"] = GetDeinterlacerName();
868
869 if (width < 640)
870 return;
871
872 bool interlaced = is_interlaced(GetScanType());
873 if (height > 2100)
874 Map["videodescrip"] = interlaced ? "UHD_4K_I" : "UHD_4K_P";
875 else if (width == 1920 || height == 1080 || height == 1088)
876 Map["videodescrip"] = interlaced ? "HD_1080_I" : "HD_1080_P";
877 else if ((width == 1280 || height == 720) && !interlaced)
878 Map["videodescrip"] = "HD_720_P";
879 else if (height >= 720)
880 Map["videodescrip"] = "HD";
881 else
882 Map["videodescrip"] = "SD";
883}
884
886{
888 if (Visible)
889 {
890 // This should already have enabled the required monitors
891 m_osdDebugTimer.start();
892 }
893 else
894 {
895 // If we have cleared/escaped the debug OSD screen, then ChangeOSDDebug
896 // is not called, so we need to ensure we turn off the monitors
897 m_osdDebugTimer.stop();
900 }
901}
902
904{
905 m_osdLock.lock();
906 InfoMap infoMap;
907 GetPlaybackData(infoMap);
910 m_osdLock.unlock();
911}
912
914{
915 m_osdLock.lock();
916 bool enable = !m_osdDebug;
917 EnableBitrateMonitor(enable);
919 if (enable)
921 else
923 m_osdDebug = enable;
924 m_osdLock.unlock();
925}
926
928{
929 bool enable = VERBOSE_LEVEL_CHECK(VB_PLAYBACK, LOG_ANY) || Enable;
930 m_outputJmeter.SetNumCycles(enable ? static_cast<int>(m_videoFrameRate) : 0);
931}
932
934{
937}
938
939/* JumpToStream, JumpToProgram and SwitchToProgram all need to be moved into the
940 * parent object and hopefully simplified. The fairly involved logic does not
941 * sit well with the new design objectives for the player classes and are better
942 * suited to the high level logic in TV.
943 */
944void MythPlayerUI::JumpToStream(const QString &stream)
945{
946 LOG(VB_PLAYBACK, LOG_INFO, LOC + "JumpToStream - begin");
947
948 // Shouldn't happen
949 if (stream.isEmpty())
950 return;
951
952 Pause();
954
955 ProgramInfo pginfo(stream);
956 SetPlayingInfo(pginfo);
957
960 else
961 m_playerCtx->m_buffer->OpenFile(stream);
962
963 if (!m_playerCtx->m_buffer->IsOpen())
964 {
965 LOG(VB_GENERAL, LOG_ERR, LOC + "JumpToStream buffer OpenFile failed");
967 SetErrored(tr("Error opening remote stream buffer"));
968 return;
969 }
970
971 m_watchingRecording = false;
972 m_totalLength = 0s;
973 m_totalFrames = 0;
974 m_totalDuration = 0s;
975
976 // 120 retries ~= 60 seconds
977 if (OpenFile(120) < 0)
978 {
979 LOG(VB_GENERAL, LOG_ERR, LOC + "JumpToStream OpenFile failed.");
981 SetErrored(tr("Error opening remote stream"));
982 return;
983 }
984
985 if (m_totalLength == 0s)
986 {
987 long long len = m_playerCtx->m_buffer->GetRealFileSize();
988 m_totalLength = std::chrono::seconds(len / ((m_decoder->GetRawBitrate() * 1000) / 8));
989 m_totalFrames = static_cast<uint64_t>(m_totalLength.count() * SafeFPS());
990 }
991
992 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("JumpToStream length %1 bytes @ %2 Kbps = %3 Secs, %4 frames @ %5 fps")
994 .arg(m_totalLength.count()).arg(m_totalFrames).arg(m_decoder->GetFPS()) );
995
997
998 // the bitrate is reset by m_playerCtx->m_buffer->OpenFile()...
1000 m_decoder->SetProgramInfo(pginfo);
1001
1002 Play();
1003 ChangeSpeed();
1004
1006#if CONFIG_MHEG
1007 if (m_interactiveTV) m_interactiveTV->StreamStarted();
1008#endif
1009
1010 LOG(VB_PLAYBACK, LOG_INFO, LOC + "JumpToStream - end");
1011}
1012
1014{
1015 if (!IsReallyNearEnd())
1016 return;
1017
1018 LOG(VB_PLAYBACK, LOG_INFO, LOC + "SwitchToProgram - start");
1019 bool discontinuity = false;
1020 bool newtype = false;
1021 int newid = -1;
1022 ProgramInfo *pginfo = m_playerCtx->m_tvchain->GetSwitchProgram(discontinuity, newtype, newid);
1023 if (!pginfo)
1024 return;
1025
1026 bool newIsDummy = m_playerCtx->m_tvchain->GetInputType(newid) == "DUMMY";
1027
1028 SetPlayingInfo(*pginfo);
1029 Pause();
1030 ChangeSpeed();
1031
1032 // Release all frames to ensure the current decoder resources are released
1033 DiscardVideoFrames(true, true);
1034
1035 if (newIsDummy)
1036 {
1037 OpenDummy();
1038 ResetPlaying();
1040 delete pginfo;
1041 return;
1042 }
1043
1045 {
1046 // Restore original ringbuffer
1047 auto *ic = dynamic_cast<MythInteractiveBuffer*>(m_playerCtx->m_buffer);
1048 if (ic)
1049 m_playerCtx->m_buffer = ic->TakeBuffer();
1050 delete ic;
1051 }
1052
1054
1055 if (!m_playerCtx->m_buffer->IsOpen())
1056 {
1057 LOG(VB_GENERAL, LOG_ERR, LOC + QString("SwitchToProgram's OpenFile failed (input type: %1)")
1058 .arg(m_playerCtx->m_tvchain->GetInputType(newid)));
1059 LOG(VB_GENERAL, LOG_ERR, m_playerCtx->m_tvchain->toString());
1061 SetErrored(tr("Error opening switch program buffer"));
1062 delete pginfo;
1063 return;
1064 }
1065
1066 if (GetEof() != kEofStateNone)
1067 {
1068 discontinuity = true;
1069 ResetCaptions();
1070 }
1071
1072 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("SwitchToProgram(void) "
1073 "discont: %1 newtype: %2 newid: %3 decoderEof: %4")
1074 .arg(discontinuity).arg(newtype).arg(newid).arg(GetEof()));
1075
1076 if (discontinuity || newtype)
1077 {
1078 m_playerCtx->m_tvchain->SetProgram(*pginfo);
1079 if (m_decoder)
1080 m_decoder->SetProgramInfo(*pginfo);
1081
1082 m_playerCtx->m_buffer->Reset(true);
1083 if (newtype)
1084 {
1085 if (OpenFile() < 0)
1086 SetErrored(tr("Error opening switch program file"));
1087 }
1088 else
1089 {
1090 ResetPlaying();
1091 }
1092 }
1093 else
1094 {
1096 if (m_decoder)
1097 {
1100 }
1101 }
1102 delete pginfo;
1103
1104 if (IsErrored())
1105 {
1106 LOG(VB_GENERAL, LOG_ERR, LOC + "SwitchToProgram failed.");
1108 return;
1109 }
1110
1112
1113 // the bitrate is reset by m_playerCtx->m_buffer->OpenFile()...
1114 if (m_decoder)
1117
1118 if (discontinuity || newtype)
1119 {
1120 CheckTVChain();
1122 }
1123
1124 Play();
1125 LOG(VB_PLAYBACK, LOG_INFO, LOC + "SwitchToProgram - end");
1126}
1127
1129{
1130 LOG(VB_PLAYBACK, LOG_INFO, LOC + "JumpToProgram - start");
1131 bool discontinuity = false;
1132 bool newtype = false;
1133 int newid = -1;
1134 std::chrono::seconds nextpos = m_playerCtx->m_tvchain->GetJumpPos();
1135 ProgramInfo *pginfo = m_playerCtx->m_tvchain->GetSwitchProgram(discontinuity, newtype, newid);
1136 if (!pginfo)
1137 return;
1138
1140
1141 bool newIsDummy = m_playerCtx->m_tvchain->GetInputType(newid) == "DUMMY";
1142 SetPlayingInfo(*pginfo);
1143
1144 Pause();
1145 ChangeSpeed();
1146 ResetCaptions();
1147
1148 // Release all frames to ensure the current decoder resources are released
1149 DiscardVideoFrames(true, true);
1150
1151 m_playerCtx->m_tvchain->SetProgram(*pginfo);
1152 m_playerCtx->m_buffer->Reset(true);
1153
1154 if (newIsDummy)
1155 {
1156 OpenDummy();
1157 ResetPlaying();
1159 delete pginfo;
1160 m_inJumpToProgramPause = false;
1161 return;
1162 }
1163
1164 SendMythSystemPlayEvent("PLAY_CHANGED", pginfo);
1165
1167 {
1168 // Restore original ringbuffer
1169 auto *ic = dynamic_cast<MythInteractiveBuffer*>(m_playerCtx->m_buffer);
1170 if (ic)
1171 m_playerCtx->m_buffer = ic->TakeBuffer();
1172 delete ic;
1173 }
1174
1176 if (!m_playerCtx->m_buffer->IsOpen())
1177 {
1178 LOG(VB_GENERAL, LOG_ERR, LOC + QString("JumpToProgram's OpenFile failed (input type: %1)")
1179 .arg(m_playerCtx->m_tvchain->GetInputType(newid)));
1180 LOG(VB_GENERAL, LOG_ERR, m_playerCtx->m_tvchain->toString());
1182 SetErrored(tr("Error opening jump program file buffer"));
1183 delete pginfo;
1184 m_inJumpToProgramPause = false;
1185 return;
1186 }
1187
1189
1190 bool wasDummy = m_isDummy;
1191 if (newtype || wasDummy)
1192 {
1193 if (OpenFile() < 0)
1194 SetErrored(tr("Error opening jump program file"));
1195 }
1196 else
1197 {
1198 ResetPlaying();
1199 }
1200
1201 if (IsErrored() || !m_decoder)
1202 {
1203 LOG(VB_GENERAL, LOG_ERR, LOC + "JumpToProgram failed.");
1204 if (!IsErrored())
1205 SetErrored(tr("Error reopening video decoder"));
1206 delete pginfo;
1207 m_inJumpToProgramPause = false;
1208 return;
1209 }
1210
1212
1213 // the bitrate is reset by m_playerCtx->m_buffer->OpenFile()...
1216
1217 m_decoder->SetProgramInfo(*pginfo);
1218 delete pginfo;
1219
1220 CheckTVChain();
1222 m_inJumpToProgramPause = false;
1223 Play();
1224 ChangeSpeed();
1225
1226 // check that we aren't too close to the end of program.
1227 // and if so set it to 10s from the end if completed recordings
1228 // or 3s if live
1229 std::chrono::seconds duration = m_playerCtx->m_tvchain->GetLengthAtCurPos();
1230 std::chrono::seconds maxpos = m_playerCtx->m_tvchain->HasNext() ? 10s : 3s;
1231
1232 if (nextpos > (duration - maxpos))
1233 {
1234 nextpos = duration - maxpos;
1235 if (nextpos < 0s)
1236 nextpos = 0s;
1237 }
1238 else if (nextpos < 0s)
1239 {
1240 // it's a relative position to the end
1241 nextpos += duration;
1242 }
1243
1244 // nextpos is the new position to use in seconds
1245 uint64_t nextframe = TranslatePositionMsToFrame(nextpos, true);
1246
1247 if (nextpos > 10s)
1248 DoJumpToFrame(nextframe, kInaccuracyNone);
1249
1251 LOG(VB_PLAYBACK, LOG_INFO, LOC + "JumpToProgram - end");
1252}
#define Clear(a)
virtual std::chrono::milliseconds GetAudioBufferedTime(void)
report amount of audio buffered in milliseconds.
Definition: audiooutput.h:142
AudioOutput * GetAudioOutput(void) const
Return internal AudioOutput object.
Definition: audioplayer.h:102
bool IsPaused(void)
float GetStretchFactor(void) const
Definition: audioplayer.h:64
int GetSampleRate(void) const
Definition: audioplayer.h:60
void DeleteOutput(void)
Definition: audioplayer.cpp:95
int GetOrigChannels(void) const
Definition: audioplayer.h:59
AVCodecID GetCodec(void) const
Definition: audioplayer.h:58
A decoder for media files.
CommSkipMode GetAutoCommercialSkip(void) const
bool DoSkipCommercials(uint64_t &jumpToFrame, uint64_t framesPlayed, double video_frame_rate, uint64_t totalFrames, QString &comm_msg)
void LoadMap(PlayerContext *player_ctx, uint64_t framesPlayed)
bool HasMap(void) const
Definition: commbreakmap.h:25
bool AutoCommercialSkip(uint64_t &jumpToFrame, uint64_t framesPlayed, double video_frame_rate, uint64_t totalFrames, QString &comm_msg)
int GetSkipCommercials(void) const
Definition: commbreakmap.h:30
void SkipCommercials(int direction)
virtual QString GetRawEncodingType(void)
Definition: decoderbase.h:199
virtual uint GetTrackCount(uint Type)
void SetProgramInfo(const ProgramInfo &pginfo)
Definition: decoderbase.cpp:41
virtual QString GetCodecDecoderName(void) const =0
virtual void UpdateFramesPlayed(void)
void SetReadAdjust(long long adjust)
uint GetRawBitrate(void) const
Returns the estimated bitrate if the video were played at normal speed.
Definition: decoderbase.h:191
void SetWaitForChange(void)
bool GetWaitForChange(void) const
int GetfpsMultiplier(void) const
Definition: decoderbase.h:252
StreamInfo GetTrackInfo(uint Type, uint TrackNo)
EofState GetEof(void)
Definition: decoderbase.h:135
virtual double GetFPS(void) const
Definition: decoderbase.h:189
void UpdateOSD(uint64_t frame, double frame_rate, OSD *osd)
Show and update the edit mode On Screen Display.
Definition: deletemap.cpp:177
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:847
bool IsEditing(void) const
Definition: deletemap.h:41
bool IsEmpty(void) const
Definition: deletemap.cpp:259
bool Detect(MythVideoFrame *Frame, float VideoAspect, AdjustFillMode &Current)
Detects if this frame is or is not letterboxed.
bool RecordCycleTime()
void SetNumCycles(int cycles)
QString GetLastCPUStats(void) const
Definition: jitterometer.h:55
float GetLastFPS(void) const
Definition: jitterometer.h:53
float GetLastSD(void) const
Definition: jitterometer.h:54
bool HasNext(void) const
std::chrono::seconds GetJumpPos(void)
Returns the jump position in seconds and clears it.
bool NeedsToSwitch(void) const
Returns true iff a switch is required but no jump is required m_jumppos sets to INT_MAX means not set...
Definition: livetvchain.h:66
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...
void SetProgram(const ProgramInfo &pginfo)
QString toString() const
ProgramInfo * GetSwitchProgram(bool &discont, bool &newtype, int &newid)
Returns the recording we should switch to.
std::chrono::seconds GetLengthAtCurPos(void)
bool NeedsToJump(void) const
Returns true iff a switch and jump are required.
Definition: livetvchain.h:69
QString GetInputType(int pos=-1) const
void EnableSubtitles(int Type, bool ForcedOnly=false)
MythScreenType * GetWindow(const QString &Window) override
void SendMessage(const QString &message)
double GetRefreshRate() const
std::chrono::microseconds GetRefreshInterval(std::chrono::microseconds Fallback) const
QSize GetResolution()
long long GetRealFileSize(void) const
QString GetStorageRate(void)
void Reset(bool Full=false, bool ToAdjust=false, bool ResetInternal=false)
Resets the read-ahead thread and our position in the file.
MythBufferType GetType() const
void ResetCommsError(void)
bool GetCommsError(void) const
void UpdateRawBitrate(uint RawBitrate)
Set the raw bit rate, to allow RingBuffer adjust effective bitrate.
void IgnoreLiveEOF(bool Ignore)
Tells RingBuffer whether to ignore the end-of-file.
QString GetSafeFilename(void)
void EnableBitrateMonitor(bool Enable)
virtual bool OpenFile(const QString &Filename, std::chrono::milliseconds Retry=kDefaultOpenTimeout)=0
uint GetBufferSize(void) const
QString GetAvailableBuffer(void)
QString GetDecoderRate(void)
virtual bool IsOpen(void) const =0
static QString BitrateToString(uint64_t Rate, bool Hz=false)
long long SetAdjustFilesize(void)
void Unpause(void)
Unpauses the read-ahead thread.
static constexpr std::chrono::milliseconds kLiveTVOpenTimeout
virtual bool Init(QRect Rect, float FontAspect)
void SetPlayer(MythPlayerUI *Player)
void GetAVSyncData(InfoMap &Map) const
std::chrono::microseconds AVSync(AudioPlayer *Audio, MythVideoFrame *Frame, std::chrono::microseconds FrameInterval, float PlaySpeed, bool HaveVideo, bool Force)
void SetRefreshInterval(std::chrono::microseconds interval)
void WaitForFrame(std::chrono::microseconds FrameDue)
std::chrono::milliseconds & DisplayTimecode()
virtual void SetTrack(uint Type, uint TrackNo)
InteractiveTV * GetInteractiveTV() override
void SetCaptionsEnabled(bool Enable, bool UpdateOSD=true)
MythCaptionsOverlay m_captionsOverlay
MythCaptionsState m_captionsState
void EnableSubtitles(bool Enable)
InteractiveTV * m_interactiveTV
void InitialiseState() override
QElapsedTimer m_editUpdateTimer
void UpdateOSDPosition()
Update the OSD status/position window.
void UpdateOSDMessage(const QString &Message)
void SetOSDStatus(const QString &Title, OSDTimeout Timeout)
QRecursiveMutex m_osdLock
MythPainter * m_painter
virtual void PreProcessNormalFrame()
MythDisplay * m_display
Definition: mythplayerui.h:72
void SwitchToProgram()
virtual void SetLastPlayPosition(uint64_t frame=0)
virtual void VideoStart()
MythPlayerUI(MythMainWindow *MainWindow, TV *Tv, PlayerContext *Context, PlayerFlags Flags)
QTimer m_osdDebugTimer
Definition: mythplayerui.h:70
bool StartPlaying()
void FileChanged()
void RenderVideoFrame(MythVideoFrame *Frame, FrameScanType Scan, bool Prepare, std::chrono::microseconds Wait)
void GetPlaybackData(InfoMap &Map)
virtual void InitialSeek()
virtual bool VideoLoop()
virtual void SetBookmark(bool Clear=false)
void InitFrameInterval() override
void ChangeOSDDebug()
virtual void DisplayPauseFrame()
virtual void EventStart()
bool CanSupportDoubleRate()
std::chrono::microseconds m_refreshInterval
Definition: mythplayerui.h:60
void RefreshPauseFrame()
void SetWatched(bool ForceWatched=false)
Determines if the recording should be considered watched.
void InitialiseState() override
void ChangeSpeed() override
void EnableBitrateMonitor(bool Enable=false)
void DoDisplayVideoFrame(MythVideoFrame *Frame, std::chrono::microseconds Due)
void GetCodecDescription(InfoMap &Map)
void JumpToStream(const QString &stream)
Jitterometer m_outputJmeter
Definition: mythplayerui.h:59
virtual void EventLoop()
virtual bool DisplayNormalFrame(bool CheckPrebuffer=true)
void ReinitVideo(bool ForceUpdate) override
void OSDDebugVisibilityChanged(bool Visible)
void JumpToProgram()
void UpdateOSDDebug()
void EnableFrameRateMonitor(bool Enable=false)
void SetVideoParams(int Width, int Height, double FrameRate, float Aspect, bool ForceUpdate, int ReferenceFrames, FrameScanType Scan=kScan_Ignore, const QString &CodecName=QString()) override
DetectLetterbox m_detectLetterBox
void CheckAspectRatio(MythVideoFrame *Frame)
bool InitVideo() override
void AutoVisualise(bool HaveVideo)
Enable visualisation if possible, there is no video and user has requested.
bool m_needNewPauseFrame
Definition: mythplayer.h:391
void SetEof(EofState eof)
void OpenDummy(void)
Definition: mythplayer.cpp:395
bool m_normalSpeed
Definition: mythplayer.h:493
bool FlagIsSet(PlayerFlags arg)
Definition: mythplayer.h:318
std::chrono::microseconds m_frameInterval
always adjusted for play_speed
Definition: mythplayer.h:486
long long m_rewindTime
Definition: mythplayer.h:428
bool m_inJumpToProgramPause
Definition: mythplayer.h:385
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:321
virtual bool HasReachedEof(void) const
Definition: mythplayer.cpp:656
uint64_t TranslatePositionMsToFrame(std::chrono::milliseconds position, bool use_cutlist) const
Definition: mythplayer.h:257
bool m_decodeOneFrame
Definition: mythplayer.h:389
bool m_captionsEnabledbyDefault
This allows us to enable captions/subtitles later if the streams are not immediately available when t...
Definition: mythplayer.h:462
bool m_allPaused
Definition: mythplayer.h:394
bool m_disableForcedSubtitles
Definition: mythplayer.h:464
virtual void DecoderStart(bool start_paused)
bool UpdateFFRewSkip(float ffrewScale=1.0F)
DecoderBase * m_decoder
Definition: mythplayer.h:362
DeleteMap m_deleteMap
Definition: mythplayer.h:478
static const double kInaccuracyNone
Definition: mythplayer.h:239
void DoJumpToFrame(uint64_t frame, double inaccuracy)
AudioPlayer m_audio
Definition: mythplayer.h:472
uint64_t GetCurrentFrameCount(void) const
uint64_t m_framesPlayed
Definition: mythplayer.h:424
CommBreakMap m_commBreakMap
Definition: mythplayer.h:475
int m_fpsMultiplier
used to detect changes
Definition: mythplayer.h:487
void SeekingSlow(int Count)
long long CalcRWTime(long long rw) const
CalcRWTime(rw): rewind rw frames back.
void DiscardVideoFrames(bool KeyFrame, bool Flushed)
Places frames in the available frames queue.
Definition: mythplayer.cpp:645
virtual void ResetPlaying(bool resetframes=true)
Definition: mythplayer.cpp:919
virtual int OpenFile(int Retries=4)
Definition: mythplayer.cpp:417
virtual void InitFrameInterval()
Definition: mythplayer.cpp:694
bool m_isDummy
Definition: mythplayer.h:500
uint64_t m_bookmarkSeek
Definition: mythplayer.h:413
int m_jumpChapter
Definition: mythplayer.h:410
virtual long long CalcMaxFFTime(long long ff, bool setjump=true) const
CalcMaxFFTime(ffframes): forward ffframes forward.
bool m_forcePositionMapSync
Definition: mythplayer.h:476
bool m_renderOneFrame
Definition: mythplayer.h:390
int m_ffrewSkip
Definition: mythplayer.h:488
virtual void ReinitVideo(bool ForceUpdate)
Definition: mythplayer.cpp:294
std::chrono::seconds m_totalDuration
Definition: mythplayer.h:427
float m_nextPlaySpeed
Definition: mythplayer.h:483
void SetErrored(const QString &reason)
uint64_t m_totalFrames
Definition: mythplayer.h:425
bool m_videoPaused
Definition: mythplayer.h:393
bool IsNearEnd(void)
Returns true iff near end of recording.
bool IsWatchingInprogress(void) const
Definition: mythplayer.cpp:127
float m_playSpeed
Definition: mythplayer.h:484
bool m_enableForcedSubtitles
Definition: mythplayer.h:463
bool IsErrored(void) const
QSize m_videoDispDim
Video (input) width & height.
Definition: mythplayer.h:438
int m_endExitPrompt
Definition: mythplayer.h:414
bool volatile m_killDecoder
Definition: mythplayer.h:388
QSize m_videoDim
Video (input) buffer width & height.
Definition: mythplayer.h:439
virtual bool PrebufferEnoughFrames(int min_buffers=0)
Definition: mythplayer.cpp:720
void SeekingComplete()
MythPlayerAVSync m_avSync
Definition: mythplayer.h:430
void SetBuffering(bool new_buffering)
Definition: mythplayer.cpp:700
bool m_watchingRecording
Definition: mythplayer.h:404
bool IsReallyNearEnd(void) const
Returns true iff really near end of recording.
float m_videoAspect
Video (input) Apect Ratio.
Definition: mythplayer.h:441
bool Pause(void)
Definition: mythplayer.cpp:153
QThread * m_playerThread
Definition: mythplayer.h:368
virtual bool DoJumpChapter(int chapter)
int m_bufferingCounter
Definition: mythplayer.h:503
double m_videoFrameRate
Video (input) Frame Rate (often inaccurate)
Definition: mythplayer.h:435
void ClearAfterSeek(bool clearvideobuffers=true)
This is to support seeking...
virtual void ChangeSpeed(void)
long long m_ffTime
If m_ffTime>0, number of frames to seek forward.
Definition: mythplayer.h:419
std::chrono::milliseconds m_latestVideoTimecode
Definition: mythplayer.h:429
void SetPlayingInfo(const ProgramInfo &pginfo)
Definition: mythplayer.cpp:231
bool GetAllowForcedSubtitles(void) const
Definition: mythplayer.h:204
void UnpauseDecoder(void)
Definition: mythplayer.cpp:992
bool Play(float speed=1.0, bool normal=true, bool unpauseaudio=true)
Definition: mythplayer.cpp:186
bool m_hasFullPositionMap
Definition: mythplayer.h:406
void CheckTVChain()
Definition: mythplayer.cpp:933
void SetPlaying(bool is_playing)
Definition: mythplayer.cpp:242
PlayerContext * m_playerCtx
Definition: mythplayer.h:366
std::chrono::seconds m_totalLength
Definition: mythplayer.h:426
MythVideoOutput * m_videoOutput
Definition: mythplayer.h:364
void SeekingDone()
bool DoRewind(uint64_t frames, double inaccuracy)
void SetFrameInterval(FrameScanType scan, double frame_period)
Definition: mythplayer.cpp:684
QString GetEncodingType(void) const
EofState GetEof(void) const
bool m_fileChanged
Definition: mythplayer.h:491
static const double kInaccuracyDefault
Definition: mythplayer.h:240
bool DoFastForward(uint64_t frames, double inaccuracy)
uint m_keyframeDist
Video (input) Number of frames between key frames (often inaccurate)
Definition: mythplayer.h:445
AdjustFillMode GetAdjustFill(void) const
void ToggleAdjustFill(AdjustFillMode AdjustFillMode=kAdjustFill_Toggle)
Sets up letterboxing for various standard video frame and monitor dimensions, then calls MoveResize()...
QRect GetDisplayVisibleRect(void) const
virtual void UpdatePauseFrame(std::chrono::milliseconds &, FrameScanType=kScan_Progressive)
Definition: mythvideoout.h:87
virtual void StartDisplayingFrame()
Tell GetLastShownFrame() to return the next frame from the head of the queue of frames to display.
virtual void GetOSDBounds(QRect &Total, QRect &Visible, float &VisibleAspect, float &FontScaling, float ThemeAspect) const
virtual int ValidVideoFrames() const
Returns number of frames that are fully decoded.
bool IsErrored() const
virtual void EndFrame()=0
virtual void PrepareFrame(MythVideoFrame *Frame, FrameScanType Scan=kScan_Ignore)=0
virtual long long GetFramesPlayed()
virtual void RenderEnd()=0
virtual MythVideoFrame * GetLastShownFrame()
Returns frame from the head of the ready to be displayed queue, if StartDisplayingFrame has been call...
int FreeVideoFrames()
Returns number of frames available for decoding onto.
virtual void SetFramesPlayed(long long FramesPlayed)
virtual void DoneDisplayingFrame(MythVideoFrame *Frame)
Releases frame returned from GetLastShownFrame() onto the queue of frames ready for decoding onto.
virtual void RenderFrame(MythVideoFrame *Frame, FrameScanType)=0
FrameScanType GetScanForDisplay(MythVideoFrame *Frame, bool &SecondField)
FrameScanType DetectInterlace(FrameScanType NewScan, float Rate, int VideoHeight)
void SetScanType(FrameScanType Scan, MythVideoOutput *VideoOutput, std::chrono::microseconds FrameInterval)
void CheckScanUpdate(MythVideoOutput *VideoOutput, std::chrono::microseconds FrameInterval)
FrameScanType GetScanType() const
void InitialiseScan(MythVideoOutput *VideoOutput)
virtual void AutoDeint(MythVideoFrame *Frame, MythVideoOutput *VideoOutput, std::chrono::microseconds FrameInterval, bool AllowLock=true)
Check whether deinterlacing should be enabled.
void ResetWindow(const QString &Window)
Definition: osd.cpp:636
bool Init(QRect Rect, float FontAspect) override
Definition: osd.cpp:51
void Draw()
Definition: osd.cpp:458
void HideWindow(const QString &Window) override
Definition: osd.cpp:675
void SetText(const QString &Window, const InfoMap &Map, OSDTimeout Timeout)
Definition: osd.cpp:210
void LockPlayingInfo(const char *file, int line) const
TVState GetState(void) const
void SetPlayerChangingBuffers(bool val)
Definition: playercontext.h:89
bool IsRecorderErrored(void) const
MythMediaBuffer * m_buffer
LiveTVChain * m_tvchain
void UnlockPlayingInfo(const char *file, int line) const
ProgramInfo * m_playingInfo
Currently playing info.
Holds information on recordings and videos.
Definition: programinfo.h:68
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:373
void SetIgnoreProgStart(bool ignore)
If "ignore" is true QueryProgStart() will return 0, otherwise QueryProgStart() will return the progst...
Definition: programinfo.h:570
void SetIgnoreBookmark(bool ignore)
If "ignore" is true GetBookmark() will return 0, otherwise GetBookmark() will return the bookmark pos...
Definition: programinfo.h:563
void SaveWatched(bool watchedFlag)
Set "watched" field in recorded/videometadata to "watchedFlag".
void UpdateInUseMark(bool force=false)
QDateTime GetScheduledEndTime(void) const
The scheduled end time of the program.
Definition: programinfo.h:398
void SetIgnoreLastPlayPos(bool ignore)
If "ignore" is true QueryLastPlayPos() will return 0, otherwise QueryLastPlayPos() will return the la...
Definition: programinfo.h:578
bool IsRecording(void) const
Definition: programinfo.h:491
TranscodingStatus QueryTranscodeStatus(void) const
Returns the "transcoded" field in "recorded" table.
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:405
void SaveLastPlayPos(uint64_t frame)
TODO Move to RecordingInfo.
QString MakeUniqueKey(void) const
Creates a unique string that can be used to identify an existing recording.
Definition: programinfo.h:340
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false)
Returns filename or URL to be used to play back this recording.
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
Definition: programinfo.h:413
void SaveBookmark(uint64_t frame)
Clears any existing bookmark in DB and if frame is greater than 0 sets a new bookmark.
bool m_forced
Subtitle and RawText.
Definition: decoderbase.h:108
void ChangeOSDDebug()
void UpdateLastPlayPosition(uint64_t frame)
void UpdateBookmark(bool Clear=false)
void InitialisePlayerState()
Control TV playback.
Definition: tv_play.h:156
#define setpriority(x, y, z)
Definition: compat.h:129
#define PRIO_PROCESS
Definition: compat.h:128
EofState
Definition: decoderbase.h:68
@ kEofStateDelayed
Definition: decoderbase.h:70
@ kEofStateNone
Definition: decoderbase.h:69
@ kEofStateImmediate
Definition: decoderbase.h:71
@ kTrackTypeRawText
Definition: decoderbase.h:36
unsigned int uint
Definition: freesurround.h:24
static constexpr const char * OSD_WIN_INTERACT
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
@ DEINT_SHADER
Definition: mythframe.h:73
@ DEINT_CPU
Definition: mythframe.h:72
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
Definition: mythlogging.h:29
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
@ kMythBufferMHEG
PlayerFlags
Definition: mythplayer.h:65
@ kMusicChoice
Definition: mythplayer.h:76
@ kVideoIsNull
Definition: mythplayer.h:73
#define LOC
void SendMythSystemPlayEvent(const QString &msg, const ProgramInfo *pginfo)
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
def scan(profile, smoonURL, gate)
Definition: scan.py:54
@ kOSDTimeout_Short
Definition: osd.h:59
@ kOSDTimeout_None
Definition: osd.h:58
@ kOSDTimeout_Med
Definition: osd.h:60
static constexpr const char * OSD_WIN_MESSAGE
Definition: osd.h:29
static constexpr const char * OSD_WIN_DEBUG
Definition: osd.h:33
@ TRANSCODING_COMPLETE
Definition: programtypes.h:158
static eu8 clamp(eu8 value, eu8 low, eu8 high)
Definition: pxsup2dast.c:206
@ kCommSkipOff
Definition: tv.h:135
@ kState_WatchingPreRecorded
Watching Pre-recorded is a TV only state for when we are watching a pre-existing recording.
Definition: tv.h:70
@ kDisplayNone
Definition: videoouttypes.h:12
AdjustFillMode
Definition: videoouttypes.h:72
FrameScanType
Definition: videoouttypes.h:95
@ kScan_Intr2ndField
Definition: videoouttypes.h:99
@ kScan_Ignore
Definition: videoouttypes.h:96
@ kScan_Interlaced
Definition: videoouttypes.h:98
@ kScan_Detect
Definition: videoouttypes.h:97
@ kScan_Progressive
bool is_interlaced(FrameScanType Scan)