MythTV  master
videooutbase.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <cstdlib>
3 
4 #include <QDesktopWidget>
5 #include <QRunnable>
6 
7 #include "osd.h"
8 #include "mythplayer.h"
9 #include "videodisplayprofile.h"
10 #include "decoderbase.h"
11 
12 #include "mythcorecontext.h"
13 #include "mythlogging.h"
14 #include "mythmainwindow.h"
15 #include "mythuihelper.h"
16 #include "mythpainter_yuva.h"
17 #include "util-osd.h"
18 #include "mythxdisplay.h"
19 #include "mythavutil.h"
20 #include "mthreadpool.h"
21 #include "mythcodeccontext.h"
22 
23 #ifdef USING_XV
24 #include "videoout_xv.h"
25 #endif
26 
27 #ifdef _WIN32
28 #include "videoout_d3d.h"
29 #endif
30 
31 #ifdef USING_OPENGL_VIDEO
32 #include "videoout_opengl.h"
33 #endif
34 
35 #ifdef USING_VDPAU
36 #include "videoout_vdpau.h"
37 #include "videoout_nullvdpau.h"
38 #endif
39 
40 #ifdef USING_VAAPI
41 #include "videoout_nullvaapi.h"
42 #endif
43 #ifdef USING_GLVAAPI
44 #include "videoout_openglvaapi.h"
45 #endif
46 
47 #ifdef USING_OPENMAX
48 #include "videoout_omx.h"
49 #endif
50 
51 #include "videoout_null.h"
52 #include "dithertable.h"
53 
54 extern "C" {
55 #include "libavcodec/avcodec.h"
56 #include "libswscale/swscale.h"
57 #include "libavutil/imgutils.h"
58 }
59 
60 #include "filtermanager.h"
61 
62 #include "videooutbase.h"
63 
64 #define LOC QString("VideoOutput: ")
65 
66 static QString to_comma_list(const QStringList &list);
67 
69 {
70  FilterManager fm;
71  QStringList cpudeints;
72  cpudeints += "onefield";
73  cpudeints += "linearblend";
74  cpudeints += "kerneldeint";
75  cpudeints += "kerneldoubleprocessdeint";
76  if (fm.GetFilterInfo("greedyhdeint"))
77  cpudeints += "greedyhdeint";
78  if (fm.GetFilterInfo("greedyhdoubleprocessdeint"))
79  cpudeints += "greedyhdoubleprocessdeint";
80  cpudeints += "yadifdeint";
81  cpudeints += "yadifdoubleprocessdeint";
82  cpudeints += "fieldorderdoubleprocessdeint";
83  cpudeints += "none";
84 
86 
87 #ifdef _WIN32
89 #endif
90 
91 #ifdef USING_XV
93 #endif // USING_XV
94 
95 #ifdef USING_OPENGL_VIDEO
97 #endif // USING_OPENGL_VIDEO
98 
99 #ifdef USING_VDPAU
102 #endif // USING_VDPAU
103 
104 #ifdef USING_VAAPI
106 #endif // USING_VAAPI
107 #ifdef USING_GLVAAPI
109 #endif // USING_GLVAAPI
110 
111 #ifdef USING_OPENMAX
113 #endif // USING_OPENMAX
114 }
115 
122  const QString &decoder, MythCodecID codec_id, void *codec_priv,
123  PIPState pipState, const QSize &video_dim_buf,
124  const QSize &video_dim_disp, float video_aspect,
125  QWidget *parentwidget, const QRect &embed_rect, float video_prate,
126  uint playerFlags, QString &codecName)
127 {
128  (void) codec_priv;
129  QStringList renderers;
130 #ifdef USING_XV
131  QStringList xvlist;
132 #endif
133 
134  // select the best available output
135  if (playerFlags & kVideoIsNull)
136  {
137  // plain null output
138  renderers += "null";
139 
140  if (playerFlags & kDecodeAllowGPU)
141  {
142 #ifdef USING_VDPAU
143  renderers += VideoOutputNullVDPAU::GetAllowedRenderers(codec_id);
144 #endif // USING_VDPAU
145 #ifdef USING_VAAPI
146  renderers += VideoOutputNullVAAPI::GetAllowedRenderers(codec_id);
147 #endif
148  }
149  }
150  else
151  {
152 #ifdef _WIN32
153  renderers += VideoOutputD3D::
154  GetAllowedRenderers(codec_id, video_dim_disp);
155 #endif
156 
157 #ifdef USING_XV
158  xvlist = VideoOutputXv::
159  GetAllowedRenderers(codec_id, video_dim_disp);
160  renderers += xvlist;
161 #endif // USING_XV
162 
163 #ifdef USING_OPENGL_VIDEO
164  renderers += VideoOutputOpenGL::
165  GetAllowedRenderers(codec_id, video_dim_disp);
166 #endif // USING_OPENGL_VIDEO
167 
168 #ifdef USING_VDPAU
169  renderers += VideoOutputVDPAU::
170  GetAllowedRenderers(codec_id, video_dim_disp);
171 #endif // USING_VDPAU
172 
173 #ifdef USING_GLVAAPI
174  renderers += VideoOutputOpenGLVAAPI::
175  GetAllowedRenderers(codec_id, video_dim_disp);
176 #endif // USING_GLVAAPI
177 
178 #ifdef USING_OPENMAX
179  renderers += VideoOutputOMX::
180  GetAllowedRenderers(codec_id, video_dim_disp);
181 #endif // USING_OPENMAX
182  }
183 
184  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Allowed renderers: " +
185  to_comma_list(renderers));
186 
187  renderers = VideoDisplayProfile::GetFilteredRenderers(decoder, renderers);
188 
189  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Allowed renderers (filt: " + decoder +
190  "): " + to_comma_list(renderers));
191 
192  QString renderer;
193 
195 
196  if (renderers.size() > 0)
197  {
198  vprof->SetInput(video_dim_disp, video_prate, codecName);
199  QString tmp = vprof->GetVideoRenderer();
200  if (vprof->IsDecoderCompatible(decoder) && renderers.contains(tmp))
201  {
202  renderer = tmp;
203  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Preferred renderer: " + renderer);
204  }
205  }
206 
207  if (renderer.isEmpty())
208  renderer = VideoDisplayProfile::GetBestVideoRenderer(renderers);
209 
210  while (!renderers.empty())
211  {
212  LOG(VB_PLAYBACK, LOG_INFO, LOC +
213  QString("Trying video renderer: '%1'").arg(renderer));
214  int index = renderers.indexOf(renderer);
215  if (index >= 0)
216  renderers.removeAt(index);
217  else
218  break;
219 
220  VideoOutput *vo = nullptr;
221 
222  /* these cases are mutually exlusive */
223  if (renderer == "null")
224  vo = new VideoOutputNull();
225 
226 #ifdef _WIN32
227  else if (renderer == "direct3d")
228  vo = new VideoOutputD3D();
229 #endif // _WIN32
230 
231 #ifdef USING_OPENGL_VIDEO
232  else if (renderer.contains("opengl") && (renderer != "openglvaapi"))
233  vo = new VideoOutputOpenGL(renderer);
234 #endif // USING_OPENGL_VIDEO
235 
236 #ifdef USING_VDPAU
237  else if (renderer == "vdpau")
238  vo = new VideoOutputVDPAU();
239  else if (renderer == "nullvdpau")
240  vo = new VideoOutputNullVDPAU();
241 #endif // USING_VDPAU
242 
243 #ifdef USING_VAAPI
244  else if (renderer == "nullvaapi")
245  vo = new VideoOutputNullVAAPI();
246 #endif // USING_VAAPI
247 
248 #ifdef USING_GLVAAPI
249  else if (renderer == "openglvaapi")
250  vo = new VideoOutputOpenGLVAAPI();
251 #endif // USING_GLVAAPI
252 
253 #ifdef USING_OPENMAX
254  else if (renderer == VideoOutputOMX::kName)
255  vo = new VideoOutputOMX();
256 #endif // USING_OPENMAX
257 
258 #ifdef USING_XV
259  else if (xvlist.contains(renderer))
260  vo = new VideoOutputXv();
261 #endif // USING_XV
262  if (vo)
263  vo->db_vdisp_profile = vprof;
264 
265  if (vo && !(playerFlags & kVideoIsNull))
266  {
267  // ensure we have a window to display into
268  QWidget *widget = parentwidget;
270  if (!widget && window)
271  widget = window->findChild<QWidget*>("video playback window");
272 
273  if (!widget)
274  {
275  LOG(VB_GENERAL, LOG_ERR, LOC + "No window for video output.");
276  delete vo;
277  vo = nullptr;
278  return nullptr;
279  }
280 
281  if (!widget->winId())
282  {
283  LOG(VB_GENERAL, LOG_ERR, LOC + "No window for video output.");
284  delete vo;
285  vo = nullptr;
286  return nullptr;
287  }
288 
289  // determine the display rectangle
290  QRect display_rect = QRect(0, 0, widget->width(), widget->height());
291  if (pipState == kPIPStandAlone)
292  display_rect = embed_rect;
293 
294  vo->SetPIPState(pipState);
295  vo->SetVideoFrameRate(video_prate);
296  if (vo->Init(
297  video_dim_buf, video_dim_disp, video_aspect,
298  widget->winId(), display_rect, codec_id))
299  {
300  vo->SetVideoScalingAllowed(true);
301  return vo;
302  }
303 
304  vo->db_vdisp_profile = nullptr;
305  delete vo;
306  vo = nullptr;
307  }
308  else if (vo && (playerFlags & kVideoIsNull))
309  {
310  if (vo->Init(video_dim_buf, video_dim_disp,
311  video_aspect, 0, QRect(), codec_id))
312  {
313  return vo;
314  }
315 
316  vo->db_vdisp_profile = nullptr;
317  delete vo;
318  vo = nullptr;
319  }
320 
321  renderer = VideoDisplayProfile::GetBestVideoRenderer(renderers);
322  }
323 
324  LOG(VB_GENERAL, LOG_ERR, LOC +
325  "Not compiled with any useable video output method.");
326  delete vprof;
327 
328  return nullptr;
329 }
330 
401  // DB Settings
402  db_display_dim(0,0),
403  db_aspectoverride(kAspect_Off), db_adjustfill(kAdjustFill_Off),
404  db_letterbox_colour(kLetterBoxColour_Black),
405 
406  // Video parameters
407  video_codec_id(kCodec_NONE), db_vdisp_profile(nullptr),
408 
409  // Picture-in-Picture stuff
410  pip_desired_display_size(160,128), pip_display_size(0,0),
411  pip_video_size(0,0),
412  pip_tmp_buf(nullptr), pip_tmp_buf2(nullptr),
413  pip_scaling_context(nullptr),
414 
415  // Video resizing (for ITV)
416  vsz_enabled(false),
417  vsz_desired_display_rect(0,0,0,0), vsz_display_size(0,0),
418  vsz_video_size(0,0),
419  vsz_tmp_buf(nullptr), vsz_scale_context(nullptr),
420 
421  // Deinterlacing
422  m_deinterlacing(false), m_deintfiltername("linearblend"),
423  m_deintFiltMan(nullptr), m_deintFilter(nullptr),
424  m_deinterlaceBeforeOSD(true),
425 
426  // Various state variables
427  errorState(kError_None), framesPlayed(0),
428 
429  // Custom display resolutions
430  display_res(nullptr),
431 
432  // Physical display
433  monitor_sz(640,480), monitor_dim(400,300),
434 
435  // OSD
436  osd_painter(nullptr), osd_image(nullptr),
437  invalid_osd_painter(nullptr),
438 
439  // Visualisation
440  m_visual(nullptr),
441 
442  // 3D TV
443  m_stereo(kStereoscopicModeNone)
444 {
445  memset(&pip_tmp_image, 0, sizeof(pip_tmp_image));
446  db_display_dim = QSize(gCoreContext->GetNumSetting("DisplaySizeWidth", 0),
447  gCoreContext->GetNumSetting("DisplaySizeHeight", 0));
448 
450  gCoreContext->GetNumSetting("AspectOverride", 0);
452  gCoreContext->GetNumSetting("AdjustFill", 0);
454  gCoreContext->GetNumSetting("LetterboxColour", 0);
455 
456  db_vdisp_profile = nullptr;
457 }
458 
464 {
465  if (osd_image)
466  osd_image->DecrRef();
467  if (osd_painter)
468  delete osd_painter;
470  delete invalid_osd_painter;
471  invalid_osd_painter = nullptr;
472 
474 
476 
477  if (m_deintFilter)
478  delete m_deintFilter;
479  if (m_deintFiltMan)
480  delete m_deintFiltMan;
481  if (db_vdisp_profile)
482  delete db_vdisp_profile;
483 
484  ResizeForGui();
485  if (display_res)
486  display_res->Unlock();
487 }
488 
494 bool VideoOutput::Init(const QSize &video_dim_buf,
495  const QSize &video_dim_disp,
496  float aspect, WId winid,
497  const QRect &win_rect, MythCodecID codec_id)
498 {
499  (void)winid;
500 
501  video_codec_id = codec_id;
502  bool wasembedding = window.IsEmbedding();
503  QRect oldrect;
504  if (wasembedding)
505  {
506  oldrect = window.GetEmbeddingRect();
507  StopEmbedding();
508  }
509 
510  bool mainSuccess = window.Init(video_dim_buf, video_dim_disp,
511  aspect, win_rect,
513 
514  if (db_vdisp_profile)
516 
517  if (wasembedding)
518  EmbedInWidget(oldrect);
519 
520  VideoAspectRatioChanged(aspect); // apply aspect ratio and letterbox mode
521 
522  return mainSuccess;
523 }
524 
526 {
528  osd->DisableFade();
529 }
530 
531 QString VideoOutput::GetFilters(void) const
532 {
533  if (db_vdisp_profile)
534  return db_vdisp_profile->GetFilters();
535  return QString();
536 }
537 
538 void VideoOutput::SetVideoFrameRate(float playback_fps)
539 {
540  if (db_vdisp_profile)
541  db_vdisp_profile->SetOutput(playback_fps);
542 }
543 
550 {
551  if (enable && m_deinterlacing)
552  return m_deinterlacing;
553 
554  // if enable and no deinterlacer allocated, attempt allocate one
555  if (enable && (!m_deintFiltMan || !m_deintFilter))
556  return SetupDeinterlace(enable);
557 
558  m_deinterlacing = enable;
559  return m_deinterlacing;
560 }
561 
569 bool VideoOutput::SetupDeinterlace(bool interlaced,
570  const QString& overridefilter)
571 {
572  PIPState pip_state = window.GetPIPState();
573 
574  if (pip_state > kPIPOff && pip_state < kPBPLeft)
575  return false;
576 
577  if (m_deinterlacing == interlaced)
578  {
579  if (!m_deinterlacing)
580  return false;
581  if (overridefilter.isEmpty() || overridefilter == m_deintfiltername)
582  return true;
583  }
584 
585  if (m_deintFiltMan)
586  {
587  delete m_deintFiltMan;
588  m_deintFiltMan = nullptr;
589  }
590  if (m_deintFilter)
591  {
592  delete m_deintFilter;
593  m_deintFilter = nullptr;
594  }
595 
596  m_deinterlacing = interlaced;
597 
598  if (m_deinterlacing)
599  {
600  m_deinterlaceBeforeOSD = true;
601 
602  VideoFrameType itmp = FMT_YV12;
603  VideoFrameType otmp = FMT_YV12;
604 
605  if (db_vdisp_profile)
607  db_vdisp_profile->GetFilteredDeint(overridefilter);
608  else
609  m_deintfiltername = "";
610 
611  m_deintFilter = nullptr;
612  m_deintFiltMan = nullptr;
613 
615  {
616  m_deinterlacing = false;
617  return false;
618  }
619 
621 
622  if (!m_deintfiltername.isEmpty())
623  {
625  {
626  LOG(VB_GENERAL, LOG_ERR,
627  QString("Failed to approve '%1' deinterlacer "
628  "as a software deinterlacer")
629  .arg(m_deintfiltername));
630  m_deintfiltername.clear();
631  }
632  else
633  {
634  int btmp;
635  int threads = db_vdisp_profile ?
637  const QSize video_dim = window.GetVideoDim();
638  int width = video_dim.width();
639  int height = video_dim.height();
641  m_deintfiltername, itmp, otmp,
642  width, height, btmp, threads);
643  window.SetVideoDim(QSize(width, height));
644  }
645  }
646 
647  if (m_deintFilter == nullptr)
648  {
649  LOG(VB_GENERAL, LOG_ERR, LOC +
650  QString("Couldn't load deinterlace filter %1")
651  .arg(m_deintfiltername));
652  m_deinterlacing = false;
653  m_deintfiltername = "";
654  }
655 
656  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Using deinterlace method %1")
657  .arg(m_deintfiltername));
658 
659  if (m_deintfiltername == "bobdeint")
660  m_deinterlaceBeforeOSD = false;
661  }
662 
663  return m_deinterlacing;
664 }
665 
670 {
671  SetupDeinterlace(false);
672  if (db_vdisp_profile)
674 }
675 
680 {
681  SetupDeinterlace(false);
682  SetupDeinterlace(true);
683 }
684 
695 {
696  return (m_deintfiltername.contains("doubleprocess")) && m_deinterlacing;
697 }
705 {
706  // Bob deinterlace requires doubling framerate
707  return ((m_deintfiltername.contains("bobdeint") ||
708  m_deintfiltername.contains("doublerate") ||
709  m_deintfiltername.contains("doubleprocess")) &&
711 }
712 
713 bool VideoOutput::IsBobDeint(void) const
714 {
715  return (m_deinterlacing && m_deintfiltername == "bobdeint");
716 }
717 
723 bool VideoOutput::ApproveDeintFilter(const QString& filtername) const
724 {
725  // Default to not supporting bob deinterlace
726  return (!filtername.contains("bobdeint") &&
727  !filtername.contains("doublerate") &&
728  !filtername.contains("opengl") &&
729  !filtername.contains("vdpau"));
730 }
731 
732 void VideoOutput::GetDeinterlacers(QStringList &deinterlacers)
733 {
734  if (!db_vdisp_profile)
735  return;
736  QString rend = db_vdisp_profile->GetActualVideoRenderer();
737  deinterlacers = db_vdisp_profile->GetDeinterlacers(rend);
738 }
739 
747 {
749 }
750 
756 bool VideoOutput::InputChanged(const QSize &video_dim_buf,
757  const QSize &video_dim_disp,
758  float aspect,
759  MythCodecID myth_codec_id,
760  void *codec_private,
761  bool &/*aspect_only*/)
762 {
763  window.InputChanged(video_dim_buf, video_dim_disp,
764  aspect, myth_codec_id, codec_private);
765 
766  AVCodecID avCodecId = (AVCodecID) myth2av_codecid(myth_codec_id);
767  AVCodec *codec = avcodec_find_decoder(avCodecId);
768  QString codecName;
769  if (codec)
770  codecName = codec->name;
771  if (db_vdisp_profile)
773  video_codec_id = myth_codec_id;
774  BestDeint();
775 
776  DiscardFrames(true);
777 
778  return true;
779 }
783 void VideoOutput::ResizeDisplayWindow(const QRect &rect, bool save_visible_rect)
784 {
785  window.ResizeDisplayWindow(rect, save_visible_rect);
786 }
787 
792 void VideoOutput::EmbedInWidget(const QRect &rect)
793 {
794  window.EmbedInWidget(rect);
795 }
796 
803 {
805 }
806 
812 void VideoOutput::DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
813 {
814  (void)frame;
815  (void)x;
816  (void)y;
817  (void)w;
818  (void)h;
819 }
820 
821 void VideoOutput::GetOSDBounds(QRect &total, QRect &visible,
822  float &visible_aspect,
823  float &font_scaling,
824  float themeaspect) const
825 {
826  total = GetTotalOSDBounds();
827  visible = GetVisibleOSDBounds(visible_aspect, font_scaling, themeaspect);
828 }
829 
837  float &visible_aspect, float &font_scaling, float themeaspect) const
838 {
839  if (!hasFullScreenOSD())
840  {
842  visible_aspect, font_scaling, themeaspect);
843  }
844 
845  QRect dvr = window.GetDisplayVisibleRect();
846 
847  // This rounding works for I420 video...
848  QSize dvr2 = QSize(dvr.width() & ~0x3,
849  dvr.height() & ~0x1);
850 
851  float dispPixelAdj = 1.0f;
852  if (dvr2.height() && dvr2.width())
853  dispPixelAdj = (GetDisplayAspect() * dvr2.height()) / dvr2.width();
854 
855  float ova = window.GetOverridenVideoAspect();
856  QRect vr = window.GetVideoRect();
857  float vs = vr.height() ? (float)vr.width() / vr.height() : 1.f;
858  visible_aspect = themeaspect * (ova ? vs / ova : 1.f) * dispPixelAdj;
859 
860  font_scaling = 1.0f;
861  return QRect(QPoint(0,0), dvr2);
862 }
863 
869 {
870  if (!hasFullScreenOSD())
871  return window.GetTotalOSDBounds();
872 
873  QRect dvr = window.GetDisplayVisibleRect();
874  QSize dvr2 = QSize(dvr.width() & ~0x3,
875  dvr.height() & ~0x1);
876 
877  return QRect(QPoint(0,0), dvr2);
878 }
879 
881 {
882  if (!hasFullScreenOSD())
883  return window.GetTotalOSDBounds();
884 
885  QRect dvr = window.GetDisplayVideoRect();
886  return QRect(QPoint(dvr.left() & ~0x1, dvr.top() & ~0x1),
887  QSize(dvr.width() & ~0x1, dvr.height() & ~0x1));
888 }
889 
891 {
892  return window.IsPreviewEPGAllowed();
893 }
894 
906 {
907  window.MoveResize();
908 }
909 
917 {
918  window.Zoom(direction);
919 }
920 
927 {
929 }
930 
936 {
938 }
939 
948 {
949  window.ToggleAspectOverride(aspectMode);
950 }
951 
960 {
961  window.ToggleAdjustFill(adjustFill);
962 }
963 
965  PictureAttribute attributeType, bool direction)
966 {
967  int curVal = GetPictureAttribute(attributeType);
968  if (curVal < 0)
969  return -1;
970 
971  int newVal = curVal + ((direction) ? +1 : -1);
972 
973  if (kPictureAttribute_Hue == attributeType)
974  newVal = newVal % 100;
975 
976  if ((kPictureAttribute_StudioLevels == attributeType) && newVal > 1)
977  newVal = 1;
978 
979  newVal = min(max(newVal, 0), 100);
980 
981  return SetPictureAttribute(attributeType, newVal);
982 }
983 
992 {
993  return videoColourSpace.SetPictureAttribute(attribute, newValue);
994 }
995 
997 {
998  return videoColourSpace.GetPictureAttribute(attributeType);
999 }
1000 
1004 QString VideoOutput::GetOSDRenderer(void) const
1005 {
1006  return db_vdisp_profile->GetOSDRenderer();
1007 }
1008 
1009 /*
1010  * \brief Determines PIP Window size and Position.
1011  */
1013  PIPLocation location, MythPlayer *pipplayer, bool do_pixel_adj) const
1014 {
1015  return window.GetPIPRect(location, pipplayer, do_pixel_adj);
1016 }
1017 
1025 void VideoOutput::DoPipResize(int pipwidth, int pipheight)
1026 {
1027  QSize vid_size = QSize(pipwidth, pipheight);
1028  if (vid_size == pip_desired_display_size)
1029  return;
1030 
1032 
1033  pip_video_size = vid_size;
1035 
1036  int sz = buffersize(FMT_YV12,
1037  pip_display_size.width(), pip_display_size.height());
1038  pip_tmp_buf = (unsigned char*)av_malloc(sz);
1039  pip_tmp_buf2 = (unsigned char*)av_malloc(sz);
1040 
1041  pip_scaling_context = sws_getCachedContext(pip_scaling_context,
1042  pip_video_size.width(), pip_video_size.height(),
1043  AV_PIX_FMT_YUV420P,
1044  pip_display_size.width(),
1045  pip_display_size.height(),
1046  AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
1047  nullptr, nullptr, nullptr);
1048 }
1049 
1057 {
1058  if (pip_tmp_buf)
1059  {
1060  av_freep(&pip_tmp_buf);
1061  }
1062 
1063  if (pip_tmp_buf2)
1064  {
1065  av_freep(&pip_tmp_buf2);
1066  }
1067 
1068  if (pip_scaling_context)
1069  {
1070  sws_freeContext(pip_scaling_context);
1071  pip_scaling_context = nullptr;
1072  }
1073 
1074  pip_video_size = QSize(0,0);
1075  pip_display_size = QSize(0,0);
1076 }
1077 
1078 void VideoOutput::ShowPIPs(VideoFrame *frame, const PIPMap &pipPlayers)
1079 {
1080  PIPMap::const_iterator it = pipPlayers.begin();
1081  for (; it != pipPlayers.end(); ++it)
1082  ShowPIP(frame, it.key(), *it);
1083 }
1084 
1096  MythPlayer *pipplayer,
1097  PIPLocation loc)
1098 {
1099  if (!pipplayer)
1100  return;
1101 
1102  const float video_aspect = window.GetVideoAspect();
1103 // const QRect display_video_rect = window.GetDisplayVideoRect();
1104 // const QRect video_rect = window.GetVideoRect();
1105 // const QRect display_visible_rect = window.GetDisplayVisibleRect();
1106 // const QSize video_disp_dim = window.GetVideoDispDim();
1107 
1108  int pipw, piph;
1109  VideoFrame *pipimage = pipplayer->GetCurrentFrame(pipw, piph);
1110  const bool pipActive = pipplayer->IsPIPActive();
1111  const bool pipVisible = pipplayer->IsPIPVisible();
1112  const float pipVideoAspect = pipplayer->GetVideoAspect();
1113 // const QSize pipVideoDim = pipplayer->GetVideoBufferSize();
1114 
1115  // If PiP is not initialized to values we like, silently ignore the frame.
1116  if ((video_aspect <= 0) || (pipVideoAspect <= 0) ||
1117  (frame->height <= 0) || (frame->width <= 0) ||
1118  !pipimage || !pipimage->buf || pipimage->codec != FMT_YV12)
1119  {
1120  pipplayer->ReleaseCurrentFrame(pipimage);
1121  return;
1122  }
1123 
1124  if (!pipVisible)
1125  {
1126  pipplayer->ReleaseCurrentFrame(pipimage);
1127  return;
1128  }
1129 
1130  QRect position = GetPIPRect(loc, pipplayer);
1131 
1132  pip_desired_display_size = position.size();
1133 
1134  // Scale the image if we have to...
1135  if (pipw != pip_desired_display_size.width() ||
1136  piph != pip_desired_display_size.height())
1137  {
1138  DoPipResize(pipw, piph);
1139 
1140  memset(&pip_tmp_image, 0, sizeof(pip_tmp_image));
1141 
1143  {
1144  AVFrame img_in, img_out;
1145  av_image_fill_arrays(
1146  img_out.data, img_out.linesize,
1147  pip_tmp_buf, AV_PIX_FMT_YUV420P,
1148  pip_display_size.width(), pip_display_size.height(),
1149  IMAGE_ALIGN);
1150 
1151  AVPictureFill(&img_in, pipimage);
1152 
1153  sws_scale(pip_scaling_context, img_in.data, img_in.linesize, 0,
1154  piph, img_out.data, img_out.linesize);
1155 
1156  pipw = pip_display_size.width();
1157  piph = pip_display_size.height();
1158 
1159  if (pipActive)
1160  {
1161  AVFrame img_padded;
1162  av_image_fill_arrays(img_padded.data, img_padded.linesize,
1163  pip_tmp_buf2,
1164  AV_PIX_FMT_YUV420P, pipw, piph, IMAGE_ALIGN);
1165 
1166  int color[3] = { 20, 0, 200 }; //deep red YUV format
1167  av_picture_pad((AVPicture*)(&img_padded),
1168  (AVPicture*)(&img_out), piph, pipw,
1169  AV_PIX_FMT_YUV420P, 4, 4, 4, 4, color);
1170 
1171  int offsets[3] = {0, int(img_padded.data[1] - img_padded.data[0]),
1172  int(img_padded.data[2] - img_padded.data[0]) };
1173  init(&pip_tmp_image, FMT_YV12, img_padded.data[0], pipw, piph,
1174  sizeof(int), img_padded.linesize, offsets);
1175  }
1176  else
1177  {
1178  int offsets[3] = {0, int(img_out.data[1] - img_out.data[0]),
1179  int(img_out.data[2] - img_out.data[0]) };
1180  init(&pip_tmp_image, FMT_YV12, img_out.data[0], pipw, piph,
1181  sizeof(int), img_out.linesize, offsets);
1182  }
1183  }
1184  }
1185 
1186  if ((position.left() >= 0) && (position.top() >= 0))
1187  {
1188  int xoff = position.left();
1189  int yoff = position.top();
1190  int xoff2[3] = { xoff, xoff>>1, xoff>>1 };
1191  int yoff2[3] = { yoff, yoff>>1, yoff>>1 };
1192 
1193  int pip_height = pip_tmp_image.height;
1194  int height[3] = { pip_height, pip_height>>1, pip_height>>1 };
1195  int pip_width = pip_tmp_image.width;
1196  int widths[3] = { pip_width, pip_width>>1, pip_width>>1 };
1197 
1198  for (int p = 0; p < 3; p++)
1199  {
1200  for (int h = pipActive ? 0 : 1; h < height[p]; h++)
1201  {
1202  memcpy((frame->buf + frame->offsets[p]) + (h + yoff2[p]) *
1203  frame->pitches[p] + xoff2[p],
1204  (pip_tmp_image.buf + pip_tmp_image.offsets[p]) + h *
1205  pip_tmp_image.pitches[p], widths[p]);
1206  }
1207  }
1208  }
1209 
1210  // we're done with the frame, release it
1211  pipplayer->ReleaseCurrentFrame(pipimage);
1212 }
1213 
1220 void VideoOutput::DoVideoResize(const QSize &inDim, const QSize &outDim)
1221 {
1222  if ((inDim == vsz_video_size) && (outDim == vsz_display_size))
1223  return;
1224 
1226 
1227  vsz_enabled = true;
1228  vsz_video_size = inDim;
1229  vsz_display_size = outDim;
1230 
1231  int sz = vsz_display_size.height() * vsz_display_size.width() * 3 / 2;
1232  vsz_tmp_buf = new unsigned char[sz];
1233 
1234  vsz_scale_context = sws_getCachedContext(vsz_scale_context,
1235  vsz_video_size.width(), vsz_video_size.height(),
1236  AV_PIX_FMT_YUV420P,
1237  vsz_display_size.width(),
1238  vsz_display_size.height(),
1239  AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
1240  nullptr, nullptr, nullptr);
1241 }
1242 
1244 {
1245  if (vsz_desired_display_rect.isNull() || frame->codec != FMT_YV12)
1246  return;
1247 
1248  QRect resize = vsz_desired_display_rect;
1249  QSize frameDim(frame->width, frame->height);
1250 
1251  // if resize is outside existing frame, abort
1252  bool abort =
1253  (resize.right() > frame->width || resize.bottom() > frame->height ||
1254  resize.width() > frame->width || resize.height() > frame->height);
1255  // if resize == existing frame, no need to carry on
1256  abort |= !resize.left() && !resize.top() && (resize.size() == frameDim);
1257 
1258  if (abort)
1259  {
1261  vsz_desired_display_rect = QRect();
1262  return;
1263  }
1264 
1265  DoVideoResize(frameDim, resize.size());
1266  if (!vsz_tmp_buf)
1267  {
1269  vsz_desired_display_rect = QRect();
1270  return;
1271  }
1272 
1274  {
1275  AVFrame img_in, img_out;
1276 
1277  av_image_fill_arrays(img_out.data, img_out.linesize,
1278  vsz_tmp_buf, AV_PIX_FMT_YUV420P,
1279  resize.width(), resize.height(),IMAGE_ALIGN);
1280  av_image_fill_arrays(img_in.data, img_in.linesize,
1281  frame->buf, AV_PIX_FMT_YUV420P,
1282  frame->width, frame->height,IMAGE_ALIGN);
1283  img_in.data[0] = frame->buf + frame->offsets[0];
1284  img_in.data[1] = frame->buf + frame->offsets[1];
1285  img_in.data[2] = frame->buf + frame->offsets[2];
1286  img_in.linesize[0] = frame->pitches[0];
1287  img_in.linesize[1] = frame->pitches[1];
1288  img_in.linesize[2] = frame->pitches[2];
1289  sws_scale(vsz_scale_context, img_in.data, img_in.linesize, 0,
1290  frame->height, img_out.data, img_out.linesize);
1291  }
1292 
1293  // Blanking the unused area can appear better but it costs CPU cycles
1294  //clear(frame);
1295 
1296  int xoff = resize.left();
1297  int yoff = resize.top();
1298  int resw = resize.width();
1299  int vidw = frame->pitches[0];
1300 
1301  unsigned char *yptr = frame->buf + frame->offsets[0];
1302  unsigned char *videoyptr = vsz_tmp_buf;
1303 
1304  // Copy Y (intensity values)
1305  yptr += yoff * vidw + xoff;
1306  for (int i = 0; i < resize.height(); i++)
1307  {
1308  memcpy(yptr, videoyptr, resw);
1309  yptr += vidw;
1310  videoyptr += resw;
1311  }
1312 
1313  // Copy U & V (half plane chroma values)
1314  xoff /= 2;
1315  yoff /= 2;
1316 
1317  unsigned char *uptr = frame->buf + frame->offsets[1];
1318  unsigned char *vptr = frame->buf + frame->offsets[2];
1319  vidw = frame->pitches[1];
1320  uptr += yoff * vidw + xoff;
1321  vptr += yoff * vidw + xoff;
1322 
1323  unsigned char *videouptr = vsz_tmp_buf + resw * resize.height();
1324  unsigned char *videovptr = vsz_tmp_buf + (resw * resize.height() * 5) / 4;
1325  resw /= 2;
1326  for (int i = 0; i < resize.height() / 2; i ++)
1327  {
1328  memcpy(uptr, videouptr, resw);
1329  uptr += vidw;
1330  videouptr += resw;
1331  memcpy(vptr, videovptr, resw);
1332  vptr += vidw;
1333  videovptr += resw;
1334  }
1335 }
1336 
1338 {
1339  return window.GetAspectOverride();
1340 }
1341 
1343 {
1344  return window.GetAdjustFill();
1345 }
1346 
1348 {
1349  return window.GetDisplayAspect();
1350 }
1351 
1353 {
1354  return window.IsVideoScalingAllowed();
1355 }
1356 
1358 {
1359  if (vsz_tmp_buf)
1360  {
1361  delete [] vsz_tmp_buf;
1362  vsz_tmp_buf = nullptr;
1363  }
1364 
1365  if (vsz_scale_context)
1366  {
1367  sws_freeContext(vsz_scale_context);
1368  vsz_scale_context = nullptr;
1369  }
1370 
1371  vsz_video_size = QSize(0,0);
1372  vsz_display_size = QSize(0,0);
1373  vsz_enabled = false;
1374 }
1375 
1377 {
1378  // used by render devices to ignore frame rendering
1379  if (frame)
1380  frame->dummy = 1;
1381  // will only clear frame in main memory
1382  clear(frame);
1383 }
1384 
1385 void VideoOutput::SetVideoResize(const QRect &videoRect)
1386 {
1387  if (!videoRect.isValid() ||
1388  videoRect.width() < 1 || videoRect.height() < 1)
1389  {
1391  vsz_desired_display_rect = QRect();
1392  }
1393  else
1394  {
1395  vsz_enabled = true;
1396  vsz_desired_display_rect = videoRect;
1397  }
1398 }
1399 
1404 {
1406 }
1407 
1408 #ifndef MMX
1409 #define THREADED_OSD_RENDER 1
1410 #endif
1411 
1412 #if THREADED_OSD_RENDER
1413 class OsdRender : public QRunnable
1414 {
1415  public:
1416  OsdRender(VideoFrame *frame, MythImage *osd_image, const QSize &dim, const QRect &vis) :
1417  m_frame(frame), m_osd_image(osd_image), m_video_dim(dim), m_vis(vis)
1418  { }
1419 
1420  void run() override // QRunnable
1421  {
1422  switch (m_frame->codec)
1423  {
1424  case FMT_YV12: yv12(); break;
1425  case FMT_AI44: i44(true); break;
1426  case FMT_IA44: i44(false); break;
1427  default: break;
1428  }
1429  }
1430 
1431  private:
1432  inline void yv12()
1433  {
1434 #define ROUNDUP( _x,_z) ((_x) + ((-(_x)) & ((_z) - 1)) )
1435 #define ROUNDDN( _x,_z) ((_x) & ~((_z) - 1))
1436  int left = m_vis.left();
1437  left = ROUNDUP(left, ALIGN_C);
1438  left = std::min(left, m_osd_image->width());
1439 
1440  int right = m_vis.left() + m_vis.width();
1441  right = ROUNDUP(right, ALIGN_C);
1442  right = std::min(right, m_osd_image->width());
1443 
1444  int top = m_vis.top();
1445  top = ROUNDDN(top, ALIGN_C);
1446 
1447  int bottom = m_vis.top() + m_vis.height();
1448  bottom = ROUNDDN(bottom, ALIGN_C);
1449 
1450  c_yuv888_to_yv12(m_frame, m_osd_image, left, top, right, bottom);
1451  }
1452 
1453  inline void i44(bool ifirst)
1454  {
1455  int left = std::min(m_vis.left(), m_osd_image->width());
1456  int top = std::min(m_vis.top(), m_osd_image->height());
1457  int right = std::min(left + m_vis.width(), m_osd_image->width());
1458  int bottom = std::min(top + m_vis.height(), m_osd_image->height());
1459 
1460  memset(m_frame->buf, 0, m_video_dim.width() * m_video_dim.height());
1461  yuv888_to_i44(m_frame->buf, m_osd_image, m_video_dim,
1462  left, top, right, bottom, ifirst);
1463  }
1464 
1465  private:
1466  VideoFrame * const m_frame;
1467  MythImage * const m_osd_image;
1468  QSize const m_video_dim;
1469  QRect const m_vis;
1470 };
1471 #endif
1472 
1484 {
1485  if (!osd || !frame)
1486  return false;
1487 
1488  if (vsz_enabled)
1489  ResizeVideo(frame);
1490 
1491  if (!osd_painter)
1492  {
1493  osd_painter = new MythYUVAPainter();
1494  if (!osd_painter)
1495  return false;
1496  }
1497 
1498  QSize osd_size = GetTotalOSDBounds().size();
1499  if (osd_image && (osd_image->size() != osd_size))
1500  {
1501  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("OSD size changed."));
1502  osd_image->DecrRef();
1503  osd_image = nullptr;
1504  }
1505 
1506  if (!osd_image)
1507  {
1509  if (osd_image)
1510  {
1511  QImage blank = QImage(osd_size,
1512  QImage::Format_ARGB32_Premultiplied);
1513  osd_image->Assign(blank);
1516  QRegion(QRect(QPoint(0,0), osd_size)));
1517  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Created YV12 OSD."));
1518  }
1519  else
1520  return false;
1521  }
1522 
1523  if (m_visual)
1524  {
1525  LOG(VB_GENERAL, LOG_ERR, LOC + "Visualiser not supported here");
1526  // Clear the audio buffer
1527  m_visual->Draw(QRect(), nullptr, nullptr);
1528  }
1529 
1530  switch (frame->codec)
1531  {
1532  case FMT_YV12:
1533  case FMT_AI44:
1534  case FMT_IA44:
1535  break;
1536  default:
1537  LOG(VB_GENERAL, LOG_ERR, LOC +
1538  "Display OSD: Frame format not supported.");
1539  return false;
1540  }
1541 
1542  QRegion dirty = QRegion();
1543  QRegion visible = osd->Draw(osd_painter, osd_image, osd_size, dirty,
1544  frame->codec == FMT_YV12 ? ALIGN_X_MMX : 0,
1545  frame->codec == FMT_YV12 ? ALIGN_C : 0);
1546  bool changed = !dirty.isEmpty();
1547  bool show = !visible.isEmpty();
1548 
1549  if (!show)
1550  return show;
1551 
1552  if (!changed && frame->codec != FMT_YV12)
1553  return show;
1554 
1555  QSize video_dim = window.GetVideoDim();
1556 
1557 #if THREADED_OSD_RENDER
1558  static MThreadPool s_pool("OsdRender");
1559 
1560  // Split visible region for greater concurrency
1561  QRect r = osd_image->rect();
1562  QPoint c = r.center();
1563  QVector<QRect> vis = visible.intersected(QRect(r.topLeft(),c)).rects();
1564  vis += visible.intersected(QRect(c,r.bottomRight())).rects();
1565  vis += visible.intersected(QRect(r.bottomLeft(),c).normalized()).rects();
1566  vis += visible.intersected(QRect(c,r.topRight()).normalized()).rects();
1567 #else
1568  QVector<QRect> vis = visible.rects();
1569 #endif
1570  for (int i = 0; i < vis.size(); i++)
1571  {
1572 #if THREADED_OSD_RENDER
1573  OsdRender *job = new OsdRender(frame, osd_image, video_dim, vis[i]);
1574  job->setAutoDelete(true);
1575  s_pool.start(job, "OsdRender");
1576 #else
1577  int left = min(vis[i].left(), osd_image->width());
1578  int top = min(vis[i].top(), osd_image->height());
1579  int right = min(left + vis[i].width(), osd_image->width());
1580  int bottom = min(top + vis[i].height(), osd_image->height());
1581 
1582  if (FMT_YV12 == frame->codec)
1583  {
1584  yuv888_to_yv12(frame, osd_image, left, top, right, bottom);
1585  }
1586  else if (FMT_AI44 == frame->codec)
1587  {
1588  memset(frame->buf, 0, video_dim.width() * video_dim.height());
1589  yuv888_to_i44(frame->buf, osd_image, video_dim,
1590  left, top, right, bottom, true);
1591  }
1592  else if (FMT_IA44 == frame->codec)
1593  {
1594  memset(frame->buf, 0, video_dim.width() * video_dim.height());
1595  yuv888_to_i44(frame->buf, osd_image, video_dim,
1596  left, top, right, bottom, false);
1597  }
1598 #endif
1599  }
1600 #if THREADED_OSD_RENDER
1601  s_pool.waitForDone();
1602 #endif
1603  return show;
1604 }
1605 
1607  const QString &name)
1608 {
1609  if (!enable)
1610  {
1612  return false;
1613  }
1614  return SetupVisualisation(audio, nullptr, name);
1615 }
1616 
1618 {
1619  return VideoVisual::CanVisualise(audio, render);
1620 }
1621 
1623  const QString &name)
1624 {
1626  m_visual = VideoVisual::Create(name, audio, render);
1627  return m_visual;
1628 }
1629 
1631 {
1632  if (m_visual)
1633  return m_visual->Name();
1634  return QString("");
1635 }
1636 
1638 {
1639  return QStringList();
1640 }
1641 
1643 {
1644  delete m_visual;
1645  m_visual = nullptr;
1646 }
1647 
1657 {
1658  if (to == nullptr || from == nullptr)
1659  return;
1660 
1661  to->frameNumber = from->frameNumber;
1662  to->disp_timecode = from->disp_timecode;
1663 
1664  copy(to, from);
1665 }
1666 
1667 QRect VideoOutput::GetImageRect(const QRect &rect, QRect *display)
1668 {
1669  float hscale, tmp;
1670  tmp = 0.0;
1671  QRect visible_osd = GetVisibleOSDBounds(tmp, tmp, tmp);
1672  QSize video_size = window.GetVideoDispDim();
1673  int image_height = video_size.height();
1674  int image_width = (image_height > 720) ? 1920 :
1675  (image_height > 576) ? 1280 : 720;
1676  float image_aspect = (float)image_width / (float)image_height;
1677  float pixel_aspect = (float)video_size.width() /
1678  (float)video_size.height();
1679 
1680  QRect rect1 = rect;
1681  if (display && display->isValid())
1682  {
1683  QMatrix m0;
1684  m0.scale((float)image_width / (float)display->width(),
1685  (float)image_height / (float)display->height());
1686  rect1 = m0.mapRect(rect1);
1687  rect1.translate(display->left(), display->top());
1688  }
1689  QRect result = rect1;
1690 
1691  if (hasFullScreenOSD())
1692  {
1693  QRect dvr_rec = window.GetDisplayVideoRect();
1694  QRect vid_rec = window.GetVideoRect();
1695 
1696  hscale = image_aspect / pixel_aspect;
1697  if (hscale < 0.99f || hscale > 1.01f)
1698  {
1699  vid_rec.setLeft(lroundf((float)vid_rec.left() * hscale));
1700  vid_rec.setWidth(lroundf((float)vid_rec.width() * hscale));
1701  }
1702 
1703  float vscale = (float)dvr_rec.width() / (float)image_width;
1704  hscale = (float)dvr_rec.height() / (float)image_height;
1705  QMatrix m1;
1706  m1.translate(dvr_rec.left(), dvr_rec.top());
1707  m1.scale(vscale, hscale);
1708 
1709  vscale = (float)image_width / (float)vid_rec.width();
1710  hscale = (float)image_height / (float)vid_rec.height();
1711  QMatrix m2;
1712  m2.scale(vscale, hscale);
1713  m2.translate(-vid_rec.left(), -vid_rec.top());
1714 
1715  result = m2.mapRect(result);
1716  result = m1.mapRect(result);
1717  return result;
1718  }
1719 
1720  hscale = pixel_aspect / image_aspect;
1721  if (hscale < 0.99f || hscale > 1.01f)
1722  {
1723  result.setLeft(lroundf((float)rect1.left() * hscale));
1724  result.setWidth(lroundf((float)rect1.width() * hscale));
1725  }
1726 
1727  result.translate(-visible_osd.left(), -visible_osd.top());
1728  return result;
1729 }
1730 
1738 {
1739  static const float safeMargin = 0.05f;
1740  float dummy;
1741  QRect result = GetVisibleOSDBounds(dummy, dummy, 1.0f);
1742  int safex = (int)((float)result.width() * safeMargin);
1743  int safey = (int)((float)result.height() * safeMargin);
1744  return QRect(result.left() + safex, result.top() + safey,
1745  result.width() - (2 * safex), result.height() - (2 * safey));
1746 }
1747 
1749 {
1750  window.SetPIPState(setting);
1751 }
1752 
1753 
1754 static QString to_comma_list(const QStringList &list)
1755 {
1756  QString ret = "";
1757  for (QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
1758  ret += *it + ",";
1759 
1760  if (ret.length())
1761  return ret.left(ret.length()-1);
1762 
1763  return "";
1764 }
1765 
1767 {
1768  return window.IsEmbedding();
1769 }
1770 
1772 {
1773  window.SetNeedRepaint(true);
1774 }
1775 
1782 {
1783  if (display_res)
1785 }
1786 
1799 {
1800  if (!display_res)
1801  return;
1802 
1803  if (!width || !height)
1804  {
1805  width = window.GetVideoDispDim().width();
1806  height = window.GetVideoDispDim().height();
1807  if (!width || !height)
1808  return;
1809  }
1810 
1811 #if 0
1812  // width and height should already be the properly cropped
1813  // versions, and therefore height should not need this manual
1814  // truncation. Delete this code if no problems crop up.
1815  if ((width == 1920 || width == 1440) && height == 1088)
1816  height = 1080; // ATSC 1920x1080
1817 #endif
1818 
1819  float rate = db_vdisp_profile ? db_vdisp_profile->GetOutput() : 0.0f;
1820  if (display_res && display_res->SwitchToVideo(width, height, rate))
1821  {
1822  // Switching to custom display resolution succeeded
1823  // Make a note of the new size
1827 
1828  bool fullscreen = !window.UsingGuiSize();
1829 
1830  // if width && height are zero users expect fullscreen playback
1831  if (!fullscreen)
1832  {
1833  int gui_width = 0, gui_height = 0;
1834  gCoreContext->GetResolutionSetting("Gui", gui_width, gui_height);
1835  fullscreen |= (0 == gui_width && 0 == gui_height);
1836  }
1837 
1838  if (fullscreen)
1839  {
1840  QSize sz(display_res->GetWidth(), display_res->GetHeight());
1841  const QRect display_visible_rect =
1842  QRect(GetMythMainWindow()->geometry().topLeft(), sz);
1843  window.SetDisplayVisibleRect(display_visible_rect);
1844  MoveResize();
1845  // Resize X window to fill new resolution
1846  MoveResizeWindow(display_visible_rect);
1847  }
1848  }
1849 }
1850 
1855 void VideoOutput::InitDisplayMeasurements(uint width, uint height, bool resize)
1856 {
1858  QString source = "Actual";
1859 
1860  // The very first Resize needs to be the maximum possible
1861  // desired res, because X will mask off anything outside
1862  // the initial dimensions
1863  QSize sz1 = disp.res;
1864  QSize sz2 = window.GetScreenGeometry().size();
1865  QSize max_size = sz1.expandedTo(sz2);
1866 
1867  if (window.UsingGuiSize())
1868  max_size = GetMythMainWindow()->geometry().size();
1869 
1870  if (display_res)
1871  {
1872  max_size.setWidth(display_res->GetMaxWidth());
1873  max_size.setHeight(display_res->GetMaxHeight());
1874  }
1875 
1876  if (resize)
1877  {
1878  MoveResizeWindow(QRect(GetMythMainWindow()->geometry().x(),
1879  GetMythMainWindow()->geometry().y(),
1880  max_size.width(), max_size.height()));
1881  }
1882 
1883  // get the physical dimensions (in mm) of the display. If using
1884  // DisplayRes, this will be overridden when we call ResizeForVideo
1885  if (db_display_dim.isEmpty())
1886  {
1887  window.SetDisplayDim(disp.size);
1888  }
1889  else
1890  {
1892  source = "Database";
1893  }
1894 
1895  // Set the display mode if required
1896  if (display_res)
1897  ResizeForVideo(width, height);
1898 
1899  // Determine window and screen dimensions in pixels
1900  QSize screen_size = window.GetScreenGeometry().size();
1901  QSize window_size = window.GetDisplayVisibleRect().size();
1902 
1903  float pixel_aspect = (float)screen_size.width() /
1904  (float)screen_size.height();
1905 
1906  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1907  QString("Pixel dimensions: Screen %1x%2, window %3x%4")
1908  .arg(screen_size.width()).arg(screen_size.height())
1909  .arg(window_size.width()).arg(window_size.height()));
1910 
1911  // Check the display dimensions
1912  QSize disp_dim = window.GetDisplayDim();
1913  float disp_aspect;
1914 
1915  // If we are using Xinerama the display dimensions cannot be trusted.
1916  // We need to use the Xinerama monitor aspect ratio from the DB to set
1917  // the physical screen width. This assumes the height is correct, which
1918  // is more or less true in the typical side-by-side monitor setup.
1919  if (window.UsingXinerama())
1920  {
1921  source = "Xinerama";
1922  disp_aspect = gCoreContext->GetFloatSettingOnHost(
1923  "XineramaMonitorAspectRatio",
1924  gCoreContext->GetHostName(), pixel_aspect);
1925  if (disp_dim.height() <= 0)
1926  disp_dim.setHeight(300);
1927  disp_dim.setWidth(lroundf(disp_dim.height() * disp_aspect));
1928  }
1929 
1930  if (disp_dim.isEmpty())
1931  {
1932  source = "Guessed!";
1933  LOG(VB_GENERAL, LOG_WARNING, LOC + "Physical size of display unknown."
1934  "\n\t\t\tAssuming 17\" monitor with square pixels.");
1935  disp_dim = QSize(lroundf(300 * pixel_aspect), 300);
1936  }
1937 
1938  disp_aspect = (float) disp_dim.width() / (float) disp_dim.height();
1939  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1940  QString("%1 display dimensions: %2x%3 mm Aspect: %4")
1941  .arg(source).arg(disp_dim.width()).arg(disp_dim.height())
1942  .arg(disp_aspect));
1943 
1944  // Save the unscaled size and dimensions for window resizing
1945  monitor_sz = screen_size;
1946  monitor_dim = disp_dim;
1947 
1948  // We must now scale the display measurements to our window size and save
1949  // them. If we are running fullscreen this is a no-op.
1950  disp_dim = QSize((disp_dim.width() * window_size.width()) /
1951  screen_size.width(),
1952  (disp_dim.height() * window_size.height()) /
1953  screen_size.height());
1954  disp_aspect = (float) disp_dim.width() / (float) disp_dim.height();
1955  window.SetDisplayDim(disp_dim);
1956  window.SetDisplayAspect(disp_aspect);
1957 
1958  // If we are using XRandR, use the aspect ratio from it
1959  if (display_res)
1961 
1962  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1963  QString("Estimated window dimensions: %1x%2 mm Aspect: %3")
1964  .arg(window.GetDisplayDim().width())
1965  .arg(window.GetDisplayDim().height())
1966  .arg(window.GetDisplayAspect()));
1967 }
1968 
1969 int VideoOutput::CalcHueBase(const QString &adaptor_name)
1970 {
1971  int hue_adj = 50;
1972 
1973  // XVideo adjustments
1974  if ((adaptor_name == "ATI Radeon Video Overlay") ||
1975  (adaptor_name == "XA G3D Textured Video") || /* ATI in VMWare*/
1976  (adaptor_name == "Radeon Textured Video") || /* ATI */
1977  (adaptor_name == "AMD Radeon AVIVO Video") || /* ATI */
1978  (adaptor_name == "XV_SWOV" /* VIA 10K & 12K */) ||
1979  (adaptor_name == "Savage Streams Engine" /* S3 Prosavage DDR-K */) ||
1980  (adaptor_name == "SIS 300/315/330 series Video Overlay") ||
1981  adaptor_name.toLower().contains("xvba") /* VAAPI */ ||
1982  adaptor_name.toLower().startsWith("intel i965 driver"))
1983  {
1984  hue_adj = 50;
1985  }
1986  else if (adaptor_name.startsWith("NV17")) /* nVidia */
1987  {
1988  hue_adj = 0;
1989  }
1990  else
1991  {
1992  LOG(VB_GENERAL, LOG_INFO, LOC +
1993  QString("CalcHueBase(%1): Unknown adaptor, hue may be wrong.")
1994  .arg(adaptor_name));
1995  LOG(VB_GENERAL, LOG_INFO, LOC +
1996  "Please open a ticket if you need to adjust the hue.");
1997  }
1998 
1999  return hue_adj;
2000 }
2001 
2003 {
2004  // TODO: support cropping in the horizontal dimension
2005  if (!frame)
2006  return;
2007  if (FMT_YV12 != frame->codec)
2008  return;
2009  if (frame->pitches[1] != frame->pitches[2])
2010  return;
2011  int crop = window.GetVideoDim().height() -
2012  window.GetVideoDispDim().height();
2013  if (crop <= 0 || crop >= 16)
2014  return; // something may be amiss, so don't crop
2015 
2016  uint64_t *ybuf = (uint64_t*) (frame->buf + frame->offsets[0]);
2017  uint64_t *ubuf = (uint64_t*) (frame->buf + frame->offsets[1]);
2018  uint64_t *vbuf = (uint64_t*) (frame->buf + frame->offsets[2]);
2019  const uint64_t Y_black = 0x0000000000000000LL; // 8 bytes
2020  const uint64_t UV_black = 0x8080808080808080LL; // 8 bytes
2021  int y;
2022  int sz = (frame->pitches[0] * frame->height) >> 3; // div 8 bytes
2023  // Luma bottom
2024  y = ((frame->height - crop) >> 4) * frame->pitches[0] << 1;
2025  y = y + (sz - y) * (16 - crop) / 16;
2026  for (; y < sz; y++)
2027  {
2028  ybuf[y] = Y_black;
2029  }
2030  // Chroma bottom
2031  sz = (frame->pitches[1] * (frame->height >> 1)) >> 3; // div 8 bytes
2032  y = ((frame->height - crop) >> 4) * frame->pitches[1];
2033  y = y + (sz - y) * (16 - crop) / 16;
2034  for (; y < sz; y++)
2035  {
2036  ubuf[y] = UV_black;
2037  vbuf[y] = UV_black;
2038  }
2039 }
virtual void ResizeForVideo(uint width=0, uint height=0)
Sets display parameters based on video resolution.
int pitches[3]
Y, U, & V pitches.
Definition: mythframe.h:63
void ToggleAspectOverride(AspectOverrideMode aspectOverrideMode=kAspect_Toggle)
Enforce different aspect ration than detected, then calls VideoAspectRatioChanged(float) to apply the...
virtual int SetPictureAttribute(PictureAttribute, int newValue)
Sets a specified picture attribute.
MythPainter * invalid_osd_painter
Definition: videooutbase.h:374
QString m_deintfiltername
Definition: videooutbase.h:351
float GetVideoAspect(void) const
Definition: mythplayer.h:175
unsigned char * pip_tmp_buf2
Definition: videooutbase.h:337
void SetDisplayAspect(float displayAspect)
A dummy video class that uses VDPAU to decode video frames.
virtual bool CanVisualise(AudioPlayer *audio, MythRender *render)
int GetMaxHeight(void) const
Returns maximum height in pixels supported by display.
Definition: DisplayRes.h:130
virtual void ResizeForGui(void)
If we are using DisplayRes support, return the screen size and refresh rate to those used for the GUI...
QMap< MythPlayer *, PIPLocation > PIPMap
Definition: videooutbase.h:37
bool UsingXinerama(void) const
void start(QRunnable *runnable, QString debugName, int priority=0)
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:91
virtual bool DisplayOSD(VideoFrame *frame, OSD *osd)
If the OSD has changed, this will convert the OSD buffer to the OSDSurface's color format.
QRect GetTotalOSDBounds(void) const
Returns total OSD bounds.
void DestroyVisualisation(void)
QString GetFilters(void) const
double GetAspectRatio(void) const
Returns current screen aspect ratio.
Definition: DisplayRes.h:119
virtual void ToggleAspectOverride(AspectOverrideMode aspectOverrideMode=kAspect_Toggle)
Enforce different aspect ration than detected, then calls VideoAspectRatioChanged(float) to apply the...
LetterBoxColour db_letterbox_colour
Definition: videooutbase.h:325
static bool isCodecDeinterlacer(QString decodername)
virtual bool IsBobDeint(void) const
MythImage * osd_image
Definition: videooutbase.h:372
virtual QString Name(void)=0
static int crop(VideoFilter *f, VideoFrame *frame, int field)
Definition: filter_crop.c:41
bool m_deinterlacing
Definition: videooutbase.h:350
virtual bool NeedsDoubleFramerate(void) const
Should Prepare() and Show() be called twice for every ProcessFrame().
virtual void DiscardFrames(bool kf)
Releases all frames not being actively displayed from any queue onto the queue of frames ready for de...
Definition: videooutbase.h:227
virtual void SetVideoFrameRate(float)
MythCodecID
Definition: mythcodecid.h:10
static bool CanVisualise(AudioPlayer *audio, MythRender *render)
Definition: videovisual.cpp:7
VideoColourSpace videoColourSpace
Definition: videooutbase.h:322
VideoOutput()
This constructor for VideoOutput must be followed by an Init(int,int,float,WId,int,...
#define ROUNDUP(_x, _z)
int DecrRef(void) override
Decrements reference count and deletes on 0.
Definition: mythimage.cpp:71
AdjustFillMode GetAdjustFill(void) const
Returns current adjust fill mode.
struct AVFrame AVFrame
static void GetRenderOptions(render_opts &opts, QStringList &cpudeints)
float GetOutput(void) const
QRect GetPIPRect(PIPLocation location, MythPlayer *pipplayer=nullptr, bool do_pixel_adj=true) const
QString GetFilteredDeint(const QString &override)
virtual bool IsExtraProcessingRequired(void) const
Should Prepare() and Show() and ProcessFrame be called twice for every Frameloop().
QRect GetVideoRect(void) const
static VideoVisual * Create(const QString &name, AudioPlayer *audio, MythRender *render)
Definition: videovisual.cpp:30
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 c_yuv888_to_yv12(VideoFrame *frame, MythImage *osd_image, int left, int top, int right, int bottom)
Definition: util-osd.cpp:236
virtual float GetDisplayAspect(void) const
Returns current display aspect ratio.
double GetFloatSettingOnHost(const QString &key, const QString &host, double defaultval=0.0)
QRect GetTotalOSDBounds(void) const
Returns total OSD bounds.
VideoFrame * GetCurrentFrame(int &w, int &h)
QString GetFallbackDeinterlacer(void) const
virtual void SaveBottomLine(void)
Save current Manual Zoom settings as BottomLine adjustment.
virtual void SetPIPState(PIPState setting)
static QString to_comma_list(const QStringList &list)
void CropToDisplay(VideoFrame *frame)
QSize db_display_dim
Screen dimensions in millimeters from DB.
Definition: videooutbase.h:321
unsigned int uint
Definition: compat.h:140
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
AspectOverrideMode GetAspectOverride(void) const
Returns current aspect override mode.
QRect GetMHEGBounds(void)
virtual void StopEmbedding(void)
Tells video output to stop embedding video in an existing window.
QSize pip_desired_display_size
Definition: videooutbase.h:333
enum FrameType_ VideoFrameType
QRect GetSafeRect(void)
Returns a QRect describing an area of the screen on which it is 'safe' to render the On Screen Displa...
virtual QString GetOSDRenderer(void) const
\ brief return OSD renderer type for this videoOutput
void waitForDone(void)
struct SwsContext * pip_scaling_context
Definition: videooutbase.h:338
static void Unlock(void)
Release any access restrictions.
Definition: DisplayRes.cpp:38
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
Generate a list of supported OpenGL profiles.
long long copy(QFile &dst, QFile &src, uint block_size)
Copies src file to dst file.
#define LOC
void SetOutput(float framerate)
VideoVisual * m_visual
Definition: videooutbase.h:377
VideoDisplayProfile * db_vdisp_profile
Definition: videooutbase.h:330
static guint32 * tmp
Definition: goom_core.c:35
void SetPIPState(PIPState setting)
unsigned char * pip_tmp_buf
Definition: videooutbase.h:336
void SetVideoScalingAllowed(bool change)
Disable or enable underscan/overscan.
void SetVideoDim(QSize dim)
QSize pip_display_size
Definition: videooutbase.h:334
bool AllowPreviewEPG(void) const
float GetDisplayAspect(void) const
Returns current display aspect ratio.
unsigned char r
Definition: ParseText.cpp:340
virtual void EmbedInWidget(const QRect &rect)
Tells video output to embed video in an existing window.
QSize vsz_video_size
Definition: videooutbase.h:345
virtual void ClearDummyFrame(VideoFrame *frame)
Clears the frame to black.
static QStringList GetDeinterlacers(const QString &video_renderer)
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:109
#define IMAGE_ALIGN
Definition: mythconfig.h:19
AdjustFillMode db_adjustfill
Definition: videooutbase.h:324
virtual void ShowPIPs(VideoFrame *frame, const PIPMap &pipPlayers)
int offsets[3]
Y, U, & V offsets.
Definition: mythframe.h:64
This class serves as the base class for all video output methods.
Definition: videooutbase.h:46
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id)
void ExposeEvent(void)
Tells video output that a full repaint is needed.
VideoFrame pip_tmp_image
Definition: videooutbase.h:339
AspectOverrideMode
Definition: videoouttypes.h:46
static int run(MythMediaDevice *dev=nullptr, bool startRandomShow=false)
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
QString GetFilters(void) const
static void CopyFrame(VideoFrame *to, const VideoFrame *from)
Copies frame data from one VideoFrame to another.
bool UsingGuiSize(void) const
int GetWidth(void) const
Returns current screen width in pixels.
Definition: DisplayRes.h:101
static QString GetBestVideoRenderer(const QStringList &renderers)
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refreshrate, int index=-1)
static void GetRenderOptions(render_opts &opts)
int AVPictureFill(AVFrame *pic, const VideoFrame *frame, AVPixelFormat fmt)
AVPictureFill Initialise AVFrame pic with content from VideoFrame frame.
Definition: mythavutil.cpp:65
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
bool IsPreviewEPGAllowed(void) const
static void GetRenderOptions(render_opts &opts)
static void show(uint8_t *buf, int length)
Definition: ringbuffer.c:335
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:830
void Clear(QPaintDevice *device, const QRegion &region) override
void ReleaseCurrentFrame(VideoFrame *frame)
void SaveBottomLine(void)
#define ALIGN_X_MMX
Definition: util-osd.h:10
static void GetRenderOptions(render_opts &opts)
int height
Definition: mythframe.h:42
QRect GetScreenGeometry(void) const
MythCodecID video_codec_id
Definition: videooutbase.h:329
QRect GetEmbeddingRect(void) const
bool SwitchToGUI(tmode which_gui=GUI)
Switches to the GUI resolution specified.
Definition: DisplayRes.cpp:188
static void GetRenderOptions(render_opts &opts)
QRegion Draw(MythPainter *painter, QPaintDevice *device, QSize size, QRegion &changed, int alignx=0, int aligny=0)
Definition: osd.cpp:786
QSize vsz_display_size
Definition: videooutbase.h:344
void DisableFade(void)
Definition: osd.h:147
virtual void BestDeint(void)
Change to the best deinterlacing method.
virtual void MoveResizeWindow(QRect new_rect)=0
void SetNeedRepaint(bool needRepaint)
bool IsVideoScalingAllowed(void) const
check if video underscan/overscan is allowed
QString GetVisualiserName(void)
int GetHeight(void) const
Returns current screen width in pixels.
Definition: DisplayRes.h:104
void SetVideoScalingAllowed(bool change)
Disable or enable underscan/overscan.
virtual void GetOSDBounds(QRect &total, QRect &visible, float &visibleAspect, float &fontScale, float themeAspect) const
FilterChain * LoadFilters(QString filters, VideoFrameType &inpixfmt, VideoFrameType &outpixfmt, int &width, int &height, int &bufsize, int max_threads=1)
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.
int ChangePictureAttribute(PictureAttribute, bool direction)
const FilterInfo * GetFilterInfo(const QString &name) const
void yuv888_to_i44(unsigned char *dest, MythImage *osd_image, QSize dst_size, int left, int top, int right, int bottom, bool ifirst)
Definition: util-osd.cpp:312
long long frameNumber
Definition: mythframe.h:48
void DoPipResize(int pipwidth, int pipheight)
Sets up Picture in Picture image resampler.
PictureAttribute
Definition: videoouttypes.h:89
bool EnableVisualisation(AudioPlayer *audio, bool enable, const QString &name=QString(""))
QRect vsz_desired_display_rect
Definition: videooutbase.h:343
QRect GetVisibleOSDBounds(float &, float &, float) const
Returns visible portions of total OSD bounds.
QSize GetVideoDispDim(void) const
int GetPhysicalHeight(void) const
Returns current screen height in millimeters.
Definition: DisplayRes.h:110
QRect GetDisplayVideoRect(void) const
int GetPictureAttribute(PictureAttribute)
void SetInput(const QSize &size, float framerate=0, const QString &codecName=QString())
bool IsVideoScalingAllowed(void) const
const char * name
Definition: ParseText.cpp:339
virtual void ResizeDisplayWindow(const QRect &, bool)
Resize Display Window.
void EmbedInWidget(const QRect &)
Tells video output to embed video in an existing window.
virtual void InitOSD(OSD *osd)
unsigned char * vsz_tmp_buf
Definition: videooutbase.h:346
void * av_malloc(unsigned int size)
bool vsz_enabled
Definition: videooutbase.h:342
QString GetActualVideoRenderer(void) const
static QString const kName
Definition: videoout_omx.h:30
void GetDeinterlacers(QStringList &deinterlacers)
virtual QStringList GetVisualiserList(void)
int GetPhysicalWidth(void) const
Returns current screen width in millimeters.
Definition: DisplayRes.h:107
static QStringList GetAllowedRenderers(MythCodecID, const QSize &)
static QStringList GetFilteredRenderers(const QString &decoder, const QStringList &renderers)
MythMainWindow * GetMythMainWindow(void)
PIPState GetPIPState(void) const
int myth2av_codecid(MythCodecID codec_id, bool &vdpau)
MythYUVAPainter * osd_painter
Definition: videooutbase.h:371
Supports common video output methods used with X11 Servers.
Definition: videoout_xv.h:28
DisplayRes * display_res
Definition: videooutbase.h:364
AdjustFillMode GetAdjustFill(void) const
Returns current adjust fill mode.
static void GetRenderOptions(render_opts &opts, QStringList &cpudeints)
virtual bool hasFullScreenOSD(void) const
Definition: videooutbase.h:309
void yuv888_to_yv12(VideoFrame *frame, MythImage *osd_image, int left, int top, int right, int bottom)
Definition: util-osd.cpp:16
PIPLocation
Definition: videoouttypes.h:19
static void GetRenderOptions(render_opts &opts, QStringList &cpudeints)
virtual void ToggleAdjustFill(AdjustFillMode adjustFillMode=kAdjustFill_Toggle)
Sets up letterboxing for various standard video frame and monitor dimensions, then calls MoveResize()...
AdjustFillMode
Definition: videoouttypes.h:57
virtual bool InputChanged(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, MythCodecID myth_codec_id, void *codec_private, bool &aspect_changed)
Tells video output to discard decoded frames and wait for new ones.
virtual void ShutdownVideoResize(void)
QRect GetImageRect(const QRect &rect, QRect *display=nullptr)
translates caption/dvd button rectangle into 'screen' space
int GetNumSetting(const QString &key, int defaultval=0)
static int CalcHueBase(const QString &adaptor_name)
void ResizeDisplayWindow(const QRect &, bool)
Resize Display Window.
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
virtual void ShowPIP(VideoFrame *frame, MythPlayer *pipplayer, PIPLocation loc)
Composites PiP image onto a video frame.
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
int64_t disp_timecode
Definition: mythframe.h:50
QSize monitor_dim
Definition: videooutbase.h:368
void DoVideoResize(const QSize &inDim, const QSize &outDim)
Sets up Picture in Picture image resampler.
virtual bool ApproveDeintFilter(const QString &filtername) const
Approves bobdeint filter for XVideo and otherwise defers to VideoOutput::ApproveDeintFilter(const QSt...
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
uint GetMaxCPUs(void) const
PIPState
Definition: videoouttypes.h:10
bool InputChanged(const QSize &input_size_buf, const QSize &input_size_disp, float aspect, MythCodecID myth_codec_id, void *codec_private)
Tells video output to discard decoded frames and wait for new ones.
static void GetRenderOptions(render_opts &opts, QStringList &cpudeints)
Definition: videoout_xv.cpp:80
QSize monitor_sz
Definition: videooutbase.h:367
QString GetOSDRenderer(void) const
virtual QRect GetPIPRect(PIPLocation location, MythPlayer *pipplayer=nullptr, bool do_pixel_adj=true) const
returns QRect of PIP based on PIPLocation
virtual void VideoAspectRatioChanged(float aspect)
Calls SetVideoAspectRatio(float aspect), then calls MoveResize() to apply changes.
virtual void Zoom(ZoomDirection direction)
Sets up zooming into to different parts of the video, the zoom is actually applied in MoveResize().
void ToggleMoveBottomLine(void)
QRect GetVisibleOSDBounds(float &, float &, float) const
Returns visible portions of total OSD bounds.
void ResizeVideo(VideoFrame *frame)
virtual void MoveResize(void)
performs all the calculations for video framing and any resizing.
float GetOverridenVideoAspect(void) const
void VideoAspectRatioChanged(float aspect)
Calls SetVideoAspectRatio(float aspect), then calls MoveResize() to apply changes.
QSize pip_video_size
Definition: videooutbase.h:335
static void GetRenderOptions(render_opts &opts)
static void GetRenderOptions(render_opts &opts, QStringList &cpudeints)
Generate the list of available OpenGL profiles.
void SetDisplayDim(QSize displayDim)
void MoveResize(void)
performs all the calculations for video framing and any resizing.
LetterBoxColour
Definition: videoouttypes.h:72
Definition: osd.h:132
float GetVideoAspect(void) const
void ConvertToYUV(void)
Definition: mythimage.cpp:452
bool IsEmbedding(void)
Returns if videooutput is embedding.
virtual void Draw(const QRect &area, MythPainter *painter, QPaintDevice *device)=0
bool Init(const QSize &new_video_dim_buf, const QSize &new_video_dim_disp, float aspect, const QRect &new_display_visible_rect, AspectOverrideMode aspectoverride, AdjustFillMode adjustfill)
QRect GetDisplayVisibleRect(void) const
FilterChain * m_deintFilter
Definition: videooutbase.h:353
void ShutdownPipResize(void)
Shuts down Picture in Picture image resampler.
QString GetVideoRenderer(void) const
QSize GetVideoDim(void) const
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
static VideoOutput * Create(const QString &decoder, MythCodecID codec_id, void *codec_priv, PIPState pipState, const QSize &video_dim_buf, const QSize &video_dim_disp, float video_aspect, QWidget *parentwidget, const QRect &embed_rect, float video_prate, uint playerFlags, QString &codecName)
Depending on compile-time configure settings and run-time renderer settings, create a relevant VideoO...
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id)
static uint buffersize(VideoFrameType type, int width, int height, int _aligned=64)
Definition: mythframe.h:291
QSize size
Definition: mythdisplay.h:18
bool IsOSDFadeEnabled(void) const
bool IsPIPVisible(void) const
Definition: mythplayer.h:229
VideoOutWindow window
Definition: videooutbase.h:320
void Assign(const QImage &img)
Definition: mythimage.cpp:96
static DisplayInfo GetDisplayInfo(int video_rate=0)
Definition: mythdisplay.cpp:44
int GetPictureAttribute(PictureAttribute attribute)
bool m_deinterlaceBeforeOSD
Definition: videooutbase.h:354
FilterManager * m_deintFiltMan
Definition: videooutbase.h:352
bool SwitchToVideo(int iwidth, int iheight, double frate=0.0)
Switches to the resolution and refresh rate defined in the database for the specified video resolutio...
Definition: DisplayRes.cpp:126
void ToggleAdjustFill(AdjustFillMode adjustFillMode=kAdjustFill_Toggle)
Sets up letterboxing for various standard video frame and monitor dimensions, then calls MoveResize()...
#define ALIGN_C
Definition: util-osd.h:8
void SetVideoResize(const QRect &videoRect)
Tells the player to resize the video frame (used for ITV)
virtual void ToggleMoveBottomLine(void)
AspectOverrideMode db_aspectoverride
Definition: videooutbase.h:323
MythImage * GetFormatImage()
Returns a blank reference counted image in the format required for the Draw functions for this painte...
QString GetHostName(void)
virtual bool SetupDeinterlace(bool interlaced, const QString &overridefilter="")
Attempts to enable or disable deinterlacing.
unsigned char * buf
Definition: mythframe.h:39
ZoomDirection
Definition: videoouttypes.h:28
virtual bool SetupVisualisation(AudioPlayer *audio, MythRender *render, const QString &name)
virtual ~VideoOutput()
Shuts down video output.
void StopEmbedding(void)
Tells video output to stop embedding video in an existing window.
AspectOverrideMode GetAspectOverride(void) const
Returns current aspect override mode.
virtual bool SetDeinterlacingEnabled(bool)
Attempts to enable/disable deinterlacing using existing deinterlace method when enabling.
void SetDisplayVisibleRect(QRect rect)
struct SwsContext * vsz_scale_context
Definition: videooutbase.h:347
virtual void FallbackDeint(void)
Fallback to non-frame-rate-doubling deinterlacing method.
void Zoom(ZoomDirection direction)
Sets up zooming into to different parts of the video, the zoom is actually applied in MoveResize().
int SetPictureAttribute(PictureAttribute attribute, int value)
bool IsDecoderCompatible(const QString &decoder)
bool IsPIPActive(void) const
Definition: mythplayer.h:228
virtual void DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
Informs video output of new data for frame, used for hardware accelerated decoding.
int GetMaxWidth(void) const
Returns maximum width in pixels supported by display.
Definition: DisplayRes.h:128
QSize GetDisplayDim(void) const
VideoFrameType codec
Definition: mythframe.h:38