Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qpipewire_videoformat_support.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <algorithm>
7#include <cmath>
8
9QT_BEGIN_NAMESPACE
10
11namespace QtPipeWire {
12
14{
15 // NTSC rates get special handling if it seems like the user wants them
16 const std::initializer_list<FrameRate> ntscRates = {
17 { 23.976, SPA_FRACTION(24'000, 1'001) },
18 { 29.97, SPA_FRACTION(30'000, 1'001) },
19 { 59.94, SPA_FRACTION(60'000, 1'001) },
20 };
21 // NOTE: One could assume that a requested 60.f mapped to 60000/1001.
22 // TODO: There's also other rates (59.97, 49.99, etc..)
23
24 for (const FrameRate &rate : ntscRates) {
25 constexpr float precision = 0.01f;
26 if (std::abs(fps - rate.fps) < precision)
27 return rate;
28 }
29
30 // By default, round to a whole number fps. Rounding down is safest,
31 // but avoid 0/1, which isn't accepted as a maximum rate
32 quint32 roundedFps = std::max(std::floor(fps), 1.);
33 return FrameRate{
34 .fps = qreal(roundedFps),
35 .frac = SPA_FRACTION(roundedFps, 1),
36 };
37}
38
39QVideoFrameFormat::PixelFormat toQtPixelFormat(spa_video_format spaVideoFormat)
40{
41 switch (spaVideoFormat) {
42 default:
43 break;
44 case SPA_VIDEO_FORMAT_I420:
45 return QVideoFrameFormat::Format_YUV420P;
46 case SPA_VIDEO_FORMAT_Y42B:
47 return QVideoFrameFormat::Format_YUV422P;
48 case SPA_VIDEO_FORMAT_YV12:
49 return QVideoFrameFormat::Format_YV12;
50 case SPA_VIDEO_FORMAT_UYVY:
51 return QVideoFrameFormat::Format_UYVY;
52 case SPA_VIDEO_FORMAT_YUY2:
53 return QVideoFrameFormat::Format_YUYV;
54 case SPA_VIDEO_FORMAT_NV12:
55 return QVideoFrameFormat::Format_NV12;
56 case SPA_VIDEO_FORMAT_NV21:
57 return QVideoFrameFormat::Format_NV21;
58 case SPA_VIDEO_FORMAT_AYUV:
59 return QVideoFrameFormat::Format_AYUV;
60 case SPA_VIDEO_FORMAT_GRAY8:
61 return QVideoFrameFormat::Format_Y8;
62 case SPA_VIDEO_FORMAT_xRGB:
63 return QVideoFrameFormat::Format_XRGB8888;
64 case SPA_VIDEO_FORMAT_xBGR:
65 return QVideoFrameFormat::Format_XBGR8888;
66 case SPA_VIDEO_FORMAT_RGBx:
67 return QVideoFrameFormat::Format_RGBX8888;
68 case SPA_VIDEO_FORMAT_BGRx:
69 return QVideoFrameFormat::Format_BGRX8888;
70 case SPA_VIDEO_FORMAT_ARGB:
71 return QVideoFrameFormat::Format_ARGB8888;
72 case SPA_VIDEO_FORMAT_ABGR:
73 return QVideoFrameFormat::Format_ABGR8888;
74 case SPA_VIDEO_FORMAT_RGBA:
75 return QVideoFrameFormat::Format_RGBA8888;
76 case SPA_VIDEO_FORMAT_BGRA:
77 return QVideoFrameFormat::Format_BGRA8888;
78#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
79 case SPA_VIDEO_FORMAT_GRAY16_LE:
80 return QVideoFrameFormat::Format_Y16;
81 case SPA_VIDEO_FORMAT_P010_10LE:
82 return QVideoFrameFormat::Format_P010;
83#else
84 case SPA_VIDEO_FORMAT_GRAY16_BE:
85 return QVideoFrameFormat::Format_Y16;
86 case SPA_VIDEO_FORMAT_P010_10BE:
87 return QVideoFrameFormat::Format_P010;
88#endif
89 }
90
91 return QVideoFrameFormat::Format_Invalid;
92}
93
94spa_video_format toSpaVideoFormat(QVideoFrameFormat::PixelFormat pixelFormat)
95{
96 switch (pixelFormat) {
97 default:
98 break;
99 case QVideoFrameFormat::Format_YUV420P:
100 return SPA_VIDEO_FORMAT_I420;
101 case QVideoFrameFormat::Format_YUV422P:
102 return SPA_VIDEO_FORMAT_Y42B;
103 case QVideoFrameFormat::Format_YV12:
104 return SPA_VIDEO_FORMAT_YV12;
105 case QVideoFrameFormat::Format_UYVY:
106 return SPA_VIDEO_FORMAT_UYVY;
107 case QVideoFrameFormat::Format_YUYV:
108 return SPA_VIDEO_FORMAT_YUY2;
109 case QVideoFrameFormat::Format_NV12:
110 return SPA_VIDEO_FORMAT_NV12;
111 case QVideoFrameFormat::Format_NV21:
112 return SPA_VIDEO_FORMAT_NV21;
113 case QVideoFrameFormat::Format_AYUV:
114 return SPA_VIDEO_FORMAT_AYUV;
115 case QVideoFrameFormat::Format_Y8:
116 return SPA_VIDEO_FORMAT_GRAY8;
117 case QVideoFrameFormat::Format_XRGB8888:
118 return SPA_VIDEO_FORMAT_xRGB;
119 case QVideoFrameFormat::Format_XBGR8888:
120 return SPA_VIDEO_FORMAT_xBGR;
121 case QVideoFrameFormat::Format_RGBX8888:
122 return SPA_VIDEO_FORMAT_RGBx;
123 case QVideoFrameFormat::Format_BGRX8888:
124 return SPA_VIDEO_FORMAT_BGRx;
125 case QVideoFrameFormat::Format_ARGB8888:
126 return SPA_VIDEO_FORMAT_ARGB;
127 case QVideoFrameFormat::Format_ABGR8888:
128 return SPA_VIDEO_FORMAT_ABGR;
129 case QVideoFrameFormat::Format_RGBA8888:
130 return SPA_VIDEO_FORMAT_RGBA;
131 case QVideoFrameFormat::Format_BGRA8888:
132 return SPA_VIDEO_FORMAT_BGRA;
133#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
134 case QVideoFrameFormat::Format_Y16:
135 return SPA_VIDEO_FORMAT_GRAY16_LE;
136 case QVideoFrameFormat::Format_P010:
137 return SPA_VIDEO_FORMAT_P010_10LE;
138#else
139 case QVideoFrameFormat::Format_Y16:
140 return SPA_VIDEO_FORMAT_GRAY16_BE;
141 case QVideoFrameFormat::Format_P010:
142 return SPA_VIDEO_FORMAT_P010_10BE;
143#endif
144 }
145
146 return SPA_VIDEO_FORMAT_UNKNOWN;
147}
148
149} // namespace QtPipeWire
150
151QT_END_NAMESPACE
spa_video_format toSpaVideoFormat(QVideoFrameFormat::PixelFormat pixelFormat)
FrameRate rateFromFps(qreal fps)
QVideoFrameFormat::PixelFormat toQtPixelFormat(spa_video_format spaVideoFormat)