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