22#include "libavutil/imgutils.h"
32#define LOC QString("VideoOutputD3D: ")
39 if (Options.
decoders->contains(
"ffmpeg"))
44 if (Options.
decoders->contains(
"dxva2"))
64 QMutexLocker locker(&
m_lock);
80 QMutexLocker locker(&
m_lock);
102 int [[maybe_unused]] reference_frames,
105 QMutexLocker locker(&
m_lock);
109 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
110 QString(
"InputChanged from %1: %2x%3 aspect %4 to %5: %6x%7 aspect %9")
113 .arg(
toString(av_codec_id)).arg(video_dim_disp.width())
114 .arg(video_dim_disp.height()).arg(video_aspect));
118 bool res_changed = video_dim_disp != cursize;
121 if (!res_changed && !cid_changed && !force_change)
134 if (
Init(video_dim_buf, video_dim_disp,
135 video_aspect, disp, av_codec_id))
140 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to re-initialise video output.");
148 QMutexLocker locker(&
m_lock);
160 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
161 "Direct3D device successfully initialized.");
167 QSize video_dim_disp,
175 QMutexLocker locker(&
m_lock);
179 video_aspect, win_rect, codec_id);
181 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Init with codec: %1")
216 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Created %1 empty DXVA2 buffers.")
232 QMutexLocker locker(&
m_lock);
235 for (
int i = 0; i < NUM_DXVA2_BUFS; i++)
237 ok &= vbuffers.CreateBuffer(video_dim.width(),
238 video_dim.height(), i,
242 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Initialised DXVA2 buffers.");
256 LOG(VB_GENERAL, LOG_ERR,
LOC +
257 "RenderFrame() called while IsErrored is true.");
307 LOG(VB_GENERAL, LOG_ERR,
LOC +
308 "Show() called while IsErrored is true.");
322 QMutexLocker locker(&
m_lock);
340 LOG(VB_PLAYBACK, LOG_WARNING,
LOC +
"Failed to update pause frame");
350 bool hardware_conv =
false;
352 uint8_t *buf = img->
GetBuffer(hardware_conv, pitch);
353 if (buf && hardware_conv)
355 copybuffer(buf, frame, pitch);
357 else if (buf && !hardware_conv)
360 av_image_fill_arrays(image_out.data, image_out.linesize,
363 image_out.linesize[0] = pitch;
374 QMutexLocker locker(&
m_lock);
377 LOG(VB_GENERAL, LOG_ERR,
LOC +
378 "ProcessFrame() called while IsErrored is true.");
386 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Wrong frame format");
391 bool pauseframe =
false;
437 !getenv(
"NO_DXVA2")))
445 AVCodecContext **Context,
const AVCodec ** Codec,
446 const QString &decoder,
uint stream_type)
451 if ((decoder ==
"dxva2") && !getenv(
"NO_DXVA2") && !use_cpu)
460 QMutexLocker locker(&
m_lock);
465 video_dim.width(), video_dim.height());
466 return (m_decoder && m_decoder->Init(
m_render));
475 QMutexLocker locker(&
m_lock);
uint8_t * GetBuffer(bool &hardware_conv, uint &pitch)
bool UpdateVertices(const QRect &dvr, const QRect &vr, int alpha=255, bool video=false)
int Copy(AVFrame *To, const MythVideoFrame *From, unsigned char *Buffer, AVPixelFormat Fmt=AV_PIX_FMT_YUV420P)
Initialise AVFrame and copy contents of VideoFrame frame into it, performing any required conversion.
virtual void FreeResources(void)
void CopyFrame(void *surface, D3D9Image *img)
bool Create(QSize size, HWND window)
QRect GetDisplayVideoRect(void) const
bool IsEmbedding(void) const
QSize GetVideoDim(void) const
void MoveResize(void)
performs all the calculations for video framing and any resizing.
QRect GetVideoRect(void) const
QRect GetDisplayVisibleRect(void) const
float GetVideoAspect(void) const
void VideoAspectRatioChanged(float Aspect)
Calls SetVideoAspectRatio(float aspect), then calls MoveResize() to apply changes.
std::chrono::milliseconds m_displayTimecode
Common code shared between GPU accelerated sub-classes (e.g. OpenGL)
MythCodecID m_videoCodecID
VideoErrorState m_errorState
virtual bool Init(QSize VideoDim, QSize VideoDispDim, float VideoAspect, QRect WindowRect, MythCodecID CodecID)
MythVideoProfilePtr m_videoProfile
VideoBuffers m_videoBuffers
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
static uint GetNumBuffers(int PixelFormat, int MaxReferenceFrames=16, bool Decoder=false)
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.
void DiscardFrames(bool NextFrameIsKeyFrame)
Mark all used frames as ready to be reused, this is for seek.
void Init(uint NumDecode, uint NeedFree, uint NeedprebufferNormal, uint NeedPrebufferSmall)
Creates buffers and sets various buffer management parameters.
MythVideoFrame * Head(BufferType Type)
void UpdateFrame(MythVideoFrame *frame, D3D9Image *img)
bool Init(QSize video_dim_buf, QSize video_dim_disp, float video_aspect, QRect win_rect, MythCodecID codec_id) override
static void GetRenderOptions(RenderOptions &Options)
MythRenderD3D9 * m_render
MythVideoFrame m_pauseFrame
static MythCodecID GetSupportedCodec(AVCodecContext **Context, const AVCodec **Codec, const QString &decoder, uint stream_type)
void PrepareFrame(MythVideoFrame *frame, FrameScanType scan) override
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
void DestroyContext(void)
void UpdatePauseFrame(std::chrono::milliseconds &disp_timecode, FrameScanType Scan=kScan_Progressive) override
void RenderEnd() override
VideoOutputD3D(MythMainWindow *MainWindow, MythRenderD3D9 *Render, MythD3D9Painter *Painter, MythDisplay *Display, const MythVideoProfilePtr &VideoProfile, QString &Profile)
bool InputChanged(QSize video_dim_buf, QSize video_dim_disp, float video_aspect, MythCodecID av_codec_id, bool &aspect_only, int reference_frames, bool force_change) override
Tells video output to discard decoded frames and wait for new ones.
void RenderFrame(MythVideoFrame *buffer, FrameScanType) override
static bool codec_is_std(MythCodecID id)
static bool codec_is_dxva2_hw(MythCodecID id)
static bool codec_is_dxva2(MythCodecID id)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythPainter * GetMythPainter(void)
std::shared_ptr< MythVideoProfile > MythVideoProfilePtr
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
def scan(profile, smoonURL, gate)
QMap< QString, QStringList > * safe_renderers
QMap< QString, uint > * priorities
const int kPrebufferFramesSmall
const int kPrebufferFramesNormal
const int kNeedFreeFrames