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 "filtermanager.h"
12 #include "fourcc.h"
13 #include "videodisplayprofile.h"
14 #include "mythmainwindow.h"
15 #include "mythplayer.h"
16 #include "mythavutil.h"
17 
18 #include "mmsystem.h"
19 #include "tv.h"
20 
21 extern "C" {
22 #include "libavutil/imgutils.h"
23 }
24 
25 #undef UNICODE
26 
27 const int kNumBuffers = 31;
28 const int kNeedFreeFrames = 1;
29 const int kPrebufferFramesNormal = 10;
30 const int kPrebufferFramesSmall = 4;
31 const int kKeepPrebuffer = 2;
32 
33 #define NUM_DXVA2_BUFS 30
34 
35 #define LOC QString("VideoOutputD3D: ")
36 
38  QStringList &cpudeints)
39 {
40  opts.renderers->append("direct3d");
41  opts.deints->insert("direct3d", cpudeints);
42  (*opts.osds)["direct3d"].append("direct3d");
43  (*opts.safe_renderers)["dummy"].append("direct3d");
44  (*opts.safe_renderers)["nuppel"].append("direct3d");
45  if (opts.decoders->contains("ffmpeg"))
46  (*opts.safe_renderers)["ffmpeg"].append("direct3d");
47  if (opts.decoders->contains("crystalhd"))
48  (*opts.safe_renderers)["crystalhd"].append("direct3d");
49  opts.priorities->insert("direct3d", 70);
50 
51 #ifdef USING_DXVA2
52  if (opts.decoders->contains("dxva2"))
53  (*opts.safe_renderers)["dxva2"].append("direct3d");
54 #endif
55 }
56 
58  : VideoOutput(), m_lock(QMutex::Recursive),
59  m_hWnd(nullptr), m_render(nullptr),
60  m_video(nullptr),
61  m_render_valid(false), m_render_reset(false), m_pip_active(nullptr),
62  m_osd_painter(nullptr)
63 {
64  m_pauseFrame.buf = nullptr;
65 #ifdef USING_DXVA2
66  m_decoder = nullptr;
67 #endif
68  m_pause_surface = nullptr;
69 }
70 
72 {
73  TearDown();
74 }
75 
77 {
78  QMutexLocker locker(&m_lock);
79  vbuffers.DiscardFrames(true);
80  vbuffers.Reset();
82  if (m_pauseFrame.buf)
83  {
84  delete [] m_pauseFrame.buf;
85  m_pauseFrame.buf = nullptr;
86  }
87 
88  if (m_osd_painter)
89  {
90  // Hack to ensure that the osd painter is not
91  // deleted while image load thread is still busy
92  // loading images with that painter
95  delete invalid_osd_painter;
97  m_osd_painter = nullptr;
98  }
99 
100  DeleteDecoder();
101  DestroyContext();
102 }
103 
105 {
106  QMutexLocker locker(&m_lock);
107  m_render_valid = false;
108  m_render_reset = false;
109 
110  while (!m_pips.empty())
111  {
112  delete *m_pips.begin();
113  m_pips.erase(m_pips.begin());
114  }
115  m_pip_ready.clear();
116 
117  if (m_video)
118  {
119  delete m_video;
120  m_video = nullptr;
121  }
122 
123  if (m_render)
124  {
125  m_render->DecrRef();
126  m_render = nullptr;
127  }
128 }
129 
130 void VideoOutputD3D::WindowResized(const QSize &new_size)
131 {
132  // FIXME this now requires the context to be re-created
133  /*
134  QMutexLocker locker(&m_lock);
135  window.SetDisplayVisibleRect(QRect(QPoint(0, 0), new_size));
136  window.SetDisplayAspect(
137  ((float)new_size.width()) / new_size.height());
138 
139  MoveResize();
140  */
141 }
142 
143 bool VideoOutputD3D::InputChanged(const QSize &video_dim_buf,
144  const QSize &video_dim_disp,
145  float aspect,
146  MythCodecID av_codec_id,
147  void *codec_private,
148  bool &aspect_only)
149 {
150  QMutexLocker locker(&m_lock);
151 
152  QSize cursize = window.GetActualVideoDim();
153 
154  LOG(VB_PLAYBACK, LOG_INFO, LOC +
155  QString("InputChanged from %1: %2x%3 aspect %4 to %5: %6x%7 aspect %9")
156  .arg(toString(video_codec_id)).arg(cursize.width())
157  .arg(cursize.height()).arg(window.GetVideoAspect())
158  .arg(toString(av_codec_id)).arg(video_dim_disp.width())
159  .arg(video_dim_disp.height()).arg(aspect));
160 
161 
162  bool cid_changed = (video_codec_id != av_codec_id);
163  bool res_changed = video_dim_disp != cursize;
164  bool asp_changed = aspect != window.GetVideoAspect();
165 
166  if (!res_changed && !cid_changed)
167  {
168  if (asp_changed)
169  {
170  aspect_only = true;
171  VideoAspectRatioChanged(aspect);
172  MoveResize();
173  }
174  return true;
175  }
176 
177  TearDown();
178  QRect disp = window.GetDisplayVisibleRect();
179  if (Init(video_dim_buf, video_dim_disp,
180  aspect, (WId)m_hWnd, disp, av_codec_id))
181  {
182  BestDeint();
183  return true;
184  }
185 
186  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to re-initialise video output.");
188 
189  return false;
190 }
191 
193 {
194  QMutexLocker locker(&m_lock);
195  DestroyContext();
196  QSize size = window.GetVideoDim();
197  m_render = new MythRenderD3D9();
199  m_hWnd)))
200  return false;
201 
202  m_video = new D3D9Image(m_render, size, true);
203  if (!(m_video && m_video->IsValid()))
204  return false;
205 
206  LOG(VB_PLAYBACK, LOG_INFO, LOC +
207  "Direct3D device successfully initialized.");
208  m_render_valid = true;
209  return true;
210 }
211 
212 bool VideoOutputD3D::Init(const QSize &video_dim_buf,
213  const QSize &video_dim_disp,
214  float aspect, WId winid,
215  const QRect &win_rect,MythCodecID codec_id)
216 {
217  MythPainter *painter = GetMythPainter();
218  if (painter)
219  painter->FreeResources();
220 
221  QMutexLocker locker(&m_lock);
222  m_hWnd = (HWND)winid;
224 
225  VideoOutput::Init(video_dim_buf, video_dim_disp,
226  aspect, winid, win_rect, codec_id);
227 
228  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Init with codec: %1")
229  .arg(toString(codec_id)));
230  SetProfile();
231 
232  bool success = true;
233  success &= SetupContext();
234  InitDisplayMeasurements(video_dim_disp.width(), video_dim_disp.height(),
235  false);
236 
238  {
239  if (!CreateDecoder())
240  return false;
241  }
242 
243  success &= CreateBuffers();
244  success &= InitBuffers();
245  success &= CreatePauseFrame();
246 
247  MoveResize();
248 
249  if (!success)
250  TearDown();
251  else
252  {
254  if (m_osd_painter)
255  {
257  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Created D3D9 osd painter.");
258  }
259  else
260  LOG(VB_GENERAL, LOG_ERR, LOC +
261  "Failed to create D3D9 osd painter.");
262  }
263  return success;
264 }
265 
267 {
268  if (db_vdisp_profile)
269  db_vdisp_profile->SetVideoRenderer("direct3d");
270 }
271 
273 {
275  {
276  vbuffers.Init(NUM_DXVA2_BUFS, false, 2, 1, 4, 1);
277  LOG(VB_PLAYBACK, LOG_INFO, LOC +
278  QString("Created %1 empty DXVA2 buffers.") .arg(NUM_DXVA2_BUFS));
279  return true;
280  }
281 
285  return true;
286 
287 }
288 
290 {
291 #ifdef USING_DXVA2
293  {
294  QMutexLocker locker(&m_lock);
295  const QSize video_dim = window.GetVideoDim();
296  bool ok = true;
297  for (int i = 0; i < NUM_DXVA2_BUFS; i++)
298  {
299  ok &= vbuffers.CreateBuffer(video_dim.width(),
300  video_dim.height(), i,
302  }
303  if (ok)
304  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Initialised DXVA2 buffers.");
305  return ok;
306  }
307 #endif
309  window.GetVideoDim().width(),
310  window.GetVideoDim().height());
311 }
312 
314 {
316  return true;
317 
319  new unsigned char[vbuffers.GetScratchFrame()->size + 128],
323 
325  return true;
326 }
327 
329  OSD *osd)
330 {
331  (void)osd;
332  if (IsErrored())
333  {
334  LOG(VB_GENERAL, LOG_ERR, LOC +
335  "PrepareFrame() called while IsErrored is true.");
336  return;
337  }
338 
339  if (!buffer && codec_is_std(video_codec_id))
340  buffer = vbuffers.GetScratchFrame();
341 
342  bool dummy = false;
343  if (buffer)
344  {
345  dummy = buffer->dummy;
346  framesPlayed = buffer->frameNumber + 1;
347  }
348 
349  if (!m_render || !m_video)
350  return;
351 
353  if (m_render_valid)
354  {
355  QRect dvr = vsz_enabled ? vsz_desired_display_rect :
357  bool ok = m_render->ClearBuffer();
358  if (ok && !dummy)
360  255, true);
361 
362  if (ok)
363  {
364  ok = m_render->Begin();
365  if (ok)
366  {
367  if (!dummy)
368  m_video->Draw();
369  QMap<MythPlayer*,D3D9Image*>::iterator it = m_pips.begin();
370  for (; it != m_pips.end(); ++it)
371  {
372  if (m_pip_ready[it.key()])
373  {
374  if (m_pip_active == *it)
375  {
376  QRect rect = (*it)->GetRect();
377  if (!rect.isNull())
378  {
379  rect.adjust(-10, -10, 10, 10);
380  m_render->DrawRect(rect, QColor(128,0,0,255), 255);
381  }
382  }
383  (*it)->Draw();
384  }
385  }
386 
387  if (m_visual)
389 
390  if (osd && m_osd_painter && !window.IsEmbedding())
392  true);
393  m_render->End();
394  }
395  }
396 
397  }
398 }
399 
401 {
402  if (IsErrored())
403  {
404  LOG(VB_GENERAL, LOG_ERR, LOC +
405  "Show() called while IsErrored is true.");
406  return;
407  }
408 
409  if (!m_render)
410  return;
411 
413  if (m_render_valid)
415 }
416 
417 void VideoOutputD3D::EmbedInWidget(const QRect &rect)
418 {
419  if (window.IsEmbedding())
420  return;
421 
423  // TODO: Initialise m_hEmbedWnd?
424 }
425 
427 {
428  if (!window.IsEmbedding())
429  return;
430 
432 }
433 
435 {
436  QMutexLocker locker(&m_lock);
437  VideoOutput::Zoom(direction);
438  MoveResize();
439 }
440 
441 void VideoOutputD3D::UpdatePauseFrame(int64_t &disp_timecode)
442 {
443  QMutexLocker locker(&m_lock);
444  VideoFrame *used_frame = vbuffers.Head(kVideoBuffer_used);
445 
447  {
448  if (!used_frame)
449  used_frame = vbuffers.GetScratchFrame();
450  CopyFrame(&m_pauseFrame, used_frame);
451  disp_timecode = m_pauseFrame.disp_timecode;
452  }
453  else if (codec_is_dxva2(video_codec_id))
454  {
455  if (used_frame)
456  {
457  m_pause_surface = used_frame->buf;
458  disp_timecode = used_frame->disp_timecode;
459  }
460  else
461  LOG(VB_PLAYBACK, LOG_WARNING, LOC + "Failed to update pause frame");
462  }
463 }
464 
466 {
468  return;
469 
470  // TODO - add a size check
471  bool hardware_conv = false;
472  uint pitch = 0;
473  uint8_t *buf = img->GetBuffer(hardware_conv, pitch);
474  if (buf && hardware_conv)
475  {
476  copybuffer(buf, frame, pitch);
477  }
478  else if (buf && !hardware_conv)
479  {
480  AVFrame image_out;
481  av_image_fill_arrays(image_out.data, image_out.linesize,
482  (uint8_t*)buf,
483  AV_PIX_FMT_RGB32, frame->width, frame->height, IMAGE_ALIGN);
484  image_out.linesize[0] = pitch;
485  m_copyFrame.Copy(&image_out, frame,(uint8_t*)buf, AV_PIX_FMT_RGB32);
486  }
487  img->ReleaseBuffer();
488 }
489 
491  FilterChain *filterList,
492  const PIPMap &pipPlayers,
494 {
495  if (!m_render || !m_video)
496  return;
497 
498  QMutexLocker locker(&m_lock);
499  if (IsErrored())
500  {
501  LOG(VB_GENERAL, LOG_ERR, LOC +
502  "ProcessFrame() called while IsErrored is true.");
503  return;
504  }
505 
506  bool gpu = codec_is_dxva2(video_codec_id);
507 
508  if (gpu && frame && frame->codec != FMT_DXVA2)
509  {
510  LOG(VB_GENERAL, LOG_ERR, LOC + "Wrong frame format");
511  return;
512  }
513 
514  bool dummy = false;
515  bool pauseframe = false;
516  if (!frame)
517  {
518  if (!gpu)
519  {
520  frame = vbuffers.GetScratchFrame();
522  }
523  pauseframe = true;
524  }
525 
526  CropToDisplay(frame);
527 
528  if (frame)
529  dummy = frame->dummy;
530  bool deint_proc = m_deinterlacing && (m_deintFilter != nullptr) &&
531  !dummy;
532 
533  if (filterList && !gpu && !dummy)
534  filterList->ProcessFrame(frame);
535 
536  bool safepauseframe = pauseframe && !IsBobDeint() && !gpu;
537  if (deint_proc && m_deinterlaceBeforeOSD &&
538  (!pauseframe || safepauseframe))
539  {
541  }
542 
543  if (!window.IsEmbedding())
544  ShowPIPs(frame, pipPlayers);
545 
546  if ((!pauseframe || safepauseframe) &&
547  deint_proc && !m_deinterlaceBeforeOSD)
548  {
550  }
551 
552  // Test the device
554  if (m_render_reset)
555  SetupContext();
556 
557  // Update a software decoded frame
558  if (m_render_valid && !gpu && !dummy)
559  UpdateFrame(frame, m_video);
560 
561  // Update a GPU decoded frame
562  if (m_render_valid && gpu && !dummy)
563  {
565  if (m_render_reset)
566  CreateDecoder();
567 
568  if (m_render_valid && frame)
569  {
570  m_render->CopyFrame(frame->buf, m_video);
571  }
572  else if (m_render_valid && pauseframe)
573  {
575  }
576  }
577 }
578 
580  MythPlayer *pipplayer,
581  PIPLocation loc)
582 {
583  if (!pipplayer)
584  return;
585 
586  int pipw, piph;
587  VideoFrame *pipimage = pipplayer->GetCurrentFrame(pipw, piph);
588  const float pipVideoAspect = pipplayer->GetVideoAspect();
589  const QSize pipVideoDim = pipplayer->GetVideoBufferSize();
590  const bool pipActive = pipplayer->IsPIPActive();
591  const bool pipVisible = pipplayer->IsPIPVisible();
592  const uint pipVideoWidth = pipVideoDim.width();
593  const uint pipVideoHeight = pipVideoDim.height();
594 
595  if ((pipVideoAspect <= 0) || !pipimage ||
596  !pipimage->buf || (pipimage->codec != FMT_YV12) || !pipVisible)
597  {
598  pipplayer->ReleaseCurrentFrame(pipimage);
599  return;
600  }
601 
602  QRect position = GetPIPRect(loc, pipplayer);
603 
604  m_pip_ready[pipplayer] = false;
605  D3D9Image *m_pip = m_pips[pipplayer];
606  if (!m_pip)
607  {
608  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Initialise PiP.");
609  m_pip = new D3D9Image(m_render, QSize(pipVideoWidth, pipVideoHeight),
610  true);
611  m_pips[pipplayer] = m_pip;
612  if (!m_pip->IsValid())
613  {
614  pipplayer->ReleaseCurrentFrame(pipimage);
615  return;
616  }
617  }
618 
619  QSize current = m_pip->GetSize();
620  if ((uint)current.width() != pipVideoWidth ||
621  (uint)current.height() != pipVideoHeight)
622  {
623  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Re-initialise PiP.");
624  delete m_pip;
625  m_pip = new D3D9Image(m_render, QSize(pipVideoWidth, pipVideoHeight),
626  true);
627  m_pips[pipplayer] = m_pip;
628  if (!m_pip->IsValid())
629  {
630  pipplayer->ReleaseCurrentFrame(pipimage);
631  return;
632  }
633  }
634  m_pip->UpdateVertices(position, QRect(0, 0, pipVideoWidth, pipVideoHeight),
635  255, true);
636  UpdateFrame(pipimage, m_pip);
637  m_pip_ready[pipplayer] = true;
638  if (pipActive)
639  m_pip_active = m_pip;
640 
641  pipplayer->ReleaseCurrentFrame(pipimage);
642 }
643 
645 {
646  if (!m_pips.contains(pipplayer))
647  return;
648 
649  QMutexLocker locker(&m_lock);
650 
651  D3D9Image *m_pip = m_pips[pipplayer];
652  if (m_pip)
653  delete m_pip;
654  m_pip_ready.remove(pipplayer);
655  m_pips.remove(pipplayer);
656 }
657 
659  MythCodecID myth_codec_id, const QSize &video_dim)
660 {
661  QStringList list;
662  if (codec_is_std(myth_codec_id) || (codec_is_dxva2_hw(myth_codec_id) &&
663  !getenv("NO_DXVA2")))
664  {
665  list += "direct3d";
666  }
667  return list;
668 }
669 
671 {
672  return m_osd_painter;
673 }
674 
675 bool VideoOutputD3D::ApproveDeintFilter(const QString& filtername) const
676 {
678  {
679  return !filtername.contains("bobdeint") &&
680  !filtername.contains("opengl") &&
681  !filtername.contains("vdpau");
682  }
683 
684  return false;
685 }
686 
688  uint width, uint height, const QString &decoder,
689  uint stream_type, bool no_acceleration,
690  AVPixelFormat &pix_fmt)
691 {
692 #ifdef USING_DXVA2
693  QSize size(width, height);
694  bool use_cpu = no_acceleration;
695  MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_DXVA2 + (stream_type - 1));
696  use_cpu |= !codec_is_dxva2_hw(test_cid);
697  pix_fmt = AV_PIX_FMT_DXVA2_VLD;
698  if ((decoder == "dxva2") && !getenv("NO_DXVA2") && !use_cpu)
699  return test_cid;
700 #endif
701  return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1));
702 }
703 
704 
705 void* VideoOutputD3D::GetDecoderContext(unsigned char* buf, uint8_t*& id)
706 {
707  (void)buf;
708  (void)id;
709 #ifdef USING_DXVA2
710  if (m_decoder)
711  return (void*)&m_decoder->m_context;
712 #endif
713  return nullptr;
714 }
715 
717 {
718 #ifdef USING_DXVA2
719  QMutexLocker locker(&m_lock);
720  if (m_decoder)
721  DeleteDecoder();
722  QSize video_dim = window.GetVideoDim();
724  video_dim.width(), video_dim.height());
725  return (m_decoder && m_decoder->Init(m_render));
726 #else
727  return false;
728 #endif
729 }
730 
732 {
733 #ifdef USING_DXVA2
734  QMutexLocker locker(&m_lock);
735  delete m_decoder;
736  m_decoder = nullptr;
737 #endif
738 }
739 
740 /* vim: set expandtab tabstop=4 shiftwidth=4: */
bool ClearBuffer(void)
void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd) override
void Reset(void)
Resets the class so that Init may be called again.
MythPainter * invalid_osd_painter
Definition: videooutbase.h:374
bool CreateDecoder(void)
float GetVideoAspect(void) const
Definition: mythplayer.h:175
void SetVideoRenderer(const QString &video_renderer)
def scan(profile, smoonURL, gate)
Definition: scan.py:43
static void copybuffer(VideoFrame *dst, uint8_t *buffer, int pitch, VideoFrameType type=FMT_YV12)
Definition: mythframe.h:324
QMap< MythPlayer *, PIPLocation > PIPMap
Definition: videooutbase.h:37
void WindowResized(const QSize &new_size) override
MythPainter * GetOSDPainter(void) override
int Copy(VideoFrame *dst, const VideoFrame *src)
Definition: mythavutil.cpp:200
QString toString(MarkTypes type)
virtual bool IsBobDeint(void) const
bool m_deinterlacing
Definition: videooutbase.h:350
MythCodecID
Definition: mythcodecid.h:10
void Zoom(ZoomDirection direction) override
Sets up zooming into to different parts of the video, the zoom is actually applied in MoveResize().
struct AVFrame AVFrame
static void GetRenderOptions(render_opts &opts, QStringList &cpudeints)
MythRenderD3D9 * m_render
Definition: videoout_d3d.h:88
#define NUM_DXVA2_BUFS
bool InitBuffers(void)
bool ApproveDeintFilter(const QString &filtername) const override
Approves bobdeint filter for XVideo and otherwise defers to VideoOutput::ApproveDeintFilter(const QSt...
QRect GetVideoRect(void) const
virtual bool Init(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, WId winid, const QRect &win_rect, MythCodecID codec_id)
Performs most of the initialization for VideoOutput.
void SetProfile(void)
void * GetSurface(uint num)
MythPainter * GetMythPainter(void)
QRect GetTotalOSDBounds(void) const
Returns total OSD bounds.
VideoFrame * GetCurrentFrame(int &w, int &h)
bool IsValid(void) const
void CropToDisplay(VideoFrame *frame)
FrameScanType
Definition: videoouttypes.h:80
unsigned int uint
Definition: compat.h:140
bool CreatePauseFrame(void)
#define codec_is_dxva2_hw(id)
Definition: mythcodecid.h:140
bool Init(MythRenderD3D9 *render)
bool CreateBuffers(void)
virtual void StopEmbedding(void)
Tells video output to stop embedding video in an existing window.
void ProcessFrame(VideoFrame *Frame, FrameScanType scan=kScan_Ignore)
#define LOC
bool Present(HWND win)
VideoVisual * m_visual
Definition: videooutbase.h:377
VideoDisplayProfile * db_vdisp_profile
Definition: videooutbase.h:330
void TearDown(void)
VideoFrame m_pauseFrame
Definition: videoout_d3d.h:84
virtual void EmbedInWidget(const QRect &rect)
Tells video output to embed video in an existing window.
bool Init(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, WId winid, const QRect &win_rect, MythCodecID codec_id) override
Performs most of the initialization for VideoOutput.
void * m_pause_surface
Definition: videoout_d3d.h:104
void * GetDecoderContext(unsigned char *buf, uint8_t *&id) override
long long framesPlayed
Definition: videooutbase.h:361
static MythCodecID GetBestSupportedCodec(uint width, uint height, const QString &decoder, uint stream_type, bool no_acceleration, AVPixelFormat &pix_fmt)
bool CreateBuffers(VideoFrameType type, int width, int height, vector< unsigned char * > bufs, vector< YUVInfo > yuvinfo)
bool Create(QSize size, HWND window)
virtual void ShowPIPs(VideoFrame *frame, const PIPMap &pipPlayers)
This class serves as the base class for all video output methods.
Definition: videooutbase.h:46
void DrawRect(const QRect &rect, const QColor &color, int alpha)
static void CopyFrame(VideoFrame *to, const VideoFrame *from)
Copies frame data from one VideoFrame to another.
void SetSwapControl(bool swap)
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
virtual void FreeResources(void)
Definition: mythpainter.h:49
#define codec_is_dxva2(id)
Definition: mythcodecid.h:138
void Show(FrameScanType) override
VideoBuffers vbuffers
VideoBuffers instance used to track video output buffers.
Definition: videooutbase.h:357
MythD3D9Painter * m_osd_painter
Definition: videoout_d3d.h:97
void ReleaseCurrentFrame(VideoFrame *frame)
int height
Definition: mythframe.h:42
MythCodecID video_codec_id
Definition: videooutbase.h:329
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
VideoErrorState errorState
Definition: videooutbase.h:360
virtual void BestDeint(void)
Change to the best deinterlacing method.
unsigned char t
Definition: ParseText.cpp:329
const int kPrebufferFramesNormal
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
bool CreateBuffer(int width, int height, uint num, void *data, VideoFrameType fmt)
bool DrawDirect(MythPainter *painter, QSize size, bool repaint=false)
Definition: osd.cpp:672
void InitDisplayMeasurements(uint width, uint height, bool resize)
Init display measurements based on database settings and actual screen parameters.
bool IsEmbedding(void) const
Returns if videooutput is embedding.
long long frameNumber
Definition: mythframe.h:48
const int kNeedFreeFrames
QRect vsz_desired_display_rect
Definition: videooutbase.h:343
bool SetupContext(void)
bool UpdateVertices(const QRect &dvr, const QRect &vr, int alpha=255, bool video=false)
QRect GetDisplayVideoRect(void) const
bool Draw(void)
DXVA2Decoder * m_decoder
Definition: videoout_d3d.h:102
bool IsErrored() const
Returns true if a fatal error has been encountered.
Definition: videooutbase.h:179
bool vsz_enabled
Definition: videooutbase.h:342
const int kPrebufferFramesSmall
const int kNumBuffers
PIPLocation
Definition: videoouttypes.h:19
VideoFrame * GetScratchFrame(void)
const int kKeepPrebuffer
bool Test(bool &reset)
QSize GetActualVideoDim(void) const
void ShowPIP(VideoFrame *frame, MythPlayer *pipplayer, PIPLocation loc) override
Composites PiP image onto a video frame.
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
QSize GetVideoBufferSize(void) const
Definition: mythplayer.h:173
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
int64_t disp_timecode
Definition: mythframe.h:50
QMap< MythPlayer *, bool > m_pip_ready
Definition: videoout_d3d.h:94
QSize GetSize(void) const
void DestroyContext(void)
void DeleteDecoder(void)
virtual QRect GetPIPRect(PIPLocation location, MythPlayer *pipplayer=nullptr, bool do_pixel_adj=true) const
returns QRect of PIP based on PIPLocation
VideoFrame * Head(BufferType)
void UpdateFrame(VideoFrame *frame, D3D9Image *img)
virtual void VideoAspectRatioChanged(float aspect)
Calls SetVideoAspectRatio(float aspect), then calls MoveResize() to apply changes.
D3D9Image * m_video
Definition: videoout_d3d.h:89
virtual void Zoom(ZoomDirection direction)
Sets up zooming into to different parts of the video, the zoom is actually applied in MoveResize().
void UpdatePauseFrame(int64_t &disp_timecode) override
Updates frame displayed when video is paused.
virtual void MoveResize(void)
performs all the calculations for video framing and any resizing.
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=64)
Definition: mythframe.h:115
Definition: osd.h:132
float GetVideoAspect(void) const
void ProcessFrame(VideoFrame *frame, OSD *osd, FilterChain *filterList, const PIPMap &pipPlayers, FrameScanType scan) override
virtual void Draw(const QRect &area, MythPainter *painter, QPaintDevice *device)=0
void Teardown(void) override
void ReleaseBuffer(void)
QRect GetDisplayVisibleRect(void) const
FilterChain * m_deintFilter
Definition: videooutbase.h:353
void RemovePIP(MythPlayer *pipplayer) override
void SetAllowPreviewEPG(bool allowPreviewEPG)
MythAVCopy m_copyFrame
Definition: videooutbase.h:382
QSize GetVideoDim(void) const
void StopEmbedding(void) override
Tells video output to stop embedding video in an existing window.
bool IsPIPVisible(void) const
Definition: mythplayer.h:229
VideoOutWindow window
Definition: videooutbase.h:320
QMap< MythPlayer *, D3D9Image * > m_pips
Definition: videoout_d3d.h:93
bool m_deinterlaceBeforeOSD
Definition: videooutbase.h:354
void Init(uint numdecode, bool extra_for_pause, uint need_free, uint needprebuffer_normal, uint needprebuffer_small, uint keepprebuffer)
Creates buffers and sets various buffer management parameters.
D3D9Image * m_pip_active
Definition: videoout_d3d.h:95
bool InputChanged(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, MythCodecID av_codec_id, void *codec_private, bool &aspect_only) override
Tells video output to discard decoded frames and wait for new ones.
uint8_t * GetBuffer(bool &hardware_conv, uint &pitch)
void DiscardFrames(bool next_frame_keyframe)
Mark all used frames as ready to be reused, this is for seek.
void EmbedInWidget(const QRect &rect) override
Tells video output to embed video in an existing window.
unsigned char * buf
Definition: mythframe.h:39
ZoomDirection
Definition: videoouttypes.h:28
void DeleteBuffers(void)
#define codec_is_std(id)
Definition: mythcodecid.h:127
bool IsPIPActive(void) const
Definition: mythplayer.h:228
struct dxva_context m_context
Definition: dxva2decoder.h:37
void CopyFrame(void *surface, D3D9Image *img)
VideoFrameType codec
Definition: mythframe.h:38