16#include <Gfx/Graph/interop/DrmFourcc.hpp>
18#include <pipewire/pipewire.h>
19#include <spa/param/video/format-utils.h>
22#include <libavutil/pixfmt.h>
25#include <private/qrhi_p.h>
32namespace Gfx::PipeWire::formats
42enum class Tag : uint8_t
64inline QString tagToString(Tag t)
noexcept
68 case Tag::RGBA8:
return QStringLiteral(
"rgba8");
69 case Tag::BGRA8:
return QStringLiteral(
"bgra8");
70 case Tag::RGB10A2:
return QStringLiteral(
"rgb10a2");
71 case Tag::BGR10A2:
return QStringLiteral(
"bgr10a2");
72 case Tag::RGBA16F:
return QStringLiteral(
"rgba16f");
73 case Tag::RGBA32F:
return QStringLiteral(
"rgba32f");
74 case Tag::P010:
return QStringLiteral(
"p010");
75 case Tag::P210:
return QStringLiteral(
"p210");
76 case Tag::YUV420P:
return QStringLiteral(
"yuv420p");
77 case Tag::YV12:
return QStringLiteral(
"yv12");
78 case Tag::NV12:
return QStringLiteral(
"nv12");
79 case Tag::YUYV422:
return QStringLiteral(
"yuyv422");
80 case Tag::UYVY422:
return QStringLiteral(
"uyvy422");
81 case Tag::RGB24:
return QStringLiteral(
"rgb24");
82 case Tag::Unknown:
break;
84 return QStringLiteral(
"rgba8");
88inline QStringList allTagNames()
91 for(
int i = 0; i < int(Tag::Unknown); i++)
92 r += tagToString(Tag(i));
99inline QStringList renderableTagNames()
102 for(
auto t : {Tag::RGBA8, Tag::BGRA8, Tag::RGB10A2, Tag::BGR10A2, Tag::RGBA16F,
110inline Tag tagFromString(
const QString& s)
112 const QString k = s.toLower();
113 if(k ==
"rgba8" || k ==
"rgba")
115 if(k ==
"bgra8" || k ==
"bgra")
121 if(k ==
"rgba16f" || k ==
"rgba_f16")
123 if(k ==
"rgba32f" || k ==
"rgba_f32")
129 if(k ==
"yuv420p" || k ==
"i420")
135 if(k ==
"yuyv422" || k ==
"yuy2")
137 if(k ==
"uyvy422" || k ==
"uyvy")
139 if(k ==
"rgb24" || k ==
"rgb")
145inline spa_video_format toSpa(Tag t)
149 case Tag::RGBA8:
return SPA_VIDEO_FORMAT_RGBA;
150 case Tag::BGRA8:
return SPA_VIDEO_FORMAT_BGRA;
151 case Tag::RGB10A2:
return SPA_VIDEO_FORMAT_xRGB_210LE;
152 case Tag::BGR10A2:
return SPA_VIDEO_FORMAT_xBGR_210LE;
153 case Tag::RGBA16F:
return SPA_VIDEO_FORMAT_RGBA_F16;
154 case Tag::RGBA32F:
return SPA_VIDEO_FORMAT_RGBA_F32;
155 case Tag::P010:
return SPA_VIDEO_FORMAT_P010_10LE;
156 case Tag::P210:
return SPA_VIDEO_FORMAT_P010_10LE;
157 case Tag::YUV420P:
return SPA_VIDEO_FORMAT_I420;
158 case Tag::YV12:
return SPA_VIDEO_FORMAT_YV12;
159 case Tag::NV12:
return SPA_VIDEO_FORMAT_NV12;
160 case Tag::YUYV422:
return SPA_VIDEO_FORMAT_YUY2;
161 case Tag::UYVY422:
return SPA_VIDEO_FORMAT_UYVY;
162 case Tag::RGB24:
return SPA_VIDEO_FORMAT_RGB;
163 case Tag::Unknown:
break;
165 return SPA_VIDEO_FORMAT_RGBA;
170inline Tag tagFromSpa(uint32_t fmt)
174 case SPA_VIDEO_FORMAT_RGBA:
return Tag::RGBA8;
175 case SPA_VIDEO_FORMAT_BGRA:
return Tag::BGRA8;
176 case SPA_VIDEO_FORMAT_xRGB_210LE:
return Tag::RGB10A2;
177 case SPA_VIDEO_FORMAT_xBGR_210LE:
return Tag::BGR10A2;
178 case SPA_VIDEO_FORMAT_RGBA_F16:
return Tag::RGBA16F;
179 case SPA_VIDEO_FORMAT_RGBA_F32:
return Tag::RGBA32F;
180 case SPA_VIDEO_FORMAT_P010_10LE:
return Tag::P010;
181 case SPA_VIDEO_FORMAT_YV12:
return Tag::YV12;
182 case SPA_VIDEO_FORMAT_I420:
return Tag::YUV420P;
183 case SPA_VIDEO_FORMAT_NV12:
return Tag::NV12;
184 case SPA_VIDEO_FORMAT_YUY2:
return Tag::YUYV422;
185 case SPA_VIDEO_FORMAT_UYVY:
return Tag::UYVY422;
186 case SPA_VIDEO_FORMAT_RGB:
return Tag::RGB24;
187 default:
return Tag::Unknown;
194inline AVPixelFormat toAvPixFmt(Tag t)
198 case Tag::RGBA8:
return AV_PIX_FMT_RGBA;
199 case Tag::BGRA8:
return AV_PIX_FMT_BGRA;
200 case Tag::RGB10A2:
return AV_PIX_FMT_X2RGB10LE;
201 case Tag::BGR10A2:
return AV_PIX_FMT_X2BGR10LE;
206 return AV_PIX_FMT_RGBA64LE;
207 case Tag::RGBA32F:
return AV_PIX_FMT_NONE;
208 case Tag::P010:
return AV_PIX_FMT_P010LE;
209 case Tag::P210:
return AV_PIX_FMT_P210LE;
210 case Tag::YUV420P:
return AV_PIX_FMT_YUV420P;
213 case Tag::YV12:
return AV_PIX_FMT_YUV420P;
214 case Tag::NV12:
return AV_PIX_FMT_NV12;
215 case Tag::YUYV422:
return AV_PIX_FMT_YUYV422;
216 case Tag::UYVY422:
return AV_PIX_FMT_UYVY422;
217 case Tag::RGB24:
return AV_PIX_FMT_RGB24;
218 case Tag::Unknown:
break;
220 return AV_PIX_FMT_NONE;
223inline Tag tagFromAvPixFmt(AVPixelFormat fmt)
227 case AV_PIX_FMT_RGBA:
return Tag::RGBA8;
228 case AV_PIX_FMT_BGRA:
return Tag::BGRA8;
229 case AV_PIX_FMT_X2RGB10LE:
return Tag::RGB10A2;
230 case AV_PIX_FMT_X2BGR10LE:
return Tag::BGR10A2;
231 case AV_PIX_FMT_RGBA64LE:
return Tag::RGBA16F;
232 case AV_PIX_FMT_P010LE:
return Tag::P010;
233 case AV_PIX_FMT_P210LE:
return Tag::P210;
234 case AV_PIX_FMT_YUV420P:
return Tag::YUV420P;
235 case AV_PIX_FMT_NV12:
return Tag::NV12;
236 case AV_PIX_FMT_YUYV422:
return Tag::YUYV422;
237 case AV_PIX_FMT_UYVY422:
return Tag::UYVY422;
238 case AV_PIX_FMT_RGB24:
return Tag::RGB24;
239 default:
return Tag::Unknown;
245inline QRhiTexture::Format toQRhi(Tag t)
249 case Tag::RGBA8:
return QRhiTexture::RGBA8;
250 case Tag::BGRA8:
return QRhiTexture::BGRA8;
252 case Tag::BGR10A2:
return QRhiTexture::RGB10A2;
253 case Tag::RGBA16F:
return QRhiTexture::RGBA16F;
254 case Tag::RGBA32F:
return QRhiTexture::RGBA32F;
258 default:
return QRhiTexture::RGBA8;
265inline uint32_t bytesPerPixel(Tag t)
272 case Tag::BGR10A2:
return 4;
274 case Tag::UYVY422:
return 2;
275 case Tag::RGBA16F:
return 8;
276 case Tag::RGBA32F:
return 16;
278 case Tag::P210:
return 2;
281 case Tag::NV12:
return 1;
282 case Tag::RGB24:
return 3;
283 case Tag::Unknown:
break;
292inline uint64_t frameBytes(Tag t,
int w,
int h)
noexcept
294 const uint64_t wh = uint64_t(w) * uint64_t(h);
296 const uint64_t cw = uint64_t(w + 1) / 2;
297 const uint64_t ch = uint64_t(h + 1) / 2;
302 case Tag::YUV420P:
return wh + 2 * cw * ch;
303 case Tag::P010:
return 2 * (wh + 2 * cw * ch);
304 case Tag::P210:
return 2 * (wh + 2 * cw * uint64_t(h));
306 case Tag::UYVY422:
return 4 * cw * uint64_t(h);
307 default:
return wh * bytesPerPixel(t);
315inline bool isPlanar(Tag t)
noexcept
336inline uint32_t toDrmFourcc(Tag t)
noexcept
340 return score::gfx::interop::DRM_P210;
341 return score::gfx::interop::spaToDrmFourcc(toSpa(t));