MythTV  master
mythvdpauhelper.cpp
Go to the documentation of this file.
1 // MythTV
3 #include "mythvideocolourspace.h"
4 #include "mythvdpauhelper.h"
5 #include "libmythui/platforms/mythxdisplay.h" // always last
6 
7 // Std
8 #include <cmath>
9 
10 #define LOC QString("VDPAUHelp: ")
11 
12 #define INIT_ST \
13 VdpStatus status; \
14 bool ok = true;
15 
16 // NOLINTBEGIN(cppcoreguidelines-macro-usage)
17 #define CHECK_ST \
18 ok &= (status == VDP_STATUS_OK); \
19 if (!ok) \
20 { \
21  LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("Error at %1:%2 (#%3, %4)") \
22  .arg(__FILE__).arg( __LINE__).arg(status) \
23  .arg(m_vdpGetErrorString(status))); \
24 }
25 
26 #define GET_PROC(FUNC_ID, PROC) \
27 status = m_vdpGetProcAddress(m_device, FUNC_ID, reinterpret_cast<void **>(&(PROC))); CHECK_ST
28 // NOLINTEND(cppcoreguidelines-macro-usage)
29 
30 VDPAUCodec::VDPAUCodec(MythCodecContext::CodecProfile Profile, QSize Size, uint32_t Macroblocks, uint32_t Level)
31  : m_maxSize(Size),
32  m_maxMacroBlocks(Macroblocks),
33  m_maxLevel(Level)
34 {
35  // Levels don't work for MPEG1/2
36  if (MythCodecContext::MPEG1 <= Profile && Profile <= MythCodecContext::MPEG2SNR)
37  m_maxLevel = 1000;
38 }
39 
40 bool VDPAUCodec::Supported(int Width, int Height, int Level) const
41 {
42  // Note - level checks are now ignored here and in FFmpeg
43  uint32_t macros = static_cast<uint32_t>(((Width + 15) & ~15) * ((Height + 15) & ~15)) / 256;
44  bool result = (Width <= m_maxSize.width()) && (Height <= m_maxSize.height()) &&
45  (macros <= m_maxMacroBlocks) /*&& (static_cast<uint32_t>(Level) <= m_maxLevel)*/;
46  if (!result)
47  {
48  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Not supported: Size %1x%2 > %3x%4, MBs %5 > %6, Level %7 > %8")
49  .arg(Width).arg(Height).arg(m_maxSize.width()).arg(m_maxSize.height())
50  .arg(macros).arg(m_maxMacroBlocks).arg(Level).arg(m_maxLevel));
51  }
52  return result;
53 }
54 
55 bool MythVDPAUHelper::HaveVDPAU(bool Reinit /*=false*/)
56 {
57  static QMutex s_mutex;
58  static bool s_checked = false;
59  static bool s_available = false;
60 
61  QMutexLocker locker(&s_mutex);
62  if (s_checked && !Reinit)
63  return s_available;
64 
65  {
66  MythVDPAUHelper vdpau;
67  s_available = vdpau.IsValid();
68  }
69 
70  s_checked = true;
71  if (s_available)
72  {
73  LOG(VB_GENERAL, LOG_INFO, LOC + "Supported/available VDPAU decoders:");
74  const VDPAUProfiles& profiles = MythVDPAUHelper::GetProfiles();
75  for (const auto& profile : qAsConst(profiles))
76  LOG(VB_GENERAL, LOG_INFO, LOC +
78  }
79  else
80  {
81  LOG(VB_GENERAL, LOG_INFO, LOC + "VDPAU is NOT available");
82  }
83  return s_available;
84 }
85 
86 bool MythVDPAUHelper::ProfileCheck(VdpDecoderProfile Profile, uint32_t &Level,
87  uint32_t &Macros, uint32_t &Width, uint32_t &Height)
88 {
89  if (!m_device)
90  return false;
91 
92  INIT_ST
93  VdpBool supported = VDP_FALSE;
94  status = m_vdpDecoderQueryCapabilities(m_device, Profile, &supported,
95  &Level, &Macros, &Width, &Height);
96  CHECK_ST
97 
98  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("ProfileCheck: Prof %1 Supp %2 Level %3 Macros %4 Width %5 Height %6 Status %7")
99  .arg(Profile).arg(supported).arg(Level).arg(Macros).arg(Width).arg(Height).arg(status));
100 
101  if (((supported != VDP_TRUE) || (status != VDP_STATUS_OK)) &&
102  (Profile == VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE ||
103  Profile == VDP_DECODER_PROFILE_H264_BASELINE))
104  {
105  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Driver does not report support for H264 %1Baseline")
106  .arg(Profile == VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE ? "Constrained " : ""));
107 
108  // H264 Constrained baseline is reported as not supported on older chipsets but
109  // works due to support for H264 Main. Test for H264 main if constrained baseline
110  // fails - which mimics the fallback in FFmpeg.
111  // Updated to included baseline... not so sure about that:)
112  status = m_vdpDecoderQueryCapabilities(m_device, VDP_DECODER_PROFILE_H264_MAIN, &supported,
113  &Level, &Macros, &Width, &Height);
114  CHECK_ST
115  if (supported == VDP_TRUE)
116  LOG(VB_GENERAL, LOG_INFO, LOC + "... but assuming available as H264 Main is supported");
117  }
118 
119  return supported == VDP_TRUE;
120 }
121 
123 {
124  static const std::array<const VdpDecoderProfile,15> MainProfiles
125  {
126  VDP_DECODER_PROFILE_MPEG1, VDP_DECODER_PROFILE_MPEG2_SIMPLE, VDP_DECODER_PROFILE_MPEG2_MAIN,
127  VDP_DECODER_PROFILE_MPEG4_PART2_SP, VDP_DECODER_PROFILE_MPEG4_PART2_ASP,
128  VDP_DECODER_PROFILE_VC1_SIMPLE, VDP_DECODER_PROFILE_VC1_MAIN, VDP_DECODER_PROFILE_VC1_ADVANCED,
129  VDP_DECODER_PROFILE_H264_BASELINE, VDP_DECODER_PROFILE_H264_MAIN, VDP_DECODER_PROFILE_H264_HIGH,
130  VDP_DECODER_PROFILE_H264_EXTENDED, VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE,
131  VDP_DECODER_PROFILE_H264_CONSTRAINED_HIGH, VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
132  };
133 
134  static const std::array<const VdpDecoderProfile,4> HEVCProfiles
135  {
136  VDP_DECODER_PROFILE_HEVC_MAIN, VDP_DECODER_PROFILE_HEVC_MAIN_10,
137  VDP_DECODER_PROFILE_HEVC_MAIN_STILL, VDP_DECODER_PROFILE_HEVC_MAIN_444
138  };
139 
140  auto VDPAUToMythProfile = [](VdpDecoderProfile Profile)
141  {
142  switch (Profile)
143  {
144  case VDP_DECODER_PROFILE_MPEG1: return MythCodecContext::MPEG1;
145  case VDP_DECODER_PROFILE_MPEG2_SIMPLE: return MythCodecContext::MPEG2Simple;
146  case VDP_DECODER_PROFILE_MPEG2_MAIN: return MythCodecContext::MPEG2Main;
147 
148  case VDP_DECODER_PROFILE_MPEG4_PART2_SP: return MythCodecContext::MPEG4Simple;
149  case VDP_DECODER_PROFILE_MPEG4_PART2_ASP: return MythCodecContext::MPEG4AdvancedSimple;
150 
151  case VDP_DECODER_PROFILE_VC1_SIMPLE: return MythCodecContext::VC1Simple;
152  case VDP_DECODER_PROFILE_VC1_MAIN: return MythCodecContext::VC1Main;
153  case VDP_DECODER_PROFILE_VC1_ADVANCED: return MythCodecContext::VC1Advanced;
154 
155  case VDP_DECODER_PROFILE_H264_BASELINE: return MythCodecContext::H264Baseline;
156  case VDP_DECODER_PROFILE_H264_MAIN: return MythCodecContext::H264Main;
157  case VDP_DECODER_PROFILE_H264_HIGH: return MythCodecContext::H264High;
158  case VDP_DECODER_PROFILE_H264_EXTENDED: return MythCodecContext::H264Extended;
159  case VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE: return MythCodecContext::H264ConstrainedBaseline;
160  case VDP_DECODER_PROFILE_H264_CONSTRAINED_HIGH: return MythCodecContext::H264ConstrainedHigh;
161  case VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE: return MythCodecContext::H264High444; // ?
162 
163  case VDP_DECODER_PROFILE_HEVC_MAIN: return MythCodecContext::HEVCMain;
164  case VDP_DECODER_PROFILE_HEVC_MAIN_10: return MythCodecContext::HEVCMain10;
165  case VDP_DECODER_PROFILE_HEVC_MAIN_STILL: return MythCodecContext::HEVCMainStill;
166  case VDP_DECODER_PROFILE_HEVC_MAIN_444: return MythCodecContext::HEVCRext;
167  }
169  };
170 
171 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
172  static QMutex lock(QMutex::Recursive);
173 #else
174  static QRecursiveMutex lock;
175 #endif
176  static bool s_initialised = false;
177  static VDPAUProfiles s_profiles;
178 
179  QMutexLocker locker(&lock);
180  if (s_initialised)
181  return s_profiles;
182  s_initialised = true;
183 
184  MythVDPAUHelper helper;
185  if (!helper.IsValid())
186  return s_profiles;
187 
188  uint32_t level = 0;
189  uint32_t macros = 0;
190  uint32_t width = 0;
191  uint32_t height = 0;
192  for (VdpDecoderProfile profile : MainProfiles)
193  {
194  if (helper.ProfileCheck(profile, level, macros, width, height))
195  {
196  MythCodecContext::CodecProfile prof = VDPAUToMythProfile(profile);
197  s_profiles.emplace_back(prof,
198  VDPAUCodec(prof, QSize(static_cast<int>(width), static_cast<int>(height)), macros, level));
199  }
200  }
201 
202  if (helper.HEVCSupported())
203  {
204  for (VdpDecoderProfile profile : HEVCProfiles)
205  {
206  if (helper.ProfileCheck(profile, level, macros, width, height))
207  {
208  MythCodecContext::CodecProfile prof = VDPAUToMythProfile(profile);
209  s_profiles.emplace_back(prof,
210  VDPAUCodec(prof, QSize(static_cast<int>(width), static_cast<int>(height)), macros, level));
211  }
212  }
213  }
214 
215  return s_profiles;
216 }
217 
218 void MythVDPAUHelper::GetDecoderList(QStringList &Decoders)
219 {
220  const VDPAUProfiles& profiles = MythVDPAUHelper::GetProfiles();
221  if (profiles.empty())
222  return;
223 
224  Decoders.append("VDPAU:");
225  for (const auto& profile : qAsConst(profiles))
226  if (profile.first != MythCodecContext::MJPEG)
227  Decoders.append(MythCodecContext::GetProfileDescription(profile.first, profile.second.m_maxSize));
228 }
229 
230 static void vdpau_preemption_callback(VdpDevice /*unused*/, void* Opaque)
231 {
232  auto* helper = static_cast<MythVDPAUHelper*>(Opaque);
233  if (helper)
234  helper->SetPreempted();
235 }
236 
240 MythVDPAUHelper::MythVDPAUHelper(AVVDPAUDeviceContext* Context)
241  : m_device(Context->device),
242  m_vdpGetProcAddress(Context->get_proc_address)
243 {
244  m_valid = InitProcs();
245  if (m_valid)
246  {
247  INIT_ST
249  CHECK_ST
250  if (!ok)
251  LOG(VB_PLAYBACK, LOG_ERR, LOC + "Failed to register preemption callback");
252  }
253 }
254 
255 static const char* DummyGetError(VdpStatus /*status*/)
256 {
257  return "Unknown";
258 }
259 
261  : m_createdDevice(true)
262 {
264  if (!m_display)
265  return;
266 
267  INIT_ST
269  m_display->Lock();
270  status = vdp_device_create_x11(m_display->GetDisplay(),
271  m_display->GetScreen(),
273  m_display->Unlock();
274  CHECK_ST
275  if (!ok)
276  {
277  LOG(VB_PLAYBACK, LOG_ERR, LOC + "Failed to create VDPAU device.");
278  return;
279  }
280  m_valid = InitProcs();
281 }
282 
284 {
286  m_vdpPreemptionCallbackRegister(m_device, nullptr, nullptr);
289  delete m_display;
290 }
291 
293 {
294  INIT_ST
295  GET_PROC(VDP_FUNC_ID_GET_ERROR_STRING, m_vdpGetErrorString)
296  if (!ok)
297  {
299  ok = true;
300  }
301  GET_PROC(VDP_FUNC_ID_GET_INFORMATION_STRING, m_vdpGetInformationString)
302  GET_PROC(VDP_FUNC_ID_DEVICE_DESTROY, m_vdpDeviceDestroy)
303  GET_PROC(VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, m_vdpDecoderQueryCapabilities)
304  GET_PROC(VDP_FUNC_ID_DECODER_CREATE, m_vdpDecoderCreate)
305  GET_PROC(VDP_FUNC_ID_DECODER_DESTROY, m_vdpDecoderDestroy)
306  GET_PROC(VDP_FUNC_ID_VIDEO_MIXER_CREATE, m_vdpVideoMixerCreate)
307  GET_PROC(VDP_FUNC_ID_VIDEO_MIXER_DESTROY, m_vdpVideoMixerDestroy)
308  GET_PROC(VDP_FUNC_ID_VIDEO_MIXER_RENDER, m_vdpVideoMixerRender)
309  GET_PROC(VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES, m_vdpVideoMixerSetAttributeValues)
310  GET_PROC(VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES, m_vdpVideoMixerSetFeatureEnables)
311  GET_PROC(VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT, m_vdpVideoMixerQueryFeatureSupport)
312  GET_PROC(VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT, m_vdpVideoMixerQueryAttributeSupport)
313  GET_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_CREATE, m_vdpOutputSurfaceCreate)
314  GET_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY, m_vdpOutputSurfaceDestroy)
315  GET_PROC(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, m_vdpVideoSurfaceGetParameters)
316  GET_PROC(VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, m_vdpPreemptionCallbackRegister)
317 
318  return ok;
319 }
320 
321 bool MythVDPAUHelper::IsValid(void) const
322 {
323  return m_valid;
324 }
325 
327 {
328  emit DisplayPreempted();
329 }
330 
332 {
333  if (!m_valid)
334  return false;
335 
336  // FFmpeg will disallow HEVC VDPAU for driver versions < 410
337  const char* infostring = nullptr;
338  INIT_ST
339  status = m_vdpGetInformationString(&infostring);
340  CHECK_ST
341  if (!ok || !infostring)
342  return false;
343 
344  if (!QString(infostring).contains("NVIDIA", Qt::CaseInsensitive))
345  return true;
346 
347  int driver = 0;
348  sscanf(infostring, "NVIDIA VDPAU Driver Shared Library %d", &driver);
349  return !(driver < 410);
350 }
351 
352 bool MythVDPAUHelper::CheckH264Decode(AVCodecContext *Context)
353 {
354  if (!Context)
355  return false;
356 
357  int mbs = static_cast<int>(ceil(static_cast<double>(Context->width) / 16.0));
358  if (mbs != 49 && mbs != 54 && mbs != 59 && mbs != 64 &&
359  mbs != 113 && mbs != 118 &&mbs != 123 && mbs != 128)
360  {
361  return true;
362  }
363 
364  VdpDecoderProfile profile = 0;
365  switch (Context->profile & ~FF_PROFILE_H264_INTRA)
366  {
367  case FF_PROFILE_H264_BASELINE: profile = VDP_DECODER_PROFILE_H264_BASELINE; break;
368  case FF_PROFILE_H264_CONSTRAINED_BASELINE: profile = VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE; break;
369  case FF_PROFILE_H264_MAIN: profile = VDP_DECODER_PROFILE_H264_MAIN; break;
370  case FF_PROFILE_H264_HIGH: profile = VDP_DECODER_PROFILE_H264_HIGH; break;
371 #ifdef VDP_DECODER_PROFILE_H264_EXTENDED
372  case FF_PROFILE_H264_EXTENDED: profile = VDP_DECODER_PROFILE_H264_EXTENDED; break;
373 #endif
374  case FF_PROFILE_H264_HIGH_10: profile = VDP_DECODER_PROFILE_H264_HIGH; break;
375 #ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
376  case FF_PROFILE_H264_HIGH_422:
377  case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
378  case FF_PROFILE_H264_CAVLC_444: profile = VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE; break;
379 #endif
380  default: return false;
381  }
382 
383  // Create an instance
384  MythVDPAUHelper helper;
385  if (helper.IsValid())
386  return helper.H264DecodeCheck(profile, Context);
387  return false;
388 }
389 
390 bool MythVDPAUHelper::H264DecodeCheck(VdpDecoderProfile Profile, AVCodecContext *Context)
391 {
392  if (!m_valid || !Context)
393  return false;
394 
395  INIT_ST
396  VdpDecoder tmp = 0;
397  status = m_vdpDecoderCreate(m_device, Profile, static_cast<uint>(Context->width),
398  static_cast<uint>(Context->height), 2, &tmp);
399  CHECK_ST
400  if (tmp)
402  if (!ok)
403  {
404  LOG(VB_GENERAL, LOG_INFO, LOC + QString("No H264 decoder support for %1x%2")
405  .arg(Context->width).arg(Context->height));
406  }
407  return ok;
408 }
409 
410 VdpOutputSurface MythVDPAUHelper::CreateOutputSurface(QSize Size)
411 {
412  if (!m_valid)
413  return 0;
414 
415  VdpOutputSurface result = 0;
416  INIT_ST
417  status = m_vdpOutputSurfaceCreate(m_device, VDP_RGBA_FORMAT_B8G8R8A8,
418  static_cast<uint>(Size.width()),
419  static_cast<uint>(Size.height()), &result);
420  CHECK_ST
421  return result;
422 }
423 
425 {
426  if (!Surface)
427  return;
428 
429  INIT_ST
431  CHECK_ST
432 }
433 
434 VdpVideoMixer MythVDPAUHelper::CreateMixer(QSize Size, VdpChromaType ChromaType,
435  MythDeintType Deinterlacer)
436 {
437  if (!m_valid || Size.isEmpty())
438  return 0;
439 
440  VdpVideoMixer result = 0;
441 
442  static const std::array<const VdpVideoMixerParameter,3> parameters {
443  VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
444  VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
445  VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE
446  };
447 
448 
449  uint width = static_cast<uint>(Size.width());
450  uint height = static_cast<uint>(Size.height());
451  std::array<void const *,3> parametervalues { &width, &height, &ChromaType};
452 
453  uint32_t featurecount = 0;
454  std::array<VdpVideoMixerFeature,2> features {};
455  VdpBool enable = VDP_TRUE;
456  const std::array<VdpBool,2> enables = { enable, enable };
457 
458  if (DEINT_MEDIUM == Deinterlacer || DEINT_HIGH == Deinterlacer)
459  {
460  features[featurecount] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL;
461  featurecount++;
462  }
463 
464  if (DEINT_HIGH== Deinterlacer)
465  {
466  features[featurecount] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL;
467  featurecount++;
468  }
469 
470  INIT_ST
471  status = m_vdpVideoMixerCreate(m_device, featurecount, featurecount ? features.data() : nullptr,
472  3, parameters.data(), parametervalues.data(), &result);
473  CHECK_ST
474 
475  if (!ok || !result)
476  {
477  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create video mixer");
478  return result;
479  }
480 
481  if (featurecount)
482  {
483  status = m_vdpVideoMixerSetFeatureEnables(result, featurecount, features.data(), enables.data());
484  CHECK_ST
485  }
486  return result;
487 }
488 
489 void MythVDPAUHelper::MixerRender(VdpVideoMixer Mixer, VdpVideoSurface Source,
490  VdpOutputSurface Dest, FrameScanType Scan, int TopFieldFirst,
491  QVector<AVBufferRef*>& Frames)
492 {
493  if (!m_valid || !Mixer || !Source || !Dest)
494  return;
495 
496  VdpVideoMixerPictureStructure field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
497  if (kScan_Interlaced == Scan)
498  {
499  field = TopFieldFirst ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD :
500  VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
501  }
502  else if (kScan_Intr2ndField == Scan)
503  {
504  field = TopFieldFirst ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD :
505  VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
506  }
507 
508  int count = Frames.size();
509  if ((count < 1) || (field == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME))
510  {
511  INIT_ST
512  status = m_vdpVideoMixerRender(Mixer, VDP_INVALID_HANDLE, nullptr, field,
513  0, nullptr, Source, 0, nullptr, nullptr, Dest, nullptr, nullptr, 0, nullptr);
514  CHECK_ST
515  }
516  else
517  {
518  std::array<VdpVideoSurface,2> past = { VDP_INVALID_HANDLE, VDP_INVALID_HANDLE };
519  std::array<VdpVideoSurface,1> future = { VDP_INVALID_HANDLE };
520 
521  auto next = static_cast<VdpVideoSurface>(reinterpret_cast<uintptr_t>(Frames[0]->data));
522  auto current = static_cast<VdpVideoSurface>(reinterpret_cast<uintptr_t>(Frames[count > 1 ? 1 : 0]->data));
523  auto last = static_cast<VdpVideoSurface>(reinterpret_cast<uintptr_t>(Frames[count > 2 ? 2 : 0]->data));
524 
525  if (field == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD)
526  {
527  future[0] = current;
528  past[0] = past[1] = last;
529  }
530  else
531  {
532  future[0] = next;
533  past[0] = current;
534  past[1] = last;
535  }
536 
537  INIT_ST
538  status = m_vdpVideoMixerRender(Mixer, VDP_INVALID_HANDLE, nullptr, field,
539  2, past.data(), current, 1, future.data(),
540  nullptr, Dest, nullptr, nullptr, 0, nullptr);
541  CHECK_ST
542  }
543 }
544 
545 void MythVDPAUHelper::DeleteMixer(VdpVideoMixer Mixer)
546 {
547  if (!Mixer)
548  return;
549 
550  INIT_ST
551  status = m_vdpVideoMixerDestroy(Mixer);
552  CHECK_ST
553 }
554 
555 void MythVDPAUHelper::SetCSCMatrix(VdpVideoMixer Mixer, MythVideoColourSpace *ColourSpace)
556 {
557  if (!Mixer || !ColourSpace)
558  return;
559 
560  VdpVideoMixerAttribute attr = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX };
561  void const* val = { ColourSpace->data() };
562 
563  INIT_ST
564  status = m_vdpVideoMixerSetAttributeValues(Mixer, 1, &attr, &val);
565  CHECK_ST
566 }
567 
569 {
570  if (!m_valid)
571  return false;
572 
573  INIT_ST
574  auto supported = static_cast<VdpBool>(false);
575  status = m_vdpVideoMixerQueryFeatureSupport(m_device, Feature, &supported);
576  CHECK_ST
577  return ok && static_cast<bool>(supported);
578 }
579 
581 {
582  if (!m_valid)
583  return false;
584 
585  INIT_ST
586  auto supported = static_cast<VdpBool>(false);
587  status = m_vdpVideoMixerQueryAttributeSupport(m_device, Attribute, &supported);
588  CHECK_ST
589  return ok && static_cast<bool>(supported);
590 }
591 
592 QSize MythVDPAUHelper::GetSurfaceParameters(VdpVideoSurface Surface, VdpChromaType &Chroma)
593 {
594  if (!Surface)
595  return {};
596 
597  uint width = 0;
598  uint height = 0;
599  INIT_ST
600  status = m_vdpVideoSurfaceGetParameters(Surface, &Chroma, &width, &height);
601  CHECK_ST
602 
603  return {static_cast<int>(width), static_cast<int>(height)};
604 }
MythCodecContext::VC1Simple
@ VC1Simple
Definition: mythcodeccontext.h:105
INIT_ST
#define INIT_ST
Definition: mythvdpauhelper.cpp:12
MythCodecContext::MPEG4Simple
@ MPEG4Simple
Definition: mythcodeccontext.h:69
MythVDPAUHelper::GetProfiles
static const VDPAUProfiles & GetProfiles(void)
Definition: mythvdpauhelper.cpp:122
MythVDPAUHelper::m_vdpVideoMixerQueryAttributeSupport
VdpVideoMixerQueryAttributeSupport * m_vdpVideoMixerQueryAttributeSupport
Definition: mythvdpauhelper.h:118
MythVDPAUHelper::~MythVDPAUHelper
~MythVDPAUHelper(void) override
Definition: mythvdpauhelper.cpp:283
MythVDPAUHelper::m_vdpVideoMixerQueryFeatureSupport
VdpVideoMixerQueryFeatureSupport * m_vdpVideoMixerQueryFeatureSupport
Definition: mythvdpauhelper.h:117
MythCodecContext::H264Baseline
@ H264Baseline
Definition: mythcodeccontext.h:87
MythXDisplay::Lock
void Lock()
Definition: mythxdisplay.h:32
MythCodecContext::MPEG2Simple
@ MPEG2Simple
Definition: mythcodeccontext.h:62
DEINT_MEDIUM
@ DEINT_MEDIUM
Definition: mythframe.h:71
MythVDPAUHelper::m_vdpOutputSurfaceDestroy
VdpOutputSurfaceDestroy * m_vdpOutputSurfaceDestroy
Definition: mythvdpauhelper.h:120
MythCodecContext::VC1Advanced
@ VC1Advanced
Definition: mythcodeccontext.h:108
MythVDPAUHelper::m_vdpDecoderQueryCapabilities
VdpDecoderQueryCapabilities * m_vdpDecoderQueryCapabilities
Definition: mythvdpauhelper.h:109
MythXDisplay::GetDisplay
Display * GetDisplay()
Definition: mythxdisplay.h:29
VDPAUCodec::m_maxSize
QSize m_maxSize
Definition: mythvdpauhelper.h:41
MythVDPAUHelper::SetCSCMatrix
void SetCSCMatrix(VdpVideoMixer Mixer, MythVideoColourSpace *ColourSpace)
Definition: mythvdpauhelper.cpp:555
MythCodecContext::HEVCMain10
@ HEVCMain10
Definition: mythcodeccontext.h:99
VDPAUCodec::m_maxMacroBlocks
uint32_t m_maxMacroBlocks
Definition: mythvdpauhelper.h:42
VDPAUProfiles
std::vector< VDPAUProfile > VDPAUProfiles
Definition: mythvdpauhelper.h:47
MythXDisplay::GetScreen
int GetScreen() const
Definition: mythxdisplay.h:31
MythCodecContext::NoProfile
@ NoProfile
Definition: mythcodeccontext.h:59
MythCodecContext::MPEG4AdvancedSimple
@ MPEG4AdvancedSimple
Definition: mythcodeccontext.h:84
VDPAUCodec::m_maxLevel
uint32_t m_maxLevel
Definition: mythvdpauhelper.h:43
MythCodecContext::CodecProfile
CodecProfile
Definition: mythcodeccontext.h:57
MythVDPAUHelper::m_vdpGetErrorString
VdpGetErrorString * m_vdpGetErrorString
Definition: mythvdpauhelper.h:106
MythVDPAUHelper::MythVDPAUHelper
MythVDPAUHelper(void)
Definition: mythvdpauhelper.cpp:260
MythCodecContext::HEVCRext
@ HEVCRext
Definition: mythcodeccontext.h:101
MythCodecContext::VC1Main
@ VC1Main
Definition: mythcodeccontext.h:106
Surface
Definition: surface.h:4
FrameScanType
FrameScanType
Definition: videoouttypes.h:94
MythVDPAUHelper::HaveVDPAU
static bool HaveVDPAU(bool Reinit=false)
Definition: mythvdpauhelper.cpp:55
MythVDPAUHelper::m_valid
bool m_valid
Definition: mythvdpauhelper.h:100
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythVDPAUHelper::m_vdpVideoMixerDestroy
VdpVideoMixerDestroy * m_vdpVideoMixerDestroy
Definition: mythvdpauhelper.h:113
MythVDPAUHelper::IsFeatureAvailable
bool IsFeatureAvailable(uint Feature)
Definition: mythvdpauhelper.cpp:568
MythVDPAUHelper::IsAttributeAvailable
bool IsAttributeAvailable(uint Attribute)
Definition: mythvdpauhelper.cpp:580
MythVDPAUHelper::CreateOutputSurface
VdpOutputSurface CreateOutputSurface(QSize Size)
Definition: mythvdpauhelper.cpp:410
MythCodecContext::HEVCMainStill
@ HEVCMainStill
Definition: mythcodeccontext.h:100
MythVDPAUHelper::InitProcs
bool InitProcs(void)
Definition: mythvdpauhelper.cpp:292
MythCodecContext::H264Extended
@ H264Extended
Definition: mythcodeccontext.h:93
MythCodecContext::H264ConstrainedBaseline
@ H264ConstrainedBaseline
Definition: mythcodeccontext.h:88
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
true
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:95
MythXDisplay::OpenMythXDisplay
static MythXDisplay * OpenMythXDisplay(bool Warn=true)
Definition: mythxdisplay.cpp:25
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
MythVDPAUHelper::m_createdDevice
bool m_createdDevice
Definition: mythvdpauhelper.h:101
MythVDPAUHelper::DeleteOutputSurface
void DeleteOutputSurface(VdpOutputSurface Surface)
Definition: mythvdpauhelper.cpp:424
mythvideocolourspace.h
kScan_Intr2ndField
@ kScan_Intr2ndField
Definition: videoouttypes.h:99
CHECK_ST
#define CHECK_ST
Definition: mythvdpauhelper.cpp:17
MythVDPAUHelper::m_display
MythXDisplay * m_display
Definition: mythvdpauhelper.h:103
mythlogging.h
LOC
#define LOC
Definition: mythvdpauhelper.cpp:10
MythVDPAUHelper::GetDecoderList
static void GetDecoderList(QStringList &Decoders)
Definition: mythvdpauhelper.cpp:218
hardwareprofile.scan.profile
profile
Definition: scan.py:99
Source
Definition: channelsettings.cpp:93
mythvdpauhelper.h
MythVDPAUHelper::DisplayPreempted
void DisplayPreempted(void)
MythCodecContext::MPEG2SNR
@ MPEG2SNR
Definition: mythcodeccontext.h:67
MythVDPAUHelper::SetPreempted
void SetPreempted(void)
Definition: mythvdpauhelper.cpp:326
vdpau_preemption_callback
static void vdpau_preemption_callback(VdpDevice, void *Opaque)
Definition: mythvdpauhelper.cpp:230
MythVDPAUHelper
A simple wrapper around VDPAU functionality.
Definition: mythvdpauhelper.h:49
MythCodecContext::H264Main
@ H264Main
Definition: mythcodeccontext.h:89
MythVDPAUHelper::m_vdpVideoMixerRender
VdpVideoMixerRender * m_vdpVideoMixerRender
Definition: mythvdpauhelper.h:114
MythVDPAUHelper::DeleteMixer
void DeleteMixer(VdpVideoMixer Mixer)
Definition: mythvdpauhelper.cpp:545
MythCodecContext::MPEG1
@ MPEG1
Definition: mythcodeccontext.h:60
MythVDPAUHelper::GetSurfaceParameters
QSize GetSurfaceParameters(VdpVideoSurface Surface, VdpChromaType &Chroma)
Definition: mythvdpauhelper.cpp:592
MythVDPAUHelper::m_vdpGetProcAddress
VdpGetProcAddress * m_vdpGetProcAddress
Definition: mythvdpauhelper.h:105
MythVDPAUHelper::IsValid
bool IsValid(void) const
Definition: mythvdpauhelper.cpp:321
uint
unsigned int uint
Definition: compat.h:81
MythVDPAUHelper::m_vdpVideoMixerSetFeatureEnables
VdpVideoMixerSetFeatureEnables * m_vdpVideoMixerSetFeatureEnables
Definition: mythvdpauhelper.h:116
MythVDPAUHelper::CreateMixer
VdpVideoMixer CreateMixer(QSize Size, VdpChromaType ChromaType=VDP_CHROMA_TYPE_420, MythDeintType Deinterlacer=DEINT_BASIC)
Definition: mythvdpauhelper.cpp:434
MythCodecContext::H264High444
@ H264High444
Definition: mythcodeccontext.h:95
mythxdisplay.h
MythXDisplay::Unlock
void Unlock()
Definition: mythxdisplay.h:33
DummyGetError
static const char * DummyGetError(VdpStatus)
Definition: mythvdpauhelper.cpp:255
MythDeintType
MythDeintType
Definition: mythframe.h:67
MythVDPAUHelper::m_vdpGetInformationString
VdpGetInformationString * m_vdpGetInformationString
Definition: mythvdpauhelper.h:107
MythVDPAUHelper::m_vdpDeviceDestroy
VdpDeviceDestroy * m_vdpDeviceDestroy
Definition: mythvdpauhelper.h:108
MythCodecContext::MPEG2Main
@ MPEG2Main
Definition: mythcodeccontext.h:63
kScan_Interlaced
@ kScan_Interlaced
Definition: videoouttypes.h:98
MythVDPAUHelper::HEVCSupported
bool HEVCSupported(void)
Definition: mythvdpauhelper.cpp:331
MythVDPAUHelper::ProfileCheck
bool ProfileCheck(VdpDecoderProfile Profile, uint32_t &Level, uint32_t &Macros, uint32_t &Width, uint32_t &Height)
Definition: mythvdpauhelper.cpp:86
MythVDPAUHelper::m_vdpDecoderCreate
VdpDecoderCreate * m_vdpDecoderCreate
Definition: mythvdpauhelper.h:110
DEINT_HIGH
@ DEINT_HIGH
Definition: mythframe.h:72
MythVDPAUHelper::m_vdpVideoMixerCreate
VdpVideoMixerCreate * m_vdpVideoMixerCreate
Definition: mythvdpauhelper.h:112
MythCodecContext::MJPEG
@ MJPEG
Definition: mythcodeccontext.h:123
MythVDPAUHelper::H264DecodeCheck
bool H264DecodeCheck(VdpDecoderProfile Profile, AVCodecContext *Context)
Definition: mythvdpauhelper.cpp:390
MythVDPAUHelper::CheckH264Decode
static bool CheckH264Decode(AVCodecContext *Context)
Definition: mythvdpauhelper.cpp:352
MythVDPAUHelper::MixerRender
void MixerRender(VdpVideoMixer Mixer, VdpVideoSurface Source, VdpOutputSurface Dest, FrameScanType Scan, int TopFieldFirst, QVector< AVBufferRef * > &Frames)
Definition: mythvdpauhelper.cpp:489
MythCodecContext::H264High
@ H264High
Definition: mythcodeccontext.h:91
MythCodecContext::GetProfileDescription
static QString GetProfileDescription(CodecProfile Profile, QSize Size, VideoFrameType Format=FMT_NONE, uint ColorDepth=0)
Definition: mythcodeccontext.cpp:784
VDPAUCodec::VDPAUCodec
VDPAUCodec(MythCodecContext::CodecProfile Profile, QSize Size, uint32_t Macroblocks, uint32_t Level)
Definition: mythvdpauhelper.cpp:30
MythVDPAUHelper::m_vdpVideoMixerSetAttributeValues
VdpVideoMixerSetAttributeValues * m_vdpVideoMixerSetAttributeValues
Definition: mythvdpauhelper.h:115
VDPAUCodec::Supported
bool Supported(int Width, int Height, int Level) const
Definition: mythvdpauhelper.cpp:40
VDPAUCodec
Definition: mythvdpauhelper.h:35
MythVDPAUHelper::m_vdpDecoderDestroy
VdpDecoderDestroy * m_vdpDecoderDestroy
Definition: mythvdpauhelper.h:111
MythVDPAUHelper::m_vdpVideoSurfaceGetParameters
VdpVideoSurfaceGetParameters * m_vdpVideoSurfaceGetParameters
Definition: mythvdpauhelper.h:121
GET_PROC
#define GET_PROC(FUNC_ID, PROC)
Definition: mythvdpauhelper.cpp:26
MythVDPAUHelper::m_vdpOutputSurfaceCreate
VdpOutputSurfaceCreate * m_vdpOutputSurfaceCreate
Definition: mythvdpauhelper.h:119
MythVDPAUHelper::m_vdpPreemptionCallbackRegister
VdpPreemptionCallbackRegister * m_vdpPreemptionCallbackRegister
Definition: mythvdpauhelper.h:122
MythVDPAUHelper::m_device
VdpDevice m_device
Definition: mythvdpauhelper.h:102
MythCodecContext::H264ConstrainedHigh
@ H264ConstrainedHigh
Definition: mythcodeccontext.h:96
MythVideoColourSpace
MythVideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
Definition: mythvideocolourspace.h:18
MythCodecContext::HEVCMain
@ HEVCMain
Definition: mythcodeccontext.h:98