MythTV master
mythvideooutgpu.cpp
Go to the documentation of this file.
1// MythTV
2#include "libmythbase/mythconfig.h"
7
8#include "mythplayer.h"
9#include "mythvideogpu.h"
10#include "mythvideooutgpu.h"
11
12#ifdef _WIN32
14#include "videoout_d3d.h"
15#endif
16#if CONFIG_OPENGL
19#endif
20#if CONFIG_VULKAN
23#endif
24
25#define LOC QString("VidOutGPU: ")
26
28{
29#if CONFIG_OPENGL
30 if (dynamic_cast<MythRenderOpenGL*>(Render) != nullptr)
32#endif
33
34#if CONFIG_VULKAN
35 if (dynamic_cast<MythRenderVulkan*>(Render) != nullptr)
37#endif
38}
39
41 MythPainter* Painter, MythDisplay* MDisplay,
42 const QString& Decoder,
43 MythCodecID CodecID, const QSize VideoDim,
44 const QSize VideoDispDim, float VideoAspect,
45 float FrameRate, uint PlayerFlags,
46 const QString& Codec, int ReferenceFrames,
47 const VideoFrameTypes*& RenderFormats)
48{
49 if (!(MainWindow && Render && Painter && MDisplay))
50 {
51 LOG(VB_GENERAL, LOG_ERR, LOC + "Fatal error");
52 return nullptr;
53 }
54
56 {
57 LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot create null video output here");
58 return nullptr;
59 }
60
61 QStringList renderers;
62
63#ifdef _WIN32
64// auto * d3drender = dynamic_cast<MythRenderD3D9*>(Render);
65// auto * d3dpainter = dynamic_cast<MythD3D9Painter*>(Painter);
66// if (Render->Type() == kRenderDirect3D9)
67// renderers += VideoOutputD3D::GetAllowedRenderers(CodecID, VideoDispDim);
68#endif
69
70#if CONFIG_OPENGL
71 auto * openglrender = dynamic_cast<MythRenderOpenGL*>(Render);
72 auto * openglpainter = dynamic_cast<MythOpenGLPainter*>(Painter);
73 if (openglrender && openglpainter && (Render->Type() == kRenderOpenGL))
74 renderers += MythVideoOutputOpenGL::GetAllowedRenderers(openglrender, CodecID, VideoDispDim);
75#endif
76
77#if CONFIG_VULKAN
78 auto * vulkanrender = dynamic_cast<MythRenderVulkan*>(Render);
79 auto * vulkanpainter = dynamic_cast<MythPainterVulkan*>(Painter);
80 if (vulkanrender && vulkanpainter && (Render->Type() == kRenderVulkan))
82#endif
83
84 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Allowed renderers for %1 %2 (Decoder: %3): '%4'")
85 .arg(get_encoding_type(CodecID),
86 get_decoder_name(CodecID),
87 Decoder,
88 renderers.join(",")));
89 renderers = MythVideoProfile::GetFilteredRenderers(Decoder, renderers);
90 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Allowed renderers (filt: %1): %2")
91 .arg(Decoder, renderers.join(",")));
92
93 QString renderer;
94
95 auto videoprofile = std::make_shared<MythVideoProfile>();
96
97 if (!renderers.empty())
98 {
99 videoprofile->SetInput(VideoDispDim, FrameRate, Codec);
100 QString tmp = videoprofile->GetVideoRenderer();
101 if (videoprofile->IsDecoderCompatible(Decoder) && renderers.contains(tmp))
102 {
103 renderer = tmp;
104 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Preferred renderer: " + renderer);
105 }
106 else
107 {
108 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("No preferred renderer for decoder '%1' - profile renderer: '%2'")
109 .arg(Decoder, tmp));
110 }
111 }
112
113 if (renderer.isEmpty())
114 renderer = MythVideoProfile::GetBestVideoRenderer(renderers);
115
116 if (renderer.isEmpty())
117 {
118 QString fallback;
119#if CONFIG_OPENGL
120 if (Render->Type() == kRenderOpenGL)
121 fallback = "opengl";
122#endif
123#if CONFIG_VULKAN
124 if (Render->Type() == kRenderVulkan)
125 fallback = VULKAN_RENDERER;
126#endif
127 LOG(VB_GENERAL, LOG_WARNING, LOC + "No renderer found. This should not happen!.");
128 LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Falling back to '%1'").arg(fallback));
129 renderer = fallback;
130 }
131
132 while (!renderers.empty())
133 {
134 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Trying video renderer: '%1'").arg(renderer));
135 int index = renderers.indexOf(renderer);
136 if (index >= 0)
137 renderers.removeAt(index);
138 else
139 break;
140
141 MythVideoOutputGPU* video = nullptr;
142
143#ifdef _WIN32
144// if (renderer == "direct3d")
145// video = new VideoOutputD3D(MainWindow, d3drender,
146// d3dpainter, MDisplay,
147// videoprofile, renderer);
148#endif
149#if CONFIG_OPENGL
150 // cppcheck-suppress knownConditionTrueFalse
151 if (!video && renderer.contains("opengl") && openglrender)
152 {
153 video = new MythVideoOutputOpenGL(MainWindow, openglrender,
154 openglpainter, MDisplay,
155 videoprofile, renderer);
156 }
157#endif
158#if CONFIG_VULKAN
159 if (!video && renderer.contains(VULKAN_RENDERER))
160 {
161 video = new MythVideoOutputVulkan(MainWindow, vulkanrender,
162 vulkanpainter, MDisplay,
163 videoprofile, renderer);
164 }
165#endif
166
167 if (video)
168 {
169 video->SetVideoFrameRate(FrameRate);
170 video->SetReferenceFrames(ReferenceFrames);
171 if (video->Init(VideoDim, VideoDispDim, VideoAspect, MainWindow->GetUIScreenRect(), CodecID))
172 {
173 video->SetVideoScalingAllowed(true);
174 RenderFormats = video->m_renderFormats;
175 return video;
176 }
177 delete video;
178 video = nullptr;
179 }
180 renderer = MythVideoProfile::GetBestVideoRenderer(renderers);
181 }
182
183 LOG(VB_GENERAL, LOG_ERR, LOC + "Not compiled with any useable video output method.");
184 return nullptr;
185}
186
188{
189 if (codec_is_vaapi(CodecId)) return FMT_VAAPI;
190 if (codec_is_vdpau(CodecId)) return FMT_VDPAU;
191 if (codec_is_nvdec(CodecId)) return FMT_NVDEC;
192 if (codec_is_vtb(CodecId)) return FMT_VTB;
193 if (codec_is_mmal(CodecId)) return FMT_MMAL;
194 if (codec_is_v4l2(CodecId) || codec_is_drmprime(CodecId)) return FMT_DRMPRIME;
195 if (codec_is_mediacodec(CodecId)) return FMT_MEDIACODEC;
196 return FMT_NONE;
197}
198
212 MythPainterGPU* Painter, MythDisplay* MDisplay,
213 MythVideoProfilePtr VideoProfile, QString& Profile)
214 : m_mainWindow(MainWindow),
215 m_render(Render),
216 m_painter(Painter),
217 m_profile(std::move(Profile))
218{
219 if (!(m_mainWindow && m_render && m_painter && MDisplay))
220 {
221 LOG(VB_GENERAL, LOG_ERR, "Fatal error");
222 return;
223 }
224
225 m_videoProfile = std::move(VideoProfile);
226 m_render->IncrRef();
227 SetDisplay(MDisplay);
229
230 // If our rendering context is overlaid on top of a video plane, we need transparency
231 // and we need to ensure we are clearing the entire framebuffer.
232 // Note: an alpha of zero is probably safe to use everywhere. tbc.
233 if (m_display->IsPlanar())
234 {
235 m_clearAlpha = 0;
236 m_needFullClear = true;
237 }
238
240
253}
254
256{
257 m_hdrTracker = nullptr;
258
260 delete m_video;
261 if (m_painter)
263 if (m_render)
264 m_render->DecrRef();
265}
266
268{
269 return GetDisplayVisibleRect();
270}
271
273{
275}
276
278{
279 SetWindowSize(Size);
281}
282
284{
285 if (!m_videoProfile)
286 return;
287
288 if (qFuzzyCompare(m_videoProfile->GetOutput() + 1.0F, NewRate + 1.0F))
289 return;
290
291 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Video frame rate changed: %1->%2")
292 .arg(static_cast<double>(m_videoProfile->GetOutput())).arg(static_cast<double>(NewRate)));
293 m_videoProfile->SetOutput(NewRate);
294 m_newFrameRate = true;
295}
296
297bool MythVideoOutputGPU::Init(const QSize VideoDim, const QSize VideoDispDim,
298 float Aspect, const QRect DisplayVisibleRect, MythCodecID CodecId)
299{
300 // if we are the main video player then free up as much video memory
301 // as possible at startup
304
305 // Default initialisation - mainly MythVideoBounds
306 if (!MythVideoOutput::Init(VideoDim, VideoDispDim, Aspect, DisplayVisibleRect, CodecId))
307 return false;
308
309 // Ensure any new profile preferences are handled after a stream change
310 if (m_videoProfile)
311 m_video->SetProfile(m_videoProfile->GetVideoRenderer());
312
313 // Set default support for picture attributes
315
316 // Setup display
317 QSize size = GetVideoDim();
318
319 // Set the display mode if required
321 ResizeForVideo(size);
323
324 // Create buffers
326 if (!m_buffersCreated)
327 return false;
328
329 // Adjust visible rect for embedding
330 QRect dvr = GetDisplayVisibleRectAdj();
332 {
333 m_render->SetViewPort(QRect(QPoint(), dvr.size()));
334 return true;
335 }
336
337 // Reset OpenGLVideo
338 if (m_video->IsValid())
340
341 return true;
342}
343
350void MythVideoOutputGPU::DiscardFrames(bool KeyFrame, bool Flushed)
351{
352 if (Flushed)
353 {
354 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("(%1): %2").arg(KeyFrame).arg(m_videoBuffers.GetStatus()));
356 }
357 MythVideoOutput::DiscardFrames(KeyFrame, Flushed);
358}
359
372{
373 if (!Frame)
374 return;
375
376 auto retain = MythVideoFrame::HardwareFormat(Frame->m_type);
377 QVector<MythVideoFrame*> release;
378
381 {
383 if (!retain || (frame != Frame))
384 release.append(frame);
385 }
386
387 if (retain)
388 {
392 }
393 else
394 {
395 release.append(Frame);
396 }
398
399 for (auto * frame : release)
401}
402
404{
406 return true;
407
408 if (codec_is_copyback(CodecID))
409 {
411 return m_videoBuffers.CreateBuffers(FMT_YV12, Size.width(), Size.height(), m_renderFormats);
412 }
413
414 if (codec_is_mediacodec(CodecID))
416 if (codec_is_vaapi(CodecID))
418 if (codec_is_vtb(CodecID))
419 return m_videoBuffers.CreateBuffers(FMT_VTB, m_renderFormats, Size, 1, 4, 2);
420 if (codec_is_vdpau(CodecID))
422 if (codec_is_nvdec(CodecID))
424 if (codec_is_mmal(CodecID))
426 if (codec_is_v4l2(CodecID) || codec_is_drmprime(CodecID))
428
430}
431
433{
436 m_buffersCreated = false;
437}
438
440{
441 m_maxReferenceFrames = ReferenceFrames;
442}
443
444bool MythVideoOutputGPU::InputChanged(QSize VideoDim, QSize VideoDispDim,
445 float VideoAspect, MythCodecID CodecId,
446 bool& AspectOnly, int ReferenceFrames,
447 bool ForceChange)
448{
449 QSize currentvideodim = GetVideoDim();
450 QSize currentvideodispdim = GetVideoDispDim();
451 MythCodecID currentcodec = m_videoCodecID;
452 float currentaspect = GetVideoAspect();
453
455 {
456 // InputChanged has been called twice in quick succession without a call to ProcessFrame
457 currentvideodim = m_newVideoDim;
458 currentvideodispdim = m_newVideoDispDim;
459 currentcodec = m_newCodecId;
460 currentaspect = m_newAspect;
461 }
462
463 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Video changed: %1x%2 (%3x%4) '%5' (Aspect %6 Refs %13)"
464 "-> %7x%8 (%9x%10) '%11' (Aspect %12 Refs %14)")
465 .arg(currentvideodispdim.width()).arg(currentvideodispdim.height())
466 .arg(currentvideodim.width()).arg(currentvideodim.height())
467 .arg(toString(currentcodec)).arg(static_cast<double>(currentaspect))
468 .arg(VideoDispDim.width()).arg(VideoDispDim.height())
469 .arg(VideoDim.width()).arg(VideoDim.height())
470 .arg(toString(CodecId)).arg(static_cast<double>(VideoAspect))
471 .arg(m_maxReferenceFrames).arg(ReferenceFrames));
472
473 bool cidchanged = (CodecId != currentcodec);
474 bool reschanged = (VideoDispDim != currentvideodispdim);
475 bool refschanged = m_maxReferenceFrames != ReferenceFrames;
476
477 // aspect ratio changes are a no-op as changes are handled at display time
478 if (!(cidchanged || reschanged || refschanged || ForceChange))
479 {
480 AspectOnly = true;
481 return true;
482 }
483
484 // N.B. We no longer check for interop support for the new codec as it is a
485 // poor substitute for a full check of decoder capabilities etc. Better to let
486 // hardware decoding fail if necessary - which should at least fallback to
487 // software decoding rather than bailing out here.
488
489 // delete and recreate the buffers and flag that the input has changed
490 m_maxReferenceFrames = ReferenceFrames;
492 if (!m_buffersCreated)
493 return false;
494
495 m_newCodecId= CodecId;
496 m_newVideoDim = VideoDim;
497 m_newVideoDispDim = VideoDispDim;
498 m_newAspect = VideoAspect;
499 return true;
500}
501
503{
505 {
506 // Ensure we don't lose embedding through program changes.
507 bool wasembedding = IsEmbedding();
508 QRect oldrect;
509 if (wasembedding)
510 {
511 oldrect = GetEmbeddingRect();
512 EmbedPlayback(false, {});
513 }
514
515 // Note - we don't call the default VideoOutput::InputChanged method as
516 // the OpenGL implementation is asynchronous.
517 // So we need to update the video display profile here. It is a little
518 // circular as we need to set the video dimensions first which are then
519 // reset in Init.
520 // All told needs a cleanup - not least because the use of codecName appears
521 // to be inconsistent.
523 AVCodecID avCodecId = myth2av_codecid(m_newCodecId);
524 const AVCodec* codec = avcodec_find_decoder(avCodecId);
525 QString codecName;
526 if (codec)
527 codecName = codec->name;
528 if (m_videoProfile)
529 m_videoProfile->SetInput(GetVideoDispDim(), 0 , codecName);
532 m_newVideoDim = QSize();
533 m_newVideoDispDim = QSize();
534 m_newAspect = 0.0F;
535 m_newFrameRate = false;
536
537 if (wasembedding && ok)
538 EmbedPlayback(true, oldrect);
539
540 // Update deinterlacers for any input change
542
543 if (!ok)
544 return false;
545 }
546 else if (m_newFrameRate)
547 {
548 // If we are switching mode purely for a refresh rate change, then there
549 // is no need to recreate buffers etc etc
551 m_newFrameRate = false;
552 }
553
554 return true;
555}
556
563{
564 if (!m_display)
565 return;
566
567 // Retrieve the display aspect ratio.
568 // This will be, in priority order:-
569 // - aspect ratio override when using resolution/mode switching (if not 'Default')
570 // - aspect ratio override for setups where detection does not work/is broken (multiscreen, broken EDID etc)
571 // - aspect ratio based on detected physical size (this should be the common/default value)
572 // - aspect ratio fallback using screen resolution
573 // - 16:9
574 QString source;
575 double displayaspect = m_display->GetAspectRatio(source);
576 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Display aspect ratio: %1 (%2)")
577 .arg(displayaspect).arg(source));
578
579 // Get the window and screen resolutions
580 QSize window = GetRawWindowRect().size();
581 QSize screen = m_display->GetResolution();
582
583 // If not running fullscreen, adjust for window size and ignore any video
584 // mode overrides as they do not apply when in a window
585 if (!window.isEmpty() && !screen.isEmpty() && window != screen)
586 {
587 displayaspect = m_display->GetAspectRatio(source, true);
588 double screenaspect = screen.width() / static_cast<double>(screen.height());
589 double windowaspect = window.width() / static_cast<double>(window.height());
590 displayaspect = displayaspect * (1.0 / screenaspect) * windowaspect;
591 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Window aspect ratio: %1").arg(displayaspect));
592 }
593
594 SetDisplayAspect(static_cast<float>(displayaspect));
595}
596
598{
599 // Process input changes
600 if (!ProcessInputChange())
601 return;
602
603 if (Frame)
604 {
605 SetRotation(Frame->m_rotation);
606
607 if (m_hdrTracker)
608 m_hdrTracker->Update(Frame);
609
610 if (MythVideoFrame::HardwareFormat(Frame->m_type) || Frame->m_dummy)
611 return;
612
613 // software deinterlacing
615
616 // update software textures
617 if (m_video)
618 m_video->PrepareFrame(Frame, Scan);
619 }
620}
621
623{
624 bool dummy = false;
625 bool topfieldfirst = false;
626 if (Frame)
627 {
628 m_framesPlayed = Frame->m_frameNumber + 1;
629 topfieldfirst = Frame->m_interlacedReverse ? !Frame->m_topFieldFirst : Frame->m_topFieldFirst;
630 dummy = Frame->m_dummy;
631 }
632 else
633 {
634 // see DoneDisplayingFrame
635 // we only retain pause frames for hardware formats
638 }
639
640 // Main UI when embedded
641 if (m_painter && IsEmbedding())
642 {
643 // If we are using high dpi, the painter needs to set the appropriate
644 // viewport and enable scaling of its images
646
648 {
649 m_mainWindow->GetPaintWindow()->clearMask();
651 }
653 }
654
655 // Video
656 // N.B. dummy streams need the viewport updated in case we have resized the window (i.e. LiveTV)
657 if (m_video && !dummy)
658 m_video->RenderFrame(Frame, topfieldfirst, Scan, GetStereoOverride());
659 else if (dummy)
661}
662
663void MythVideoOutputGPU::UpdatePauseFrame(std::chrono::milliseconds& DisplayTimecode, FrameScanType Scan)
664{
665 MythVideoFrame* release = nullptr;
668 if (used)
669 {
671 {
673 }
674 else
675 {
677 m_deinterlacer.Filter(used, Scan, m_videoProfile.get(), true);
678 if (m_video)
679 m_video->PrepareFrame(used, Scan);
680 }
681 DisplayTimecode = used->m_displayTimecode;
682 }
683 else
684 {
685 LOG(VB_PLAYBACK, LOG_WARNING, LOC + "Could not update pause frame");
686 }
688
689 if (release)
690 DoneDisplayingFrame(release);
691}
692
694{
695 m_video->EndFrame();
696}
697
699{
700 // Clear reference frames for GPU deinterlacing
701 if (m_video)
703 // Clear decoded frames
705}
706
719{
720 if (!m_display)
721 return;
723 return;
724
725 if (Size.isEmpty())
726 {
727 Size = GetVideoDispDim();
728 if (Size.isEmpty())
729 return;
730 }
731
732 float rate = m_videoProfile ? m_videoProfile->GetOutput() : 0.0F;
733
734 bool hide = m_display->NextModeIsLarger(Size);
735 if (hide)
736 m_mainWindow->hide();
737
738 if (m_display->SwitchToVideo(Size, static_cast<double>(rate)))
739 {
740 // Switching to custom display resolution succeeded
741 // Make a note of the new size
742 QString source;
743 double aspect = m_display->GetAspectRatio(source);
744 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Aspect ratio: %1 (%2)")
745 .arg(aspect).arg(source));
746 SetDisplayAspect(static_cast<float>(aspect));
748
749 bool fullscreen = !UsingGuiSize();
750
751 // if width && height are zero users expect fullscreen playback
752 if (!fullscreen)
753 {
754 int gui_width = 0;
755 int gui_height = 0;
756 gCoreContext->GetResolutionSetting("Gui", gui_width, gui_height);
757 fullscreen |= (0 == gui_width && 0 == gui_height);
758 }
759
760 if (fullscreen)
761 {
762 QSize size = m_display->GetResolution();
763 QRect display_visible_rect = QRect(m_mainWindow->geometry().topLeft(), size);
764 if (hide)
765 {
767 hide = false;
768 }
769 m_mainWindow->MoveResize(display_visible_rect);
770 }
771 }
772 if (hide)
774}
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
void Filter(MythVideoFrame *Frame, FrameScanType Scan, MythVideoProfile *Profile, bool Force=false)
Deinterlace Frame if needed.
double GetAspectRatio(QString &Source, bool IgnoreModeOverride=false)
Returns current screen aspect ratio.
bool SwitchToVideo(QSize Size, double Rate=0.0)
Switches to the resolution and refresh rate defined in the database for the specified video resolutio...
virtual bool UsingVideoModes()
Definition: mythdisplay.h:30
QSize GetResolution()
bool NextModeIsLarger(QSize Size)
Check whether the next mode is larger in size than the current mode.
virtual bool IsPlanar()
Definition: mythdisplay.h:31
static HDRTracker Create(class MythDisplay *MDisplay)
Create a tracker instance that looks for changes in the required EOTF.
QWidget * GetPaintWindow()
void MoveResize(QRect &Geometry)
void Draw(MythPainter *Painter=nullptr)
void SetViewControl(ViewControls Control)
virtual void FreeResources(void)
Definition: mythpainter.h:53
RenderType Type(void) const
virtual void SetViewPort(const QRect, bool=false)
QRect GetEmbeddingRect(void) const
void RefreshVideoBoundsState()
Send out latest state to listeners.
void SetRotation(int Rotation)
Set the rotation in degrees.
bool IsEmbedding(void) const
virtual void EmbedPlayback(bool Embed, QRect Rect)
QSize GetVideoDim(void) const
QSize GetVideoDispDim(void) const
void SourceChanged(QSize VideoDim, QSize VideoDispDim, float Aspect)
Update for new source video dimensions and aspect ratio.
MythDisplay * m_display
void SetDisplayAspect(float DisplayAspect)
void SetVideoScalingAllowed(bool Change)
Disable or enable underscan/overscan.
QRect GetDisplayVisibleRect(void) const
QRect GetRawWindowRect(void) const
float GetVideoAspect(void) const
void SetDisplay(MythDisplay *mDisplay)
QRect GetWindowRect(void) const
void SetWindowSize(QSize Size)
StereoscopicMode GetStereoOverride() const
bool UsingGuiSize(void) const
void PictureAttributeChanged(PictureAttribute Attribute, int Value)
void SetSupportedAttributes(PictureAttributeSupported Supported)
Enable the given set of picture attributes.
void SupportedAttributesChanged(PictureAttributeSupported Supported)
void PictureAttributesUpdated(const std::map< PictureAttribute, int > &Values)
int ChangePictureAttribute(PictureAttribute Attribute, bool Direction, int Value)
std::chrono::milliseconds m_displayTimecode
Definition: mythframe.h:131
VideoFrameType m_type
Definition: mythframe.h:118
bool m_alreadyDeinterlaced
Definition: mythframe.h:153
static bool HardwareFormat(VideoFrameType Type)
Definition: mythframe.h:424
virtual void RenderFrame(MythVideoFrame *Frame, bool TopFieldFirst, FrameScanType Scan, StereoscopicMode StereoOverride, bool DrawBorder=false)=0
bool IsValid() const
virtual void PrepareFrame(MythVideoFrame *Frame, FrameScanType Scan=kScan_Progressive)=0
virtual void EndFrame()=0
virtual void ResetTextures()=0
virtual void ResetFrameFormat()
void SetProfile(const QString &Profile)
Common code shared between GPU accelerated sub-classes (e.g. OpenGL)
virtual QRect GetDisplayVisibleRectAdj()
MythCodecID m_newCodecId
MythVideoOutputGPU(MythMainWindow *MainWindow, MythRender *Render, MythPainterGPU *Painter, MythDisplay *Display, MythVideoProfilePtr VideoProfile, QString &Profile)
HDRTracker m_hdrTracker
MythMainWindow * m_mainWindow
void PrepareFrame(MythVideoFrame *Frame, FrameScanType Scan) override
void WindowResized(QSize Size)
void PictureAttributesUpdated(const std::map< PictureAttribute, int > &Values)
void SetVideoFrameRate(float NewRate) override
MythRender * m_render
static MythVideoOutputGPU * Create(MythMainWindow *MainWindow, MythRender *Render, MythPainter *Painter, MythDisplay *Display, const QString &Decoder, MythCodecID CodecID, QSize VideoDim, QSize VideoDispDim, float VideoAspect, float FrameRate, uint PlayerFlags, const QString &Codec, int ReferenceFrames, const VideoFrameTypes *&RenderFormats)
void UpdatePauseFrame(std::chrono::milliseconds &DisplayTimecode, FrameScanType Scan=kScan_Progressive) override
void EndFrame() override
MythPainterGPU * m_painter
~MythVideoOutputGPU() override
void ChangePictureAttribute(PictureAttribute Attribute, bool Direction, int Value)
static VideoFrameType FrameTypeForCodec(MythCodecID CodecId)
bool CreateBuffers(MythCodecID CodecID, QSize Size)
bool InputChanged(QSize VideoDim, QSize VideoDispDim, float VideoAspect, MythCodecID CodecId, bool &AspectOnly, int ReferenceFrames, bool ForceChange) override
Tells video output to discard decoded frames and wait for new ones.
void ResizeForVideo(QSize Size=QSize())
static void GetRenderOptions(RenderOptions &Options, MythRender *Render)
void PictureAttributeChanged(PictureAttribute Attribute, int Value)
void DiscardFrames(bool KeyFrame, bool Flushed) override
Discard video frames.
bool Init(QSize VideoDim, QSize VideoDispDim, float Aspect, QRect DisplayVisibleRect, MythCodecID CodecId) override
void InitDisplayMeasurements()
Initialise display measurement.
void SupportedAttributesChanged(PictureAttributeSupported Supported)
void SetReferenceFrames(int ReferenceFrames)
void DoneDisplayingFrame(MythVideoFrame *Frame) override
Release a video frame back into the decoder pool.
void InitPictureAttributes() override
void RenderFrame(MythVideoFrame *Frame, FrameScanType Scan) override
void ClearAfterSeek() override
Tells video output to toss decoded buffers due to a seek.
MythVideoGPU * m_video
static void GetRenderOptions(RenderOptions &Options)
Generate the list of available OpenGL profiles.
static QStringList GetAllowedRenderers(MythRenderOpenGL *Render, MythCodecID CodecId, QSize VideoDim)
Generate a list of supported OpenGL profiles.
static void GetRenderOptions(RenderOptions &Options)
static QStringList GetAllowedRenderers(MythCodecID CodecId)
MythCodecID m_videoCodecID
Definition: mythvideoout.h:98
long long m_framesPlayed
Definition: mythvideoout.h:103
virtual void ClearAfterSeek()
Tells video output to toss decoded buffers due to a seek.
virtual void SetDeinterlacing(bool Enable, bool DoubleRate, MythDeintType Force=DEINT_NONE)
MythVideoColourSpace m_videoColourSpace
Definition: mythvideoout.h:94
virtual bool Init(QSize VideoDim, QSize VideoDispDim, float VideoAspect, QRect WindowRect, MythCodecID CodecID)
MythVideoProfilePtr m_videoProfile
Definition: mythvideoout.h:100
MythDeintType m_forcedDeinterlacer
Definition: mythvideoout.h:109
uint8_t m_clearAlpha
Definition: mythvideoout.h:97
VideoBuffers m_videoBuffers
Definition: mythvideoout.h:101
MythDeinterlacer m_deinterlacer
Definition: mythvideoout.h:105
const VideoFrameTypes * m_renderFormats
Definition: mythvideoout.h:106
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...
int m_maxReferenceFrames
Definition: mythvideoout.h:99
static QStringList GetFilteredRenderers(const QString &Decoder, const QStringList &Renderers)
static QString GetBestVideoRenderer(const QStringList &Renderers)
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual int IncrRef(void)
Increments reference count.
static uint GetNumBuffers(int PixelFormat, int MaxReferenceFrames=16, bool Decoder=false)
frame_queue_t::iterator BeginLock(BufferType Type)
Lock the video buffers.
MythVideoFrame * Tail(BufferType Type)
QString GetStatus(uint Num=0) const
bool CreateBuffers(VideoFrameType Type, const VideoFrameTypes *RenderFormats, QSize Size, uint NeedFree, uint NeedprebufferNormal, uint NeedPrebufferSmall, int MaxReferenceFrames=16)
void Reset(void)
Resets the class so that Init may be called again.
bool Contains(BufferType Type, MythVideoFrame *Frame) const
void Remove(BufferType Type, MythVideoFrame *Frame)
void DiscardPauseFrames(void)
void DoneDisplayingFrame(MythVideoFrame *Frame)
Removes frame from used queue and adds it to the available list.
MythVideoFrame * Dequeue(BufferType Type)
void Enqueue(BufferType Type, MythVideoFrame *Frame)
void Init(uint NumDecode, uint NeedFree, uint NeedprebufferNormal, uint NeedPrebufferSmall)
Creates buffers and sets various buffer management parameters.
bool DiscardAndRecreate(MythCodecID CodecID, QSize VideoDim, int References)
Discard all buffers and recreate.
uint Size(BufferType Type) const
MythVideoFrame * Head(BufferType Type)
unsigned int uint
Definition: freesurround.h:24
static guint32 * tmp
Definition: goom_core.cpp:26
QString get_decoder_name(MythCodecID codec_id)
AVCodecID myth2av_codecid(MythCodecID codec_id)
QString get_encoding_type(MythCodecID codecid)
MythCodecID
Definition: mythcodecid.h:14
@ kCodec_NONE
Definition: mythcodecid.h:17
static bool codec_is_vdpau(MythCodecID id)
Definition: mythcodecid.h:304
static bool codec_is_mediacodec(MythCodecID id)
Definition: mythcodecid.h:337
static bool codec_is_drmprime(MythCodecID id)
Definition: mythcodecid.h:301
static bool codec_is_mmal(MythCodecID id)
Definition: mythcodecid.h:363
static bool codec_is_nvdec(MythCodecID id)
Definition: mythcodecid.h:344
static bool codec_is_vtb(MythCodecID id)
Definition: mythcodecid.h:351
static bool codec_is_v4l2(MythCodecID id)
Definition: mythcodecid.h:358
static bool codec_is_copyback(MythCodecID id)
Definition: mythcodecid.h:368
static bool codec_is_vaapi(MythCodecID id)
Definition: mythcodecid.h:321
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
std::vector< VideoFrameType > VideoFrameTypes
Definition: mythframe.h:82
VideoFrameType
Definition: mythframe.h:20
@ FMT_VAAPI
Definition: mythframe.h:57
@ FMT_VTB
Definition: mythframe.h:61
@ FMT_YV12
Definition: mythframe.h:23
@ FMT_DRMPRIME
Definition: mythframe.h:63
@ FMT_VDPAU
Definition: mythframe.h:56
@ FMT_NONE
Definition: mythframe.h:21
@ FMT_NVDEC
Definition: mythframe.h:62
@ FMT_MMAL
Definition: mythframe.h:59
@ FMT_MEDIACODEC
Definition: mythframe.h:60
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
PlayerFlags
Definition: mythplayer.h:65
@ kVideoIsNull
Definition: mythplayer.h:73
@ kRenderOpenGL
@ kRenderVulkan
std::shared_ptr< MythVideoProfile > MythVideoProfilePtr
Definition: mythvideogpu.h:18
#define LOC
#define VULKAN_RENDERER
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93
STL namespace.
@ kVideoBuffer_used
Definition: videobuffers.h:30
@ kVideoBuffer_pause
Definition: videobuffers.h:31
FrameScanType
Definition: videoouttypes.h:95
@ kScan_Interlaced
Definition: videoouttypes.h:98
@ kScan_Progressive
bool is_interlaced(FrameScanType Scan)
#define ALL_PICTURE_ATTRIBUTES