Loading...
Searching...
No Matches
GpuFormats.hpp
1#pragma once
2#include <Media/Libav.hpp>
3
4#include <QtGlobal>
5
6#include <cstdlib>
7#include <string>
8#include <string_view>
9#include <vector>
10
11#if defined(__linux__)
12#include <unistd.h>
13#endif
14
15#if SCORE_HAS_LIBAV
16extern "C" {
17#include <libavcodec/avcodec.h>
18#include <libavformat/avformat.h>
19#include <libavutil/pixdesc.h>
20#include <libavutil/version.h>
21#if __has_include(<libavutil/hwcontext.h>)
22#include <libavutil/hwcontext.h>
23#endif
24struct AVCodecContext;
25}
26
27namespace Video
28{
29
30inline bool hardwareDecoderIsAvailable(AVPixelFormat p) noexcept
31{
32 switch(p)
33 {
34#if defined(__linux__)
35 case AV_PIX_FMT_DRM_PRIME: {
36 static const bool ok = avcodec_find_decoder_by_name("h264_v4l2m2m");
37 return ok;
38 }
39 case AV_PIX_FMT_VAAPI: {
40 // FFmpeg 7+ removed dedicated VAAPI decoders (mjpeg_vaapi, etc.).
41 // VAAPI now uses the generic decoder with hw_device_ctx.
42 // Check if the VAAPI device type is supported instead.
43 static const bool ok = avcodec_find_decoder_by_name("mjpeg_vaapi")
44 || av_hwdevice_find_type_by_name("vaapi") != AV_HWDEVICE_TYPE_NONE;
45 return ok;
46 }
47 case AV_PIX_FMT_VDPAU: {
48 static const bool ok = avcodec_find_decoder_by_name("h264_vdpau");
49 return ok;
50 }
51#endif
52#if defined(_WIN32)
53 case AV_PIX_FMT_DXVA2_VLD:
54 return true;
55 case AV_PIX_FMT_D3D11:
56 return true;
57#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 29, 100)
58 case AV_PIX_FMT_D3D12:
59 return true;
60#endif
61#endif
62#if defined(__APPLE__)
63 case AV_PIX_FMT_VIDEOTOOLBOX:
64 return true;
65#endif
66 // Cross-platform pix formats
67 case AV_PIX_FMT_CUDA: {
68 static const bool ok = avcodec_find_decoder_by_name("mjpeg_cuvid")
69 || avcodec_find_decoder_by_name("h264_cuvid");
70 return ok;
71 }
72 case AV_PIX_FMT_QSV: {
73 static const bool ok = avcodec_find_decoder_by_name("mjpeg_qsv")
74 || avcodec_find_decoder_by_name("h264_qsv");
75 return ok;
76 }
77 case AV_PIX_FMT_VULKAN: {
78 static const bool ok
79 = av_hwdevice_find_type_by_name("vulkan") != AV_HWDEVICE_TYPE_NONE;
80 return ok;
81 }
82 default:
83 return false;
84 }
85}
86
87inline constexpr bool formatIsHardwareDecoded(AVPixelFormat fmt) noexcept
88{
89#if LIBAVUTIL_VERSION_MAJOR < 57
90 return false;
91#else
92 switch(fmt)
93 {
94 case AV_PIX_FMT_VAAPI:
95 case AV_PIX_FMT_VDPAU:
96 case AV_PIX_FMT_DXVA2_VLD:
97 case AV_PIX_FMT_D3D11:
98#if defined(_WIN32) && LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 29, 100)
99 case AV_PIX_FMT_D3D12:
100#endif
101 case AV_PIX_FMT_CUDA:
102 case AV_PIX_FMT_QSV:
103 case AV_PIX_FMT_VIDEOTOOLBOX:
104 case AV_PIX_FMT_DRM_PRIME:
105 case AV_PIX_FMT_VULKAN:
106 return true;
107 default:
108 return false;
109 }
110#endif
111}
112
113inline constexpr bool formatNeedsDecoding(AVPixelFormat fmt) noexcept
114{
115 // They all get translated to some NV12 or something like that
116 if(formatIsHardwareDecoded(fmt))
117 return false;
118
119 switch(fmt)
120 {
121 case AV_PIX_FMT_YUV420P:
122 case AV_PIX_FMT_RGB24:
123 case AV_PIX_FMT_BGR24:
124 case AV_PIX_FMT_RGB48LE:
125 case AV_PIX_FMT_BGR48LE:
126 case AV_PIX_FMT_XYZ12LE:
127 case AV_PIX_FMT_NV12:
128 case AV_PIX_FMT_NV21:
129 case AV_PIX_FMT_NV16:
130 case AV_PIX_FMT_P010LE:
131 case AV_PIX_FMT_P016LE:
132 case AV_PIX_FMT_YUVJ420P:
133 case AV_PIX_FMT_YUVJ422P:
134 case AV_PIX_FMT_YUVJ440P:
135 case AV_PIX_FMT_YUV422P:
136 case AV_PIX_FMT_YUV440P:
137 case AV_PIX_FMT_YUV444P:
138 case AV_PIX_FMT_YUVJ444P:
139 case AV_PIX_FMT_YUVA420P:
140 case AV_PIX_FMT_YUVA444P:
141 case AV_PIX_FMT_UYVY422:
142 case AV_PIX_FMT_YUYV422:
143 case AV_PIX_FMT_RGB0:
144 case AV_PIX_FMT_RGBA:
145 case AV_PIX_FMT_BGR0:
146 case AV_PIX_FMT_BGRA:
147 case AV_PIX_FMT_ARGB:
148 case AV_PIX_FMT_ABGR:
149 case AV_PIX_FMT_RGBA64LE:
150 case AV_PIX_FMT_BGRA64LE:
151 case AV_PIX_FMT_X2RGB10LE:
152 case AV_PIX_FMT_GBRP:
153 case AV_PIX_FMT_GBRAP:
154 case AV_PIX_FMT_YA8:
155 case AV_PIX_FMT_YA16LE:
156
157#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 19, 100)
158 case AV_PIX_FMT_YUV420P10LE:
159 case AV_PIX_FMT_YUV420P12LE:
160 case AV_PIX_FMT_YUV422P10LE:
161 case AV_PIX_FMT_YUV422P12LE:
162 case AV_PIX_FMT_YUV444P10LE:
163 case AV_PIX_FMT_YUV444P12LE:
164 case AV_PIX_FMT_YUVA444P10LE:
165 case AV_PIX_FMT_YUVA444P12LE:
166 case AV_PIX_FMT_GBRP10LE:
167 case AV_PIX_FMT_GBRP12LE:
168 case AV_PIX_FMT_GBRP16LE:
169 case AV_PIX_FMT_GBRAP10LE:
170 case AV_PIX_FMT_GBRAP12LE:
171 case AV_PIX_FMT_GBRAP16LE:
172 case AV_PIX_FMT_GBRPF32LE:
173 case AV_PIX_FMT_GBRAPF32LE:
174 case AV_PIX_FMT_GRAYF32:
175 case AV_PIX_FMT_NV24:
176 case AV_PIX_FMT_NV42:
177 case AV_PIX_FMT_Y210LE:
178#endif
179
180#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 17, 100)
181 case AV_PIX_FMT_X2BGR10LE:
182 case AV_PIX_FMT_P210LE:
183 case AV_PIX_FMT_P216LE:
184 case AV_PIX_FMT_P410LE:
185#endif
186
187 // These guards must match GPUVideoDecoderFactory.cpp: a format whose decoder
188 // is compiled in but whose case here is compiled out gets routed through
189 // swscale even though it has a direct GPU path.
190#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 29, 100)
191 case AV_PIX_FMT_RGBAF32LE:
192 case AV_PIX_FMT_VUYA:
193 case AV_PIX_FMT_VUYX:
194 case AV_PIX_FMT_P012LE:
195 case AV_PIX_FMT_RGBAF16LE:
196#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
197 case AV_PIX_FMT_XV30LE:
198#endif
199#endif
200
201#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(59, 55, 100)
202 case AV_PIX_FMT_GBRPF16LE:
203 case AV_PIX_FMT_GBRAPF16LE:
204#endif
205
206#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(60, 8, 100)
207 case AV_PIX_FMT_GRAYF16:
208#endif
209
210 case AV_PIX_FMT_GRAY8:
211 case AV_PIX_FMT_GRAY16:
212
213 case AV_PIX_FMT_YUV410P:
214 case AV_PIX_FMT_YUV411P:
215 case AV_PIX_FMT_YUVA422P:
216 case AV_PIX_FMT_YUV420P16LE:
217 case AV_PIX_FMT_YUV422P16LE:
218 case AV_PIX_FMT_YUVA422P16LE:
219 case AV_PIX_FMT_PAL8:
220 case AV_PIX_FMT_RGB555LE:
221 case AV_PIX_FMT_RGB555BE:
222 case AV_PIX_FMT_BGR555LE:
223 case AV_PIX_FMT_RGB565LE:
224 case AV_PIX_FMT_RGB565BE:
225 case AV_PIX_FMT_BGR8:
226 case AV_PIX_FMT_0RGB:
227 case AV_PIX_FMT_BAYER_RGGB8:
228 case AV_PIX_FMT_BAYER_BGGR8:
229 case AV_PIX_FMT_BAYER_GRBG8:
230 case AV_PIX_FMT_BAYER_GBRG8:
231 case AV_PIX_FMT_BAYER_RGGB16LE:
232 case AV_PIX_FMT_BAYER_BGGR16LE:
233 case AV_PIX_FMT_BAYER_GRBG16LE:
234 case AV_PIX_FMT_BAYER_GBRG16LE:
235 return false;
236
237 // Other formats get rgb'd
238 default:
239 return true;
240 }
241}
242
243#if LIBAVUTIL_VERSION_MAJOR >= 57
244// Get hardware pix format
245struct HWAccelFormats
246{
247 AVPixelFormat format{AV_PIX_FMT_NONE};
248 AVHWDeviceType device{AV_HWDEVICE_TYPE_NONE};
249};
250
251inline constexpr HWAccelFormats ffmpegHardwareDecodingFormats(AVPixelFormat p) noexcept
252{
253 switch(p)
254 {
255#if defined(__linux__)
256 case AV_PIX_FMT_DRM_PRIME:
257 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_DRM_PRIME))
258 return {};
259 return {AV_PIX_FMT_DRM_PRIME, AV_HWDEVICE_TYPE_DRM};
260 case AV_PIX_FMT_VAAPI:
261 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_VAAPI))
262 return {};
263 return {AV_PIX_FMT_VAAPI, AV_HWDEVICE_TYPE_VAAPI};
264 case AV_PIX_FMT_VDPAU:
265 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_VDPAU))
266 return {};
267 return {AV_PIX_FMT_VDPAU, AV_HWDEVICE_TYPE_VDPAU};
268#endif
269#if defined(_WIN32)
270 case AV_PIX_FMT_DXVA2_VLD:
271 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_DXVA2_VLD))
272 return {};
273 return {AV_PIX_FMT_DXVA2_VLD, AV_HWDEVICE_TYPE_DXVA2};
274 case AV_PIX_FMT_D3D11:
275 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_D3D11))
276 return {};
277 return {AV_PIX_FMT_D3D11, AV_HWDEVICE_TYPE_D3D11VA};
278#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 29, 100)
279 case AV_PIX_FMT_D3D12:
280 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_D3D12))
281 return {};
282 return {AV_PIX_FMT_D3D12, AV_HWDEVICE_TYPE_D3D12VA};
283#endif
284#endif
285#if defined(__APPLE__)
286 case AV_PIX_FMT_VIDEOTOOLBOX:
287 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_VIDEOTOOLBOX))
288 return {};
289 return {AV_PIX_FMT_VIDEOTOOLBOX, AV_HWDEVICE_TYPE_VIDEOTOOLBOX};
290#endif
291 // Cross-platform pix formats
292 case AV_PIX_FMT_CUDA:
293 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_CUDA))
294 return {};
295 return {AV_PIX_FMT_CUDA, AV_HWDEVICE_TYPE_CUDA};
296 case AV_PIX_FMT_QSV:
297 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_QSV))
298 return {};
299 return {AV_PIX_FMT_QSV, AV_HWDEVICE_TYPE_QSV};
300 case AV_PIX_FMT_VULKAN:
301 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_VULKAN))
302 return {};
303 return {AV_PIX_FMT_VULKAN, AV_HWDEVICE_TYPE_VULKAN};
304 // case AV_PIX_FMT_OPENCL:
305 // return {AV_PIX_FMT_OPENCL, AV_HWDEVICE_TYPE_OPENCL};
306 default:
307 return {};
308 }
309}
310
311inline constexpr bool ffmpegCanDoHardwareDecoding(AVCodecID id) noexcept
312{
313 switch(id)
314 {
315 case AV_CODEC_ID_AV1:
316 case AV_CODEC_ID_H264:
317 case AV_CODEC_ID_HEVC:
318 case AV_CODEC_ID_MJPEG:
319 case AV_CODEC_ID_MPEG1VIDEO:
320 case AV_CODEC_ID_MPEG2VIDEO:
321 case AV_CODEC_ID_MPEG4:
322 case AV_CODEC_ID_VC1:
323 case AV_CODEC_ID_VP8:
324 case AV_CODEC_ID_VP9:
325 case AV_CODEC_ID_WMV1:
326 case AV_CODEC_ID_WMV2:
327 case AV_CODEC_ID_WMV3:
328 case AV_CODEC_ID_PRORES:
329 return true;
330 default:
331 return false;
332 }
333}
335inline std::string hwCodecName(const char* codec_name, AVHWDeviceType device)
336{
337 std::string name{codec_name};
338 switch(device)
339 {
340 case AV_HWDEVICE_TYPE_CUDA:
341 return name + "_cuvid";
342 case AV_HWDEVICE_TYPE_QSV:
343 return name + "_qsv";
344 case AV_HWDEVICE_TYPE_VDPAU:
345 return name + "_vdpau";
346 case AV_HWDEVICE_TYPE_VAAPI:
347 return name;
348 case AV_HWDEVICE_TYPE_DRM:
349 return name + "_v4l2m2m";
350 case AV_HWDEVICE_TYPE_DXVA2:
351 case AV_HWDEVICE_TYPE_D3D11VA:
352#if defined(_WIN32) && LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 29, 100)
353 case AV_HWDEVICE_TYPE_D3D12VA:
354#endif
355 case AV_HWDEVICE_TYPE_VIDEOTOOLBOX:
356 case AV_HWDEVICE_TYPE_VULKAN:
357 return name;
358 default:
359 return {};
360 }
361}
362
364inline bool isVulkanComputeCodec(AVCodecID id)
365{
366 switch(id)
367 {
368 case AV_CODEC_ID_PRORES:
369 case AV_CODEC_ID_FFV1:
370 return true;
371 default:
372 return false;
373 }
374}
375
384inline bool vulkanComputeDecodersAreReliable() noexcept
385{
386 return avcodec_version() >= AV_VERSION_INT(63, 2, 0);
387}
388
391 AVCodecID codec_id, AVPixelFormat pix_fmt, uint32_t gpuVendorId = 0)
392{
393 (void)gpuVendorId;
394
395 // This check is the gate for both an explicitly requested accel and the
396 // automatic selection, so refusing here sends these codecs to the software
397 // decoder on every path. Checked against the libavcodec actually loaded, not
398 // the headers: Linux builds use the distribution's.
399 if(pix_fmt == AV_PIX_FMT_VULKAN && isVulkanComputeCodec(codec_id)
400 && !vulkanComputeDecodersAreReliable())
401 return false;
402
403 auto hwInfo = ffmpegHardwareDecodingFormats(pix_fmt);
404 if(hwInfo.device == AV_HWDEVICE_TYPE_NONE)
405 return false;
406
407 const AVCodec* codec = avcodec_find_decoder(codec_id);
408 if(!codec)
409 return false;
410
411 auto dedicated = hwCodecName(codec->name, hwInfo.device);
412 if(!dedicated.empty() && dedicated != codec->name)
413 {
414 if(avcodec_find_decoder_by_name(dedicated.c_str()))
415 return true;
416 return false;
417 }
418
419 for(int i = 0;; i++)
420 {
421 const AVCodecHWConfig* config = avcodec_get_hw_config(codec, i);
422 if(!config)
423 break;
424 if(config->pix_fmt == pix_fmt
425 && (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
426 return true;
427 }
428 return false;
429}
430
432namespace GpuVendor
433{
434inline constexpr uint32_t NVIDIA = 0x10DE;
435inline constexpr uint32_t Intel = 0x8086;
436inline constexpr uint32_t AMD = 0x1002;
437inline constexpr uint32_t Apple = 0x106B;
438inline constexpr uint32_t Broadcom = 0x14E4; // RPi VideoCore
439inline constexpr uint32_t ARM = 0x13B5; // Mali
440inline constexpr uint32_t Qualcomm = 0x5143;
441inline constexpr uint32_t Samsung = 0x144D;
442}
443
448inline std::vector<AVPixelFormat> selectHardwareAccelerations(
449 int graphicsApi, AVCodecID codec_id, uint32_t gpuVendorId = 0)
450{
451 struct Candidate { AVPixelFormat fmt; };
452 std::vector<Candidate> candidates;
453
454 switch(graphicsApi)
455 {
456#if defined(_WIN32)
457 case 3: // D3D11
458 candidates = {{AV_PIX_FMT_D3D11}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
459 break;
460 case 5: // D3D12
461#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 29, 100)
462 candidates = {{AV_PIX_FMT_D3D12}, {AV_PIX_FMT_D3D11}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
463#else
464 candidates = {{AV_PIX_FMT_D3D11}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
465#endif
466 break;
467#endif
468#if defined(__APPLE__)
469 case 4: // Metal
470 candidates = {{AV_PIX_FMT_VIDEOTOOLBOX}};
471 break;
472#endif
473 case 2: // Vulkan
474 {
475#if defined(__linux__)
476 if(gpuVendorId == GpuVendor::NVIDIA)
477 {
478 candidates = {{AV_PIX_FMT_VULKAN}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_VAAPI}, {AV_PIX_FMT_QSV}};
479 }
480 else if(gpuVendorId == GpuVendor::Intel)
481 {
482 candidates = {{AV_PIX_FMT_VAAPI}, {AV_PIX_FMT_VULKAN}, {AV_PIX_FMT_QSV}};
483 }
484 else if(gpuVendorId == GpuVendor::AMD)
485 {
486 candidates = {{AV_PIX_FMT_VAAPI}, {AV_PIX_FMT_VULKAN}};
487 }
488 else if(gpuVendorId == GpuVendor::Broadcom
489 || gpuVendorId == GpuVendor::ARM
490 || gpuVendorId == GpuVendor::Qualcomm)
491 {
492 candidates = {{AV_PIX_FMT_DRM_PRIME}, {AV_PIX_FMT_VULKAN}};
493 }
494 else
495 {
496 candidates = {{AV_PIX_FMT_VAAPI}, {AV_PIX_FMT_VULKAN}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
497 }
498#elif defined(_WIN32)
499 candidates = {
500 {AV_PIX_FMT_VULKAN}, {AV_PIX_FMT_D3D11},
501#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 29, 100)
502 {AV_PIX_FMT_D3D12},
503#endif
504 {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
505#elif defined(__APPLE__)
506 candidates = {{AV_PIX_FMT_VIDEOTOOLBOX}};
507#else
508 candidates = {{AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
509#endif
510 break;
511 }
512 case 1: // OpenGL
513 {
514#if defined(__linux__)
515 if(gpuVendorId == GpuVendor::Broadcom
516 || gpuVendorId == GpuVendor::ARM
517 || gpuVendorId == GpuVendor::Qualcomm)
518 {
519 candidates = {{AV_PIX_FMT_DRM_PRIME}};
520 }
521 else
522 {
523 candidates = {{AV_PIX_FMT_VAAPI}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
524 }
525#elif defined(_WIN32)
526 candidates = {{AV_PIX_FMT_D3D11}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
527#elif defined(__APPLE__)
528 candidates = {{AV_PIX_FMT_VIDEOTOOLBOX}};
529#endif
530 break;
531 }
532 default:
533 {
534#if defined(__linux__)
535#if defined(__arm__) || defined(__aarch64__)
536 candidates = {{AV_PIX_FMT_DRM_PRIME}, {AV_PIX_FMT_VAAPI}};
537#else
538 candidates = {{AV_PIX_FMT_VAAPI}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
539#endif
540#elif defined(_WIN32)
541 candidates = {{AV_PIX_FMT_D3D11}, {AV_PIX_FMT_CUDA}, {AV_PIX_FMT_QSV}};
542#elif defined(__APPLE__)
543 candidates = {{AV_PIX_FMT_VIDEOTOOLBOX}};
544#endif
545 break;
546 }
547 }
548
549 std::vector<AVPixelFormat> result;
550 for(auto& c : candidates)
551 {
552 if(hardwareDecoderIsAvailable(c.fmt)
553 && codecSupportsHWPixelFormat(codec_id, c.fmt, gpuVendorId))
554 result.push_back(c.fmt);
555 }
556 return result;
557}
558
560inline AVPixelFormat selectHardwareAcceleration(
561 int graphicsApi, AVCodecID codec_id, uint32_t gpuVendorId = 0)
562{
563 auto fmts = selectHardwareAccelerations(graphicsApi, codec_id, gpuVendorId);
564 return fmts.empty() ? AV_PIX_FMT_NONE : fmts.front();
565}
566
567#if defined(__linux__)
574inline std::string preferredVAAPIRenderNode() noexcept
575{
576 for(int i = 128; i < 128 + 16; i++)
577 {
578 char link[64], drv[256];
579 snprintf(link, sizeof link, "/sys/class/drm/renderD%d/device/driver", i);
580 ssize_t n = readlink(link, drv, sizeof(drv) - 1);
581 if(n <= 0)
582 continue;
583 drv[n] = 0;
584 std::string_view driver{drv};
585 if(auto slash = driver.rfind('/'); slash != std::string_view::npos)
586 driver.remove_prefix(slash + 1);
587 if(driver != "nvidia")
588 {
589 char dev[64];
590 snprintf(dev, sizeof dev, "/dev/dri/renderD%d", i);
591 return dev;
592 }
593 }
594 return {};
595}
596#endif
597
604inline std::string hardwareDecodingDeviceName(AVHWDeviceType device) noexcept
605{
606 if(const char* env = getenv("SCORE_VIDEO_HW_DEVICE"); env && *env)
607 return env;
608#if defined(__linux__)
609 if(device == AV_HWDEVICE_TYPE_VAAPI)
610 return preferredVAAPIRenderNode();
611#endif
612 return {};
613}
614
616inline int createHardwareDevice(AVBufferRef** ctx, AVHWDeviceType device) noexcept
617{
618 const std::string name = hardwareDecodingDeviceName(device);
619 return av_hwdevice_ctx_create(
620 ctx, device, name.empty() ? nullptr : name.c_str(), nullptr, 0);
621}
622
623#endif
624}
625
626#endif
GpuVendor
Definition GpuCapabilities.hpp:50
AVPixelFormat selectHardwareAcceleration(score::gfx::GraphicsApi api, AVCodecID codec_id, QRhi *rhi)
Picks the best HW accel for the given API/codec, using QRhi for vendor detection.
Definition HWAccelSetup.cpp:36
std::string hwCodecName(const char *codec_name, AVHWDeviceType device)
Delegates to Video::hwCodecName (score-plugin-gfx wrapper)
Definition HWAccelSetup.cpp:18
bool codecSupportsHWPixelFormat(AVCodecID codec_id, AVPixelFormat pix_fmt)
Delegates to Video::codecSupportsHWPixelFormat (score-plugin-gfx wrapper)
Definition HWAccelSetup.cpp:27