20 #include "libavutil/imgutils.h"
30 #define LOC QString("VideoOutputD3D: ")
37 if (Options.
decoders->contains(
"ffmpeg"))
42 if (
opts.decoders->contains(
"dxva2"))
43 (*
opts.safe_renderers)[
"dxva2"].append(
"direct3d");
60 QMutexLocker locker(&
m_lock);
76 if (invalid_osd_painter)
77 delete invalid_osd_painter;
88 QMutexLocker locker(&
m_lock);
126 const QSize &video_dim_disp,
132 QMutexLocker locker(&
m_lock);
134 QSize cursize = m_window.GetVideoDim();
136 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
137 QString(
"InputChanged from %1: %2x%3 aspect %4 to %5: %6x%7 aspect %9")
139 .arg(cursize.height()).arg(m_window.GetVideoAspect())
140 .arg(
toString(av_codec_id)).arg(video_dim_disp.width())
141 .arg(video_dim_disp.height()).arg(video_aspect));
145 bool res_changed = video_dim_disp != cursize;
146 bool asp_changed = video_aspect != m_window.GetVideoAspect();
148 if (!res_changed && !cid_changed)
160 QRect disp = m_window.GetDisplayVisibleRect();
161 if (
Init(video_dim_buf, video_dim_disp,
162 video_aspect, (WId)
m_hWnd, disp, av_codec_id))
167 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to re-initialise video output.");
175 QMutexLocker locker(&
m_lock);
177 QSize size = m_window.GetVideoDim();
187 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
188 "Direct3D device successfully initialized.");
194 const QSize &video_dim_disp,
195 float video_aspect, WId winid,
202 QMutexLocker locker(&
m_lock);
206 video_aspect, winid, win_rect, codec_id);
208 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Init with codec: %1")
214 InitDisplayMeasurements(video_dim_disp.width(), video_dim_disp.height(),
237 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Created D3D9 osd painter.");
240 LOG(VB_GENERAL, LOG_ERR,
LOC +
241 "Failed to create D3D9 osd painter.");
257 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Created %1 empty DXVA2 buffers.")
273 QMutexLocker locker(&
m_lock);
274 const QSize video_dim = window.GetVideoDim();
276 for (
int i = 0; i < NUM_DXVA2_BUFS; i++)
278 ok &= vbuffers.CreateBuffer(video_dim.width(),
279 video_dim.height(), i,
283 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Initialised DXVA2 buffers.");
288 m_window.GetVideoDim().width(),
289 m_window.GetVideoDim().height());
298 new unsigned char[
m_videoBuffers.GetScratchFrame()->m_bufferSize + 128],
312 LOG(VB_GENERAL, LOG_ERR,
LOC +
313 "RenderFrame() called while IsErrored is true.");
333 QRect dvr = m_window.GetITVResizing() ? m_window.GetITVDisplayRect() :
334 m_window.GetDisplayVideoRect();
347 QMap<MythPlayer*,D3D9Image*>::iterator it =
m_pips.begin();
348 for (; it !=
m_pips.end(); ++it)
354 QRect rect = (*it)->GetRect();
357 rect.adjust(-10, -10, 10, 10);
366 m_visual->Draw(GetTotalOSDBounds(),
m_osdPainter,
nullptr);
382 LOG(VB_GENERAL, LOG_ERR,
LOC +
383 "Show() called while IsErrored is true.");
397 if (m_window.IsEmbedding())
400 MythVideoOutput::EmbedInWidget(rect);
406 if (!m_window.IsEmbedding())
409 MythVideoOutput::StopEmbedding();
414 QMutexLocker locker(&
m_lock);
432 LOG(VB_PLAYBACK, LOG_WARNING,
LOC +
"Failed to update pause frame");
442 bool hardware_conv =
false;
444 uint8_t *buf = img->
GetBuffer(hardware_conv, pitch);
445 if (buf && hardware_conv)
447 copybuffer(buf, frame, pitch);
449 else if (buf && !hardware_conv)
452 av_image_fill_arrays(image_out.data, image_out.linesize,
455 image_out.linesize[0] = pitch;
467 QMutexLocker locker(&
m_lock);
470 LOG(VB_GENERAL, LOG_ERR,
LOC +
471 "ProcessFrame() called while IsErrored is true.");
479 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Wrong frame format");
484 bool pauseframe =
false;
498 if (!m_window.IsEmbedding())
499 ShowPIPs(pipPlayers);
534 MythVideoFrame *pipimage = pipplayer->GetCurrentFrame(pipw, piph);
537 const bool pipActive = pipplayer->IsPIPActive();
538 const bool pipVisible = pipplayer->IsPIPVisible();
539 const uint pipVideoWidth = pipVideoDim.width();
540 const uint pipVideoHeight = pipVideoDim.height();
542 if ((pipVideoAspect <= 0) || !pipimage ||
545 pipplayer->ReleaseCurrentFrame(pipimage);
549 QRect position = GetPIPRect(loc, pipplayer);
555 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Initialise PiP.");
558 m_pips[pipplayer] = m_pip;
561 pipplayer->ReleaseCurrentFrame(pipimage);
570 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Re-initialise PiP.");
574 m_pips[pipplayer] = m_pip;
577 pipplayer->ReleaseCurrentFrame(pipimage);
581 m_pip->
UpdateVertices(position, QRect(0, 0, pipVideoWidth, pipVideoHeight),
588 pipplayer->ReleaseCurrentFrame(pipimage);
593 if (!
m_pips.contains(pipplayer))
596 QMutexLocker locker(&
m_lock);
610 !getenv(
"NO_DXVA2")))
623 uint width,
uint height,
const QString &decoder,
624 uint stream_type,
bool no_acceleration,
625 AVPixelFormat &pix_fmt)
628 QSize size(width, height);
629 bool use_cpu = no_acceleration;
632 pix_fmt = AV_PIX_FMT_DXVA2_VLD;
633 if ((decoder ==
"dxva2") && !getenv(
"NO_DXVA2") && !use_cpu)
642 QMutexLocker locker(&
m_lock);
645 QSize video_dim = window.GetVideoDim();
647 video_dim.width(), video_dim.height());
657 QMutexLocker locker(&
m_lock);