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 : qAsConst(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 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
172 static QMutex lock(QMutex::Recursive);
174 static QRecursiveMutex lock;
176 static bool s_initialised =
false;
179 QMutexLocker locker(&lock);
182 s_initialised =
true;
192 for (VdpDecoderProfile
profile : MainProfiles)
197 s_profiles.emplace_back(prof,
198 VDPAUCodec(prof, QSize(
static_cast<int>(width),
static_cast<int>(height)), macros, level));
204 for (VdpDecoderProfile
profile : HEVCProfiles)
209 s_profiles.emplace_back(prof,
210 VDPAUCodec(prof, QSize(
static_cast<int>(width),
static_cast<int>(height)), macros, level));
221 if (profiles.empty())
224 Decoders.append(
"VDPAU:");
225 for (
const auto&
profile : qAsConst(profiles))
241 : m_device(Context->device),
242 m_vdpGetProcAddress(Context->get_proc_address)
251 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
"Failed to register preemption callback");
261 : m_createdDevice(
true)
277 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
"Failed to create VDPAU device.");
337 const char* infostring =
nullptr;
341 if (!ok || !infostring)
344 if (!QString(infostring).contains(
"NVIDIA", Qt::CaseInsensitive))
348 sscanf(infostring,
"NVIDIA VDPAU Driver Shared Library %d", &driver);
349 return !(driver < 410);
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)
365 switch (Context->profile & ~FF_PROFILE_H264_INTRA)
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;
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;
380 default:
return false;
398 static_cast<uint>(Context->height), 2, &
tmp);
404 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"No H264 decoder support for %1x%2")
405 .arg(Context->width).arg(Context->height));
415 VdpOutputSurface result = 0;
418 static_cast<uint>(Size.width()),
419 static_cast<uint>(Size.height()), &result);
437 if (!
m_valid || Size.isEmpty())
440 VdpVideoMixer result = 0;
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
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};
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 };
460 features[featurecount] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL;
466 features[featurecount] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL;
472 3, parameters.data(), parametervalues.data(), &result);
477 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create video mixer");
490 VdpOutputSurface Dest,
FrameScanType Scan,
int TopFieldFirst,
491 QVector<AVBufferRef*>& Frames)
496 VdpVideoMixerPictureStructure field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
499 field = TopFieldFirst ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD :
500 VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
504 field = TopFieldFirst ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD :
505 VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
508 int count = Frames.size();
509 if ((count < 1) || (field == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME))
513 0,
nullptr,
Source, 0,
nullptr,
nullptr, Dest,
nullptr,
nullptr, 0,
nullptr);
518 std::array<VdpVideoSurface,2> past = { VDP_INVALID_HANDLE, VDP_INVALID_HANDLE };
519 std::array<VdpVideoSurface,1> future = { VDP_INVALID_HANDLE };
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));
525 if (field == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD)
528 past[0] = past[1] = last;
539 2, past.data(),
current, 1, future.data(),
540 nullptr, Dest,
nullptr,
nullptr, 0,
nullptr);
557 if (!Mixer || !ColourSpace)
560 VdpVideoMixerAttribute attr = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX };
561 void const* val = { ColourSpace->data() };
574 auto supported =
static_cast<VdpBool
>(
false);
577 return ok &&
static_cast<bool>(supported);
586 auto supported =
static_cast<VdpBool
>(
false);
589 return ok &&
static_cast<bool>(supported);
603 return {
static_cast<int>(width),
static_cast<int>(height)};