MythTV  master
videoout_d3d.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 #include <map>
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7 
8 #include "mythcontext.h"
9 #include "videoout_d3d.h"
10 #include "osd.h"
11 #include "fourcc.h"
12 #include "videodisplayprofile.h"
13 #include "mythmainwindow.h"
14 #include "mythplayer.h"
15 #include "mythavutil.h"
16 
17 #include "mmsystem.h"
18 #include "tv.h"
19 
20 extern "C" {
21 #include "libavutil/imgutils.h"
22 }
23 
24 #undef UNICODE
25 
26 const int kNumBuffers = 31;
27 const int kNeedFreeFrames = 1;
28 const int kPrebufferFramesNormal = 10;
29 const int kPrebufferFramesSmall = 4;
30 
31 #define LOC QString("VideoOutputD3D: ")
32 
34 {
35  Options.renderers->append("direct3d");
36  (*Options.safe_renderers)["dummy"].append("direct3d");
37  (*Options.safe_renderers)["nuppel"].append("direct3d");
38  if (Options.decoders->contains("ffmpeg"))
39  (*Options.safe_renderers)["ffmpeg"].append("direct3d");
40  Options.priorities->insert("direct3d", 70);
41 
42 #ifdef USING_DXVA2
43  if (opts.decoders->contains("dxva2"))
44  (*opts.safe_renderers)["dxva2"].append("direct3d");
45 #endif
46 }
47 
49  : MythVideoOutput(),
50 {
51  m_pauseFrame.buf = nullptr;
52 }
53 
55 {
56  TearDown();
57 }
58 
60 {
61  QMutexLocker locker(&m_lock);
65  if (m_pauseFrame.buf)
66  {
67  delete [] m_pauseFrame.buf;
68  m_pauseFrame.buf = nullptr;
69  }
70 
71  if (m_osdPainter)
72  {
73  // Hack to ensure that the osd painter is not
74  // deleted while image load thread is still busy
75  // loading images with that painter
77  if (invalid_osd_painter)
78  delete invalid_osd_painter;
79  invalid_osd_painter = m_osdPainter;
80  m_osdPainter = nullptr;
81  }
82 
83  DeleteDecoder();
85 }
86 
88 {
89  QMutexLocker locker(&m_lock);
90  m_renderValid = false;
91  m_renderReset = false;
92 
93  while (!m_pips.empty())
94  {
95  delete *m_pips.begin();
96  m_pips.erase(m_pips.begin());
97  }
98  m_pipReady.clear();
99 
100  if (m_video)
101  {
102  delete m_video;
103  m_video = nullptr;
104  }
105 
106  if (m_render)
107  {
108  m_render->DecrRef();
109  m_render = nullptr;
110  }
111 }
112 
113 void VideoOutputD3D::WindowResized(const QSize &new_size)
114 {
115  // FIXME this now requires the context to be re-created
116  /*
117  QMutexLocker locker(&m_lock);
118  window.SetDisplayVisibleRect(QRect(QPoint(0, 0), new_size));
119  window.SetDisplayAspect(
120  ((float)new_size.width()) / new_size.height());
121 
122  MoveResize();
123  */
124 }
125 
126 bool VideoOutputD3D::InputChanged(const QSize &video_dim_buf,
127  const QSize &video_dim_disp,
128  float aspect,
129  MythCodecID av_codec_id,
130  bool &aspect_only,
132 {
133  QMutexLocker locker(&m_lock);
134 
135  QSize cursize = m_window.GetVideoDim();
136 
137  LOG(VB_PLAYBACK, LOG_INFO, LOC +
138  QString("InputChanged from %1: %2x%3 aspect %4 to %5: %6x%7 aspect %9")
139  .arg(toString(m_videoCodecID)).arg(cursize.width())
140  .arg(cursize.height()).arg(m_window.GetVideoAspect())
141  .arg(toString(av_codec_id)).arg(video_dim_disp.width())
142  .arg(video_dim_disp.height()).arg(aspect));
143 
144 
145  bool cid_changed = (m_videoCodecID != av_codec_id);
146  bool res_changed = video_dim_disp != cursize;
147  bool asp_changed = aspect != m_window.GetVideoAspect();
148 
149  if (!res_changed && !cid_changed)
150  {
151  if (asp_changed)
152  {
153  aspect_only = true;
154  VideoAspectRatioChanged(aspect);
155  MoveResize();
156  }
157  return true;
158  }
159 
160  TearDown();
161  QRect disp = m_window.GetDisplayVisibleRect();
162  if (Init(video_dim_buf, video_dim_disp,
163  aspect, (WId)m_hWnd, disp, av_codec_id))
164  {
165  return true;
166  }
167 
168  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to re-initialise video output.");
170 
171  return false;
172 }
173 
175 {
176  QMutexLocker locker(&m_lock);
177  DestroyContext();
178  QSize size = m_window.GetVideoDim();
179  m_render = new MythRenderD3D9();
181  m_hWnd)))
182  return false;
183 
184  m_video = new D3D9Image(m_render, size, true);
185  if (!(m_video && m_video->IsValid()))
186  return false;
187 
188  LOG(VB_PLAYBACK, LOG_INFO, LOC +
189  "Direct3D device successfully initialized.");
190  m_renderValid = true;
191  return true;
192 }
193 
194 bool VideoOutputD3D::Init(const QSize &video_dim_buf,
195  const QSize &video_dim_disp,
196  float aspect, WId winid,
197  const QRect &win_rect,MythCodecID codec_id)
198 {
199  MythPainter *painter = GetMythPainter();
200  if (painter)
201  painter->FreeResources();
202 
203  QMutexLocker locker(&m_lock);
204  m_hWnd = (HWND)winid;
205 
206  MythVideoOutput::Init(video_dim_buf, video_dim_disp,
207  aspect, winid, win_rect, codec_id);
208 
209  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Init with codec: %1")
210  .arg(toString(codec_id)));
211  SetProfile();
212 
213  bool success = true;
214  success &= SetupContext();
215  InitDisplayMeasurements(video_dim_disp.width(), video_dim_disp.height(),
216  false);
217 
219  {
220  if (!CreateDecoder())
221  return false;
222  }
223 
224  success &= CreateBuffers();
225  success &= InitBuffers();
226  success &= CreatePauseFrame();
227 
228  MoveResize();
229 
230  if (!success)
231  TearDown();
232  else
233  {
235  if (m_osdPainter)
236  {
238  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Created D3D9 osd painter.");
239  }
240  else
241  LOG(VB_GENERAL, LOG_ERR, LOC +
242  "Failed to create D3D9 osd painter.");
243  }
244  return success;
245 }
246 
248 {
249  if (m_dbDisplayProfile)
251 }
252 
254 {
256  {
258  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created %1 empty DXVA2 buffers.")
260  return true;
261  }
262 
265  return true;
266 
267 }
268 
270 {
271 #ifdef USING_DXVA2
272  if ((codec_is_dxva2(video_codec_id)) && m_decoder)
273  {
274  QMutexLocker locker(&m_lock);
275  const QSize video_dim = window.GetVideoDim();
276  bool ok = true;
277  for (int i = 0; i < NUM_DXVA2_BUFS; i++)
278  {
279  ok &= vbuffers.CreateBuffer(video_dim.width(),
280  video_dim.height(), i,
282  }
283  if (ok)
284  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Initialised DXVA2 buffers.");
285  return ok;
286  }
287 #endif
289  m_window.GetVideoDim().width(),
290  m_window.GetVideoDim().height());
291 }
292 
294 {
296  return true;
297 
299  new unsigned char[m_videoBuffers.GetScratchFrame()->size + 128],
303 
305  return true;
306 }
307 
309  OSD *osd)
310 {
311  (void)osd;
312  if (IsErrored())
313  {
314  LOG(VB_GENERAL, LOG_ERR, LOC +
315  "PrepareFrame() called while IsErrored is true.");
316  return;
317  }
318 
319  if (!buffer && codec_is_std(m_videoCodecID))
320  buffer = m_videoBuffers.GetScratchFrame();
321 
322  bool dummy = false;
323  if (buffer)
324  {
325  dummy = buffer->dummy;
326  m_framesPlayed = buffer->frameNumber + 1;
327  }
328 
329  if (!m_render || !m_video)
330  return;
331 
333  if (m_renderValid)
334  {
337  bool ok = m_render->ClearBuffer();
338  if (ok && !dummy)
340  255, true);
341 
342  if (ok)
343  {
344  ok = m_render->Begin();
345  if (ok)
346  {
347  if (!dummy)
348  m_video->Draw();
349  QMap<MythPlayer*,D3D9Image*>::iterator it = m_pips.begin();
350  for (; it != m_pips.end(); ++it)
351  {
352  if (m_pipReady[it.key()])
353  {
354  if (m_pipActive == *it)
355  {
356  QRect rect = (*it)->GetRect();
357  if (!rect.isNull())
358  {
359  rect.adjust(-10, -10, 10, 10);
360  m_render->DrawRect(rect, QColor(128,0,0,255), 255);
361  }
362  }
363  (*it)->Draw();
364  }
365  }
366 
367  if (m_visual)
369 
370  if (osd && m_osdPainter && !m_window.IsEmbedding())
371  osd->Draw(m_osdPainter, GetTotalOSDBounds().size(),
372  true);
373  m_render->End();
374  }
375  }
376 
377  }
378 }
379 
381 {
382  if (IsErrored())
383  {
384  LOG(VB_GENERAL, LOG_ERR, LOC +
385  "Show() called while IsErrored is true.");
386  return;
387  }
388 
389  if (!m_render)
390  return;
391 
393  if (m_renderValid)
395 }
396 
397 void VideoOutputD3D::EmbedInWidget(const QRect &rect)
398 {
399  if (m_window.IsEmbedding())
400  return;
401 
403  // TODO: Initialise m_hEmbedWnd?
404 }
405 
407 {
408  if (!m_window.IsEmbedding())
409  return;
410 
412 }
413 
414 void VideoOutputD3D::UpdatePauseFrame(int64_t &disp_timecode)
415 {
416  QMutexLocker locker(&m_lock);
418 
420  {
421  if (!used_frame)
422  used_frame = m_videoBuffers.GetScratchFrame();
423  CopyFrame(&m_pauseFrame, used_frame);
424  disp_timecode = m_pauseFrame.disp_timecode;
425  }
426  else if (codec_is_dxva2(m_videoCodecID))
427  {
428  if (used_frame)
429  {
430  m_pauseSurface = used_frame->buf;
431  disp_timecode = used_frame->disp_timecode;
432  }
433  else
434  LOG(VB_PLAYBACK, LOG_WARNING, LOC + "Failed to update pause frame");
435  }
436 }
437 
439 {
441  return;
442 
443  // TODO - add a size check
444  bool hardware_conv = false;
445  uint pitch = 0;
446  uint8_t *buf = img->GetBuffer(hardware_conv, pitch);
447  if (buf && hardware_conv)
448  {
449  copybuffer(buf, frame, pitch);
450  }
451  else if (buf && !hardware_conv)
452  {
453  AVFrame image_out;
454  av_image_fill_arrays(image_out.data, image_out.linesize,
455  (uint8_t*)buf,
456  AV_PIX_FMT_RGB32, frame->width, frame->height, IMAGE_ALIGN);
457  image_out.linesize[0] = pitch;
458  m_copyFrame.Copy(&image_out, frame,(uint8_t*)buf, AV_PIX_FMT_RGB32);
459  }
460  img->ReleaseBuffer();
461 }
462 
464  const PIPMap &pipPlayers,
466 {
467  if (!m_render || !m_video)
468  return;
469 
470  QMutexLocker locker(&m_lock);
471  if (IsErrored())
472  {
473  LOG(VB_GENERAL, LOG_ERR, LOC +
474  "ProcessFrame() called while IsErrored is true.");
475  return;
476  }
477 
478  bool gpu = codec_is_dxva2(m_videoCodecID);
479 
480  if (gpu && frame && frame->codec != FMT_DXVA2)
481  {
482  LOG(VB_GENERAL, LOG_ERR, LOC + "Wrong frame format");
483  return;
484  }
485 
486  bool dummy = false;
487  bool pauseframe = false;
488  if (!frame)
489  {
490  if (!gpu)
491  {
494  }
495  pauseframe = true;
496  }
497 
498  if (frame)
499  dummy = frame->dummy;
500 
501  bool safepauseframe = pauseframe && !gpu;
502 
503  if (!m_window.IsEmbedding())
504  ShowPIPs(frame, pipPlayers);
505 
506  // Test the device
508  if (m_renderReset)
509  SetupContext();
510 
511  // Update a software decoded frame
512  if (m_renderValid && !gpu && !dummy)
513  UpdateFrame(frame, m_video);
514 
515  // Update a GPU decoded frame
516  if (m_renderValid && gpu && !dummy)
517  {
519  if (m_renderReset)
520  CreateDecoder();
521 
522  if (m_renderValid && frame)
523  {
524  m_render->CopyFrame(frame->buf, m_video);
525  }
526  else if (m_renderValid && pauseframe)
527  {
529  }
530  }
531 }
532 
534  MythPlayer *pipplayer,
535  PIPLocation loc)
536 {
537  if (!pipplayer)
538  return;
539 
540  int pipw, piph;
541  VideoFrame *pipimage = pipplayer->GetCurrentFrame(pipw, piph);
542  const float pipVideoAspect = pipplayer->GetVideoAspect();
543  const QSize pipVideoDim = pipplayer->GetVideoBufferSize();
544  const bool pipActive = pipplayer->IsPIPActive();
545  const bool pipVisible = pipplayer->IsPIPVisible();
546  const uint pipVideoWidth = pipVideoDim.width();
547  const uint pipVideoHeight = pipVideoDim.height();
548 
549  if ((pipVideoAspect <= 0) || !pipimage ||
550  !pipimage->buf || (pipimage->codec != FMT_YV12) || !pipVisible)
551  {
552  pipplayer->ReleaseCurrentFrame(pipimage);
553  return;
554  }
555 
556  QRect position = GetPIPRect(loc, pipplayer);
557 
558  m_pipReady[pipplayer] = false;
559  D3D9Image *m_pip = m_pips[pipplayer];
560  if (!m_pip)
561  {
562  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Initialise PiP.");
563  m_pip = new D3D9Image(m_render, QSize(pipVideoWidth, pipVideoHeight),
564  true);
565  m_pips[pipplayer] = m_pip;
566  if (!m_pip->IsValid())
567  {
568  pipplayer->ReleaseCurrentFrame(pipimage);
569  return;
570  }
571  }
572 
573  QSize current = m_pip->GetSize();
574  if ((uint)current.width() != pipVideoWidth ||
575  (uint)current.height() != pipVideoHeight)
576  {
577  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Re-initialise PiP.");
578  delete m_pip;
579  m_pip = new D3D9Image(m_render, QSize(pipVideoWidth, pipVideoHeight),
580  true);
581  m_pips[pipplayer] = m_pip;
582  if (!m_pip->IsValid())
583  {
584  pipplayer->ReleaseCurrentFrame(pipimage);
585  return;
586  }
587  }
588  m_pip->UpdateVertices(position, QRect(0, 0, pipVideoWidth, pipVideoHeight),
589  255, true);
590  UpdateFrame(pipimage, m_pip);
591  m_pipReady[pipplayer] = true;
592  if (pipActive)
593  m_pipActive = m_pip;
594 
595  pipplayer->ReleaseCurrentFrame(pipimage);
596 }
597 
599 {
600  if (!m_pips.contains(pipplayer))
601  return;
602 
603  QMutexLocker locker(&m_lock);
604 
605  D3D9Image *m_pip = m_pips[pipplayer];
606  if (m_pip)
607  delete m_pip;
608  m_pipReady.remove(pipplayer);
609  m_pips.remove(pipplayer);
610 }
611 
613  MythCodecID myth_codec_id, const QSize &video_dim)
614 {
615  QStringList list;
616  if (codec_is_std(myth_codec_id) || (codec_is_dxva2_hw(myth_codec_id) &&
617  !getenv("NO_DXVA2")))
618  {
619  list += "direct3d";
620  }
621  return list;
622 }
623 
625 {
626  return m_osdPainter;
627 }
628 
630  uint width, uint height, const QString &decoder,
631  uint stream_type, bool no_acceleration,
632  AVPixelFormat &pix_fmt)
633 {
634 #ifdef USING_DXVA2
635  QSize size(width, height);
636  bool use_cpu = no_acceleration;
637  MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_DXVA2 + (stream_type - 1));
638  use_cpu |= !codec_is_dxva2_hw(test_cid);
639  pix_fmt = AV_PIX_FMT_DXVA2_VLD;
640  if ((decoder == "dxva2") && !getenv("NO_DXVA2") && !use_cpu)
641  return test_cid;
642 #endif
643  return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1));
644 }
645 
647 {
648 #ifdef USING_DXVA2
649  QMutexLocker locker(&m_lock);
650  if (m_decoder)
651  DeleteDecoder();
652  QSize video_dim = window.GetVideoDim();
653  m_decoder = new DXVA2Decoder(NUM_DXVA2_BUFS, video_codec_id,
654  video_dim.width(), video_dim.height());
655  return (m_decoder && m_decoder->Init(m_render));
656 #else
657  return false;
658 #endif
659 }
660 
662 {
663 #ifdef USING_DXVA2
664  QMutexLocker locker(&m_lock);
665  delete m_decoder;
666  m_decoder = nullptr;
667 #endif
668 }
669 
670 /* vim: set expandtab tabstop=4 shiftwidth=4: */
virtual void VideoAspectRatioChanged(float VideoAspect)
bool ClearBuffer(void)
void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd) override
void Reset(void)
Resets the class so that Init may be called again.
QMap< MythPlayer *, PIPLocation > PIPMap
Definition: mythvideoout.h:32
bool CreateDecoder(void)
MythD3D9Painter * m_osdPainter
Definition: videoout_d3d.h:87
float GetVideoAspect(void) const
Definition: mythplayer.h:189
def scan(profile, smoonURL, gate)
Definition: scan.py:46
MythCodecID m_videoCodecID
Definition: mythvideoout.h:167
static void copybuffer(VideoFrame *dst, uint8_t *buffer, int pitch, VideoFrameType type=FMT_YV12)
Definition: mythframe.h:698
static void GetRenderOptions(RenderOptions &Options)
virtual void MoveResize(void)
QRect GetITVDisplayRect(void) const
void WindowResized(const QSize &new_size) override
unsigned char * buf
Definition: mythframe.h:139
MythPainter * GetOSDPainter(void) override
int Copy(VideoFrame *dst, const VideoFrame *src)
Definition: mythavutil.cpp:331
QString toString(MarkTypes type)
QRect GetTotalOSDBounds(void) const
MythCodecID
Definition: mythcodecid.h:10
VideoDisplayProfile * m_dbDisplayProfile
Definition: mythvideoout.h:169
VideoVisual * m_visual
Definition: mythvideoout.h:175
MythRenderD3D9 * m_render
Definition: videoout_d3d.h:78
VideoFrameType codec
Definition: mythframe.h:138
bool InitBuffers(void)
QRect GetVideoRect(void) const
struct AVFrame AVFrame
void SetProfile(void)
void * GetSurface(uint num)
MythPainter * GetMythPainter(void)
VideoFrame * GetCurrentFrame(int &w, int &h)
Definition: mythplayer.cpp:998
bool IsValid(void) const
FrameScanType
Definition: videoouttypes.h:80
bool CreatePauseFrame(void)
#define codec_is_dxva2_hw(id)
Definition: mythcodecid.h:301
bool Init(MythRenderD3D9 *render)
bool CreateBuffers(void)
#define LOC
bool Present(HWND win)
MythAVCopy m_copyFrame
Definition: mythvideoout.h:177
void TearDown(void)
void Init(uint NumDecode, bool ExtraForPause, uint NeedFree, uint NeedprebufferNormal, uint NeedPrebufferSmall)
Creates buffers and sets various buffer management parameters.
VideoFrame m_pauseFrame
Definition: videoout_d3d.h:74
bool Init(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, WId winid, const QRect &win_rect, MythCodecID codec_id) override
bool GetITVResizing(void) const
static MythCodecID GetBestSupportedCodec(uint width, uint height, const QString &decoder, uint stream_type, bool no_acceleration, AVPixelFormat &pix_fmt)
bool Create(QSize size, HWND window)
QMap< QString, QStringList > * safe_renderers
virtual bool Init(const QSize &VideoDim, const QSize &VideoDispDim, float VideoAspect, MythDisplay *Display, const QRect &WindowRect, MythCodecID CodecID)
void DrawRect(const QRect &rect, const QColor &color, int alpha)
void SetSwapControl(bool swap)
virtual void FreeResources(void)
Definition: mythpainter.h:49
#define codec_is_dxva2(id)
Definition: mythcodecid.h:299
void Show(FrameScanType) override
VideoOutWindow m_window
Definition: mythvideoout.h:161
QStringList * renderers
VideoErrorState m_errorState
Definition: mythvideoout.h:171
void ReleaseCurrentFrame(VideoFrame *frame)
VideoBuffers m_videoBuffers
Definition: mythvideoout.h:170
virtual void EmbedInWidget(const QRect &EmbedRect)
Tells video output to embed video in an existing window.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
const int kPrebufferFramesNormal
bool IsErrored() const
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual void StopEmbedding(void)
bool IsEmbedding(void) const
const int kNeedFreeFrames
unsigned int uint
Definition: compat.h:140
bool SetupContext(void)
bool UpdateVertices(const QRect &dvr, const QRect &vr, int alpha=255, bool video=false)
bool CreateBuffers(VideoFrameType Type, QSize Size, bool ExtraForPause, uint NeedFree, uint NeedprebufferNormal, uint NeedPrebufferSmall, int MaxReferenceFrames=16)
QRect GetDisplayVideoRect(void) const
bool Draw(void)
bool Draw(MythPainter *Painter, QSize Size, bool Repaint=false)
Definition: osd.cpp:636
D3D9Image * m_pipActive
Definition: videoout_d3d.h:85
DXVA2Decoder * m_decoder
Definition: videoout_d3d.h:92
void * m_pauseSurface
Definition: videoout_d3d.h:94
QMap< MythPlayer *, bool > m_pipReady
Definition: videoout_d3d.h:84
static void init(VideoFrame *vf, VideoFrameType _codec, unsigned char *_buf, int _width, int _height, int _size, const int *p=nullptr, const int *o=nullptr, float _aspect=-1.0F, double _rate=-1.0F, int _aligned=MYTH_WIDTH_ALIGNMENT)
Definition: mythframe.h:230
const int kPrebufferFramesSmall
long long frameNumber
Definition: mythframe.h:147
const int kNumBuffers
QStringList * decoders
long long m_framesPlayed
Definition: mythvideoout.h:172
PIPLocation
Definition: videoouttypes.h:19
int64_t disp_timecode
Definition: mythframe.h:150
VideoFrame * GetScratchFrame(void)
bool Test(bool &reset)
void ShowPIP(VideoFrame *frame, MythPlayer *pipplayer, PIPLocation loc) override
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
QSize GetVideoBufferSize(void) const
Definition: mythplayer.h:187
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
virtual void ShowPIPs(VideoFrame *Frame, const PIPMap &PiPPlayers)
static uint GetNumBuffers(int PixelFormat, int MaxReferenceFrames=16, bool Decoder=false)
QSize GetSize(void) const
void DestroyContext(void)
virtual QRect GetPIPRect(PIPLocation Location, MythPlayer *PiPPlayer=nullptr, bool DoPixelAdj=true) const
returns QRect of PIP based on PIPLocation
void DeleteDecoder(void)
int height
Definition: mythframe.h:142
void UpdateFrame(VideoFrame *frame, D3D9Image *img)
D3D9Image * m_video
Definition: videoout_d3d.h:79
void ProcessFrame(VideoFrame *frame, OSD *osd, const PIPMap &pipPlayers, FrameScanType scan) override
void UpdatePauseFrame(int64_t &disp_timecode) override
Definition: osd.h:131
float GetVideoAspect(void) const
void DiscardFrames(bool NextFrameIsKeyFrame)
Mark all used frames as ready to be reused, this is for seek.
virtual void Draw(const QRect &area, MythPainter *painter, QPaintDevice *device)=0
void Teardown(void) override
void ReleaseBuffer(void)
QRect GetDisplayVisibleRect(void) const
QMap< QString, uint > * priorities
void RemovePIP(MythPlayer *pipplayer) override
QSize GetVideoDim(void) const
void StopEmbedding(void) override
bool IsPIPVisible(void) const
Definition: mythplayer.h:238
QMap< MythPlayer *, D3D9Image * > m_pips
Definition: videoout_d3d.h:83
VideoFrame * Head(BufferType Type)
uint8_t * GetBuffer(bool &hardware_conv, uint &pitch)
void EmbedInWidget(const QRect &rect) override
Tells video output to embed video in an existing window.
bool InputChanged(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, MythCodecID av_codec_id, bool &aspect_only, MythMultiLocker *Locks) override
void DeleteBuffers(void)
void SetVideoRenderer(const QString &VideoRenderer)
void InitDisplayMeasurements(void)
Init display measurements based on database settings and actual screen parameters.
#define codec_is_std(id)
Definition: mythcodecid.h:276
static void CopyFrame(VideoFrame *To, const VideoFrame *From)
bool IsPIPActive(void) const
Definition: mythplayer.h:237
void CopyFrame(void *surface, D3D9Image *img)