Loading...
Searching...
No Matches
GpuFormats.hpp
1#pragma once
2#include <Media/Libav.hpp>
3
4#if SCORE_HAS_LIBAV
5extern "C" {
6#include <libavformat/avformat.h>
7#include <libavutil/pixdesc.h>
8#include <libavutil/version.h>
9#if __has_include(<libavutil/hwcontext.h>)
10#include <libavutil/hwcontext.h>
11#endif
12struct AVCodecContext;
13}
14
15namespace Video
16{
17
18inline bool hardwareDecoderIsAvailable(AVPixelFormat p) noexcept
19{
20 switch(p)
21 {
22#if defined(__linux__)
23 case AV_PIX_FMT_DRM_PRIME: {
24 static const bool ok = avcodec_find_decoder_by_name("h264_v4l2m2m");
25 return ok;
26 }
27 case AV_PIX_FMT_VAAPI: {
28 static const bool ok = avcodec_find_decoder_by_name("mjpeg_vaapi");
29 return ok;
30 }
31 case AV_PIX_FMT_VDPAU: {
32 static const bool ok = avcodec_find_decoder_by_name("h264_vdpau");
33 return ok;
34 }
35#endif
36#if defined(_WIN32)
37 case AV_PIX_FMT_DXVA2_VLD:
38 return true;
39 case AV_PIX_FMT_D3D11:
40 return true;
41#endif
42#if defined(__APPLE__)
43 case AV_PIX_FMT_VIDEOTOOLBOX:
44 return true;
45#endif
46 // Cross-platform pix formats
47 case AV_PIX_FMT_CUDA: {
48 static const bool ok = avcodec_find_decoder_by_name("mjpeg_cuvid")
49 || avcodec_find_decoder_by_name("h264_cuvid");
50 return ok;
51 }
52 case AV_PIX_FMT_QSV: {
53 static const bool ok = avcodec_find_decoder_by_name("mjpeg_qsv")
54 || avcodec_find_decoder_by_name("h264_qsv");
55 return ok;
56 }
57 default:
58 return false;
59 }
60}
61
62inline constexpr bool formatIsHardwareDecoded(AVPixelFormat fmt) noexcept
63{
64#if LIBAVUTIL_VERSION_MAJOR < 57
65 return false;
66#else
67 switch(fmt)
68 {
69 case AV_PIX_FMT_VAAPI:
70 case AV_PIX_FMT_VDPAU:
71 case AV_PIX_FMT_DXVA2_VLD:
72 case AV_PIX_FMT_D3D11:
73 case AV_PIX_FMT_CUDA:
74 case AV_PIX_FMT_QSV:
75 case AV_PIX_FMT_VIDEOTOOLBOX:
76 case AV_PIX_FMT_DRM_PRIME:
77 return true;
78 default:
79 return false;
80 }
81#endif
82}
83
84inline constexpr bool formatNeedsDecoding(AVPixelFormat fmt) noexcept
85{
86 // They all get translated to some NV12 or something like that
87 if(formatIsHardwareDecoded(fmt))
88 return false;
89
90 switch(fmt)
91 {
92 case AV_PIX_FMT_YUV420P:
93 case AV_PIX_FMT_RGB24:
94 case AV_PIX_FMT_BGR24:
95 case AV_PIX_FMT_NV12:
96 case AV_PIX_FMT_NV21:
97 case AV_PIX_FMT_YUVJ420P:
98 case AV_PIX_FMT_YUVJ422P:
99 case AV_PIX_FMT_YUV422P:
100 case AV_PIX_FMT_UYVY422:
101 case AV_PIX_FMT_YUYV422:
102 case AV_PIX_FMT_RGB0:
103 case AV_PIX_FMT_RGBA:
104 case AV_PIX_FMT_BGR0:
105 case AV_PIX_FMT_BGRA:
106 case AV_PIX_FMT_ARGB:
107 case AV_PIX_FMT_ABGR:
108
109#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 19, 100)
110 case AV_PIX_FMT_YUV420P10LE:
111 case AV_PIX_FMT_YUV420P12LE:
112 case AV_PIX_FMT_YUV422P10LE:
113 case AV_PIX_FMT_YUV422P12LE:
114 case AV_PIX_FMT_GBRPF32LE:
115 case AV_PIX_FMT_GBRAPF32LE:
116 case AV_PIX_FMT_GRAYF32LE:
117 case AV_PIX_FMT_GRAYF32BE:
118#endif
119
120#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(60, 8, 100)
121 case AV_PIX_FMT_GRAYF16LE:
122 case AV_PIX_FMT_GRAYF16BE:
123#endif
124
125 case AV_PIX_FMT_GRAY8:
126 case AV_PIX_FMT_GRAY16:
127 return false;
128
129 // Other formats get rgb'd
130 default:
131 return true;
132 }
133}
134
135#if LIBAVUTIL_VERSION_MAJOR >= 57
136// Get hardware pix format
137struct HWAccelFormats
138{
139 AVPixelFormat format{AV_PIX_FMT_NONE};
140 AVHWDeviceType device{AV_HWDEVICE_TYPE_NONE};
141};
142
143inline constexpr HWAccelFormats ffmpegHardwareDecodingFormats(AVPixelFormat p) noexcept
144{
145 switch(p)
146 {
147#if defined(__linux__)
148 case AV_PIX_FMT_DRM_PRIME:
149 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_DRM_PRIME))
150 return {};
151 return {AV_PIX_FMT_DRM_PRIME, AV_HWDEVICE_TYPE_DRM};
152 case AV_PIX_FMT_VAAPI:
153 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_VAAPI))
154 return {};
155 return {AV_PIX_FMT_VAAPI, AV_HWDEVICE_TYPE_VAAPI};
156 case AV_PIX_FMT_VDPAU:
157 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_VDPAU))
158 return {};
159 return {AV_PIX_FMT_VDPAU, AV_HWDEVICE_TYPE_VDPAU};
160#endif
161#if defined(_WIN32)
162 case AV_PIX_FMT_DXVA2_VLD:
163 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_DXVA2_VLD))
164 return {};
165 return {AV_PIX_FMT_DXVA2_VLD, AV_HWDEVICE_TYPE_DXVA2};
166 case AV_PIX_FMT_D3D11:
167 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_D3D11))
168 return {};
169 return {AV_PIX_FMT_D3D11, AV_HWDEVICE_TYPE_D3D11VA};
170#endif
171#if defined(__APPLE__)
172 case AV_PIX_FMT_VIDEOTOOLBOX:
173 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_VIDEOTOOLBOX))
174 return {};
175 return {AV_PIX_FMT_VIDEOTOOLBOX, AV_HWDEVICE_TYPE_VIDEOTOOLBOX};
176#endif
177 // Cross-platform pix formats
178 case AV_PIX_FMT_CUDA:
179 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_CUDA))
180 return {};
181 return {AV_PIX_FMT_CUDA, AV_HWDEVICE_TYPE_CUDA};
182 case AV_PIX_FMT_QSV:
183 if(!hardwareDecoderIsAvailable(AV_PIX_FMT_QSV))
184 return {};
185 return {AV_PIX_FMT_QSV, AV_HWDEVICE_TYPE_QSV};
186 // case AV_PIX_FMT_VULKAN:
187 // return {AV_PIX_FMT_VULKAN, AV_HWDEVICE_TYPE_VULKAN};
188 // case AV_PIX_FMT_OPENCL:
189 // return {AV_PIX_FMT_OPENCL, AV_HWDEVICE_TYPE_OPENCL};
190 default:
191 return {};
192 }
193}
194
195inline constexpr bool ffmpegCanDoHardwareDecoding(AVCodecID id) noexcept
196{
197 switch(id)
198 {
199 case AV_CODEC_ID_AV1:
200 case AV_CODEC_ID_H264:
201 case AV_CODEC_ID_HEVC:
202 case AV_CODEC_ID_MJPEG:
203 case AV_CODEC_ID_MPEG1VIDEO:
204 case AV_CODEC_ID_MPEG2VIDEO:
205 case AV_CODEC_ID_MPEG4:
206 case AV_CODEC_ID_VC1:
207 case AV_CODEC_ID_VP8:
208 case AV_CODEC_ID_VP9:
209 case AV_CODEC_ID_WMV1:
210 case AV_CODEC_ID_WMV2:
211 case AV_CODEC_ID_WMV3:
212 return true;
213 default:
214 return false;
215 }
216}
217#endif
218}
219
220#endif