10 #define LOC QString("VDPAUHelp: ")
18 ok &= (status == VDP_STATUS_OK); \
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))); \
26 #define GET_PROC(FUNC_ID, PROC) \
27 status = m_vdpGetProcAddress(m_device, FUNC_ID, reinterpret_cast<void **>(&(PROC))); CHECK_ST
32 m_maxMacroBlocks(Macroblocks),
43 uint32_t macros =
static_cast<uint32_t
>(((Width + 15) & ~15) * ((Height + 15) & ~15)) / 256;
48 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Not supported: Size %1x%2 > %3x%4, MBs %5 > %6, Level %7 > %8")
57 static QMutex s_mutex;
58 static bool s_checked =
false;
59 static bool s_available =
false;
61 QMutexLocker locker(&s_mutex);
62 if (s_checked && !Reinit)
73 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Supported/available VDPAU decoders:");
75 for (
const auto&
profile : std::as_const(profiles))
76 LOG(VB_GENERAL, LOG_INFO,
LOC +
81 LOG(VB_GENERAL, LOG_INFO,
LOC +
"VDPAU is NOT available");
87 uint32_t &Macros, uint32_t &Width, uint32_t &Height)
93 VdpBool supported = VDP_FALSE;
95 &Level, &Macros, &Width, &Height);
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));
101 if (((supported != VDP_TRUE) || (status != VDP_STATUS_OK)) &&
102 (Profile == VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE ||
103 Profile == VDP_DECODER_PROFILE_H264_BASELINE))
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 " :
""));
113 &Level, &Macros, &Width, &Height);
115 if (supported == VDP_TRUE)
116 LOG(VB_GENERAL, LOG_INFO,
LOC +
"... but assuming available as H264 Main is supported");
119 return supported == VDP_TRUE;
124 static const std::array<const VdpDecoderProfile,15> MainProfiles
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
134 static const std::array<const VdpDecoderProfile,4> HEVCProfiles
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
140 auto VDPAUToMythProfile = [](VdpDecoderProfile Profile)
171 static QRecursiveMutex lock;
172 static bool s_initialised =
false;
175 QMutexLocker locker(&lock);
178 s_initialised =
true;
188 for (VdpDecoderProfile
profile : MainProfiles)
193 s_profiles.emplace_back(prof,
194 VDPAUCodec(prof, QSize(
static_cast<int>(width),
static_cast<int>(height)), macros, level));
200 for (VdpDecoderProfile
profile : HEVCProfiles)
205 s_profiles.emplace_back(prof,
206 VDPAUCodec(prof, QSize(
static_cast<int>(width),
static_cast<int>(height)), macros, level));
217 if (profiles.empty())
220 Decoders.append(
"VDPAU:");
221 for (
const auto&
profile : std::as_const(profiles))
237 : m_device(Context->device),
238 m_vdpGetProcAddress(Context->get_proc_address)
247 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
"Failed to register preemption callback");
257 : m_createdDevice(
true)
273 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
"Failed to create VDPAU device.");
333 const char* infostring =
nullptr;
337 if (!ok || !infostring)
340 if (!QString(infostring).contains(
"NVIDIA", Qt::CaseInsensitive))
344 sscanf(infostring,
"NVIDIA VDPAU Driver Shared Library %d", &driver);
345 return !(driver < 410);
353 int mbs =
static_cast<int>(ceil(
static_cast<double>(Context->width) / 16.0));
354 if (mbs != 49 && mbs != 54 && mbs != 59 && mbs != 64 &&
355 mbs != 113 && mbs != 118 &&mbs != 123 && mbs != 128)
361 switch (Context->profile & ~FF_PROFILE_H264_INTRA)
363 case FF_PROFILE_H264_BASELINE:
profile = VDP_DECODER_PROFILE_H264_BASELINE;
break;
364 case FF_PROFILE_H264_CONSTRAINED_BASELINE:
profile = VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE;
break;
365 case FF_PROFILE_H264_MAIN:
profile = VDP_DECODER_PROFILE_H264_MAIN;
break;
366 case FF_PROFILE_H264_HIGH:
profile = VDP_DECODER_PROFILE_H264_HIGH;
break;
367 #ifdef VDP_DECODER_PROFILE_H264_EXTENDED
368 case FF_PROFILE_H264_EXTENDED:
profile = VDP_DECODER_PROFILE_H264_EXTENDED;
break;
370 case FF_PROFILE_H264_HIGH_10:
profile = VDP_DECODER_PROFILE_H264_HIGH;
break;
371 #ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
372 case FF_PROFILE_H264_HIGH_422:
373 case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
374 case FF_PROFILE_H264_CAVLC_444:
profile = VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE;
break;
376 default:
return false;
394 static_cast<uint>(Context->height), 2, &
tmp);
400 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"No H264 decoder support for %1x%2")
401 .arg(Context->width).arg(Context->height));
411 VdpOutputSurface result = 0;
414 static_cast<uint>(Size.width()),
415 static_cast<uint>(Size.height()), &result);
433 if (!
m_valid || Size.isEmpty())
436 VdpVideoMixer result = 0;
438 static const std::array<const VdpVideoMixerParameter,3> parameters {
439 VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
440 VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
441 VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE
445 uint width =
static_cast<uint>(Size.width());
446 uint height =
static_cast<uint>(Size.height());
447 std::array<void const *,3> parametervalues { &width, &height, &ChromaType};
449 uint32_t featurecount = 0;
450 std::array<VdpVideoMixerFeature,2> features {};
451 VdpBool enable = VDP_TRUE;
452 const std::array<VdpBool,2> enables = { enable, enable };
456 features[featurecount] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL;
462 features[featurecount] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL;
468 3, parameters.data(), parametervalues.data(), &result);
473 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create video mixer");
486 VdpOutputSurface Dest,
FrameScanType Scan,
int TopFieldFirst,
487 QVector<AVBufferRef*>& Frames)
492 VdpVideoMixerPictureStructure field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
495 field = TopFieldFirst ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD :
496 VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
500 field = TopFieldFirst ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD :
501 VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
504 int count = Frames.size();
505 if ((count < 1) || (field == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME))
509 0,
nullptr,
Source, 0,
nullptr,
nullptr, Dest,
nullptr,
nullptr, 0,
nullptr);
514 std::array<VdpVideoSurface,2> past = { VDP_INVALID_HANDLE, VDP_INVALID_HANDLE };
515 std::array<VdpVideoSurface,1> future = { VDP_INVALID_HANDLE };
517 auto next =
static_cast<VdpVideoSurface
>(
reinterpret_cast<uintptr_t
>(Frames[0]->data));
518 auto current =
static_cast<VdpVideoSurface
>(
reinterpret_cast<uintptr_t
>(Frames[count > 1 ? 1 : 0]->data));
519 auto last =
static_cast<VdpVideoSurface
>(
reinterpret_cast<uintptr_t
>(Frames[count > 2 ? 2 : 0]->data));
521 if (field == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD)
524 past[0] = past[1] = last;
535 2, past.data(),
current, 1, future.data(),
536 nullptr, Dest,
nullptr,
nullptr, 0,
nullptr);
553 if (!Mixer || !ColourSpace)
556 VdpVideoMixerAttribute attr = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX };
557 void const* val = { ColourSpace->data() };
570 auto supported =
static_cast<VdpBool
>(
false);
573 return ok &&
static_cast<bool>(supported);
582 auto supported =
static_cast<VdpBool
>(
false);
585 return ok &&
static_cast<bool>(supported);
599 return {
static_cast<int>(width),
static_cast<int>(height)};