2#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
3#include <QtSystemDetection>
7#include "libmythbase/mythconfig.h"
30#define LOC QString("VidOutGPU: ")
50 const QSize VideoDispDim,
float VideoAspect,
52 const QString& Codec,
int ReferenceFrames,
55 if (!(MainWindow && Render && Painter && MDisplay))
57 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Fatal error");
63 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Cannot create null video output here");
67 QStringList renderers;
90 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Allowed renderers for %1 %2 (Decoder: %3): '%4'")
94 renderers.join(
",")));
96 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Allowed renderers (filt: %1): %2")
97 .arg(
Decoder, renderers.join(
",")));
101 auto videoprofile = std::make_shared<MythVideoProfile>();
103 if (!renderers.empty())
105 videoprofile->SetInput(VideoDispDim, FrameRate, Codec);
106 QString tmp = videoprofile->GetVideoRenderer();
107 if (videoprofile->IsDecoderCompatible(
Decoder) && renderers.contains(tmp))
110 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Preferred renderer: " + renderer);
114 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"No preferred renderer for decoder '%1' - profile renderer: '%2'")
119 if (renderer.isEmpty())
122 if (renderer.isEmpty())
133 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"No renderer found. This should not happen!.");
134 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Falling back to '%1'").arg(fallback));
138 while (!renderers.empty())
140 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Trying video renderer: '%1'").arg(renderer));
141 int index = renderers.indexOf(renderer);
143 renderers.removeAt(index);
157 if (!video && renderer.contains(
"opengl") && openglrender)
160 openglpainter, MDisplay,
161 videoprofile, renderer);
168 vulkanpainter, MDisplay,
169 videoprofile, renderer);
177 if (video->
Init(VideoDim, VideoDispDim, VideoAspect, MainWindow->
GetUIScreenRect(), CodecID))
189 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Not compiled with any useable video output method.");
220 : m_mainWindow(MainWindow),
223 m_profile(
std::move(Profile))
227 LOG(VB_GENERAL, LOG_ERR,
"Fatal error");
294 if (qFuzzyCompare(
m_videoProfile->GetOutput() + 1.0F, NewRate + 1.0F))
297 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Video frame rate changed: %1->%2")
298 .arg(
static_cast<double>(
m_videoProfile->GetOutput())).arg(
static_cast<double>(NewRate)));
304 float Aspect,
const QRect DisplayVisibleRect,
MythCodecID CodecId)
383 QVector<MythVideoFrame*> release;
389 if (!retain || (frame !=
Frame))
390 release.append(frame);
401 release.append(
Frame);
405 for (
auto * frame : release)
452 bool& AspectOnly,
int ReferenceFrames,
469 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Video changed: %1x%2 (%3x%4) '%5' (Aspect %6 Refs %13)"
470 "-> %7x%8 (%9x%10) '%11' (Aspect %12 Refs %14)")
471 .arg(currentvideodispdim.width()).arg(currentvideodispdim.height())
472 .arg(currentvideodim.width()).arg(currentvideodim.height())
473 .arg(
toString(currentcodec)).arg(
static_cast<double>(currentaspect))
474 .arg(VideoDispDim.width()).arg(VideoDispDim.height())
475 .arg(VideoDim.width()).arg(VideoDim.height())
476 .arg(
toString(CodecId)).arg(
static_cast<double>(VideoAspect))
479 bool cidchanged = (CodecId != currentcodec);
480 bool reschanged = (VideoDispDim != currentvideodispdim);
484 if (!(cidchanged || reschanged || refschanged || ForceChange))
530 const AVCodec* codec = avcodec_find_decoder(avCodecId);
533 codecName = codec->name;
543 if (wasembedding && ok)
582 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Display aspect ratio: %1 (%2)")
583 .arg(displayaspect).arg(source));
591 if (!window.isEmpty() && !screen.isEmpty() && window != screen)
594 double screenaspect = screen.width() /
static_cast<double>(screen.height());
595 double windowaspect = window.width() /
static_cast<double>(window.height());
596 displayaspect = displayaspect * (1.0 / screenaspect) * windowaspect;
597 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Window aspect ratio: %1").arg(displayaspect));
631 bool topfieldfirst =
false;
635 topfieldfirst =
Frame->m_interlacedReverse ? !
Frame->m_topFieldFirst :
Frame->m_topFieldFirst;
636 dummy =
Frame->m_dummy;
691 LOG(VB_PLAYBACK, LOG_WARNING,
LOC +
"Could not update pause frame");
750 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Aspect ratio: %1 (%2)")
751 .arg(aspect).arg(source));
763 fullscreen |= (0 == gui_width && 0 == gui_height);
769 QRect display_visible_rect = QRect(
m_mainWindow->geometry().topLeft(), size);
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()
bool NextModeIsLarger(QSize Size)
Check whether the next mode is larger in size than the current mode.
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)
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.
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
bool m_alreadyDeinterlaced
static bool HardwareFormat(VideoFrameType Type)
virtual void RenderFrame(MythVideoFrame *Frame, bool TopFieldFirst, FrameScanType Scan, StereoscopicMode StereoOverride, bool DrawBorder=false)=0
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()
bool ProcessInputChange()
MythVideoOutputGPU(MythMainWindow *MainWindow, MythRender *Render, MythPainterGPU *Painter, MythDisplay *Display, MythVideoProfilePtr VideoProfile, QString &Profile)
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
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
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.
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
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
virtual bool Init(QSize VideoDim, QSize VideoDispDim, float VideoAspect, QRect WindowRect, MythCodecID CodecID)
MythVideoProfilePtr m_videoProfile
MythDeintType m_forcedDeinterlacer
VideoBuffers m_videoBuffers
MythDeinterlacer m_deinterlacer
const VideoFrameTypes * m_renderFormats
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...
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)
QString get_decoder_name(MythCodecID codec_id)
AVCodecID myth2av_codecid(MythCodecID codec_id)
QString get_encoding_type(MythCodecID codecid)
static bool codec_is_vdpau(MythCodecID id)
static bool codec_is_mediacodec(MythCodecID id)
static bool codec_is_drmprime(MythCodecID id)
static bool codec_is_mmal(MythCodecID id)
static bool codec_is_nvdec(MythCodecID id)
static bool codec_is_vtb(MythCodecID id)
static bool codec_is_v4l2(MythCodecID id)
static bool codec_is_copyback(MythCodecID id)
static bool codec_is_vaapi(MythCodecID id)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
std::vector< VideoFrameType > VideoFrameTypes
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
std::shared_ptr< MythVideoProfile > MythVideoProfilePtr
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
bool is_interlaced(FrameScanType Scan)
#define ALL_PICTURE_ATTRIBUTES