Loading...
Searching...
No Matches
GStreamerCompatibility.hpp
1#pragma once
2#include <Media/Libav.hpp>
3#if SCORE_HAS_LIBAV
4#include <ossia/detail/hash_map.hpp>
5
6#include <QDebug>
7
8#include <score_plugin_media_export.h>
9
10#include <array>
11#include <charconv>
12#include <optional>
13#include <string>
14#include <string_view>
15#include <utility>
16
17extern "C" {
18#include <libavformat/avformat.h>
19#include <libavutil/imgutils.h>
20#include <libavutil/pixdesc.h>
21}
22
23namespace Video
24{
25
27{
28 std::string format;
29 int width{};
30 int height{};
31 double rate{};
32};
33
43inline std::optional<RawVideoCaps> parseRawVideoCaps(std::string_view caps)
44{
45 auto trim = [](std::string_view v) {
46 while(!v.empty() && v.front() == ' ')
47 v.remove_prefix(1);
48 while(!v.empty() && v.back() == ' ')
49 v.remove_suffix(1);
50 return v;
51 };
52 auto value = [&](std::string_view v) {
53 v = trim(v);
54 if(!v.empty() && v.front() == '(')
55 if(auto end = v.find(')'); end != v.npos)
56 v.remove_prefix(end + 1);
57 return trim(v);
58 };
59 auto to_int = [](std::string_view v) {
60 int i = 0;
61 std::from_chars(v.data(), v.data() + v.size(), i);
62 return i;
63 };
64
65 RawVideoCaps res;
66 bool first = true;
67 while(!caps.empty())
68 {
69 const auto comma = caps.find(',');
70 const auto field = trim(caps.substr(0, comma));
71 caps = comma == caps.npos ? std::string_view{} : caps.substr(comma + 1);
72 if(std::exchange(first, false))
73 {
74 if(field != "video/x-raw")
75 return std::nullopt;
76 continue;
77 }
78 const auto eq = field.find('=');
79 if(eq == field.npos)
80 continue;
81 const auto key = trim(field.substr(0, eq));
82 const auto val = value(field.substr(eq + 1));
83 if(key == "format")
84 res.format = val;
85 else if(key == "width")
86 res.width = to_int(val);
87 else if(key == "height")
88 res.height = to_int(val);
89 else if(key == "framerate")
90 {
91 const auto slash = val.find('/');
92 const int num = to_int(val.substr(0, slash));
93 const int den = slash == val.npos ? 1 : to_int(val.substr(slash + 1));
94 res.rate = den > 0 ? double(num) / den : 0.;
95 }
96 }
97 if(res.format.empty() || res.width < 1 || res.height < 1 || res.rate <= 0.)
98 return std::nullopt;
99 return res;
100}
101
102inline const ossia::hash_map<std::string, AVPixelFormat>& gstreamerToLibav()
103{
104 static const auto map = [] {
105 ossia::hash_map<std::string, AVPixelFormat> format_map;
106
107 /*
108 * @GST_VIDEO_FORMAT_I420: planar 4:2:0 YUV
109 * @GST_VIDEO_FORMAT_YV12: planar 4:2:0 YVU (like I420 but UV planes swapped)
110 * @GST_VIDEO_FORMAT_YUY2: packed 4:2:2 YUV (Y0-U0-Y1-V0 Y2-U2-Y3-V2 Y4 ...)
111 * @GST_VIDEO_FORMAT_UYVY: packed 4:2:2 YUV (U0-Y0-V0-Y1 U2-Y2-V2-Y3 U4 ...)
112 * @GST_VIDEO_FORMAT_VYUY: packed 4:2:2 YUV (V0-Y0-U0-Y1 V2-Y2-U2-Y3 V4 ...)
113 * @GST_VIDEO_FORMAT_AYUV: packed 4:4:4 YUV with alpha channel (A0-Y0-U0-V0 ...)
114 * @GST_VIDEO_FORMAT_RGBx: sparse rgb packed into 32 bit, space last
115 * @GST_VIDEO_FORMAT_BGRx: sparse reverse rgb packed into 32 bit, space last
116 * @GST_VIDEO_FORMAT_xRGB: sparse rgb packed into 32 bit, space first
117 * @GST_VIDEO_FORMAT_xBGR: sparse reverse rgb packed into 32 bit, space first
118 * @GST_VIDEO_FORMAT_RGBA: rgb with alpha channel last
119 * @GST_VIDEO_FORMAT_BGRA: reverse rgb with alpha channel last
120 * @GST_VIDEO_FORMAT_ARGB: rgb with alpha channel first
121 * @GST_VIDEO_FORMAT_ABGR: reverse rgb with alpha channel first
122 * @GST_VIDEO_FORMAT_RGB: RGB packed into 24 bits without padding (`R-G-B-R-G-B`)
123 * @GST_VIDEO_FORMAT_BGR: reverse RGB packed into 24 bits without padding (`B-G-R-B-G-R`)
124 * @GST_VIDEO_FORMAT_Y41B: planar 4:1:1 YUV
125 * @GST_VIDEO_FORMAT_Y42B: planar 4:2:2 YUV
126 * @GST_VIDEO_FORMAT_YVYU: packed 4:2:2 YUV (Y0-V0-Y1-U0 Y2-V2-Y3-U2 Y4 ...)
127 * @GST_VIDEO_FORMAT_Y444: planar 4:4:4 YUV
128 * @GST_VIDEO_FORMAT_v210: packed 4:2:2 10-bit YUV, complex format
129 * @GST_VIDEO_FORMAT_v216: packed 4:2:2 16-bit YUV, Y0-U0-Y1-V1 order
130 * @GST_VIDEO_FORMAT_NV12: planar 4:2:0 YUV with interleaved UV plane
131 * @GST_VIDEO_FORMAT_NV21: planar 4:2:0 YUV with interleaved VU plane
132 * @GST_VIDEO_FORMAT_NV12_10LE32: 10-bit variant of @GST_VIDEO_FORMAT_NV12, packed into 32bit words (MSB 2 bits padding) (Since: 1.14)
133 * @GST_VIDEO_FORMAT_GRAY8: 8-bit grayscale
134 * @GST_VIDEO_FORMAT_GRAY10_LE32: 10-bit grayscale, packed into 32bit words (2 bits padding) (Since: 1.14)
135 * @GST_VIDEO_FORMAT_GRAY16_BE: 16-bit grayscale, most significant byte first
136 * @GST_VIDEO_FORMAT_GRAY16_LE: 16-bit grayscale, least significant byte first
137 * @GST_VIDEO_FORMAT_v308: packed 4:4:4 YUV (Y-U-V ...)
138 * @GST_VIDEO_FORMAT_IYU2: packed 4:4:4 YUV (U-Y-V ...) (Since: 1.10)
139 * @GST_VIDEO_FORMAT_RGB16: rgb 5-6-5 bits per component
140 * @GST_VIDEO_FORMAT_BGR16: reverse rgb 5-6-5 bits per component
141 * @GST_VIDEO_FORMAT_RGB15: rgb 5-5-5 bits per component
142 * @GST_VIDEO_FORMAT_BGR15: reverse rgb 5-5-5 bits per component
143 * @GST_VIDEO_FORMAT_UYVP: packed 10-bit 4:2:2 YUV (U0-Y0-V0-Y1 U2-Y2-V2-Y3 U4 ...)
144 * @GST_VIDEO_FORMAT_A420: planar 4:4:2:0 AYUV
145 * @GST_VIDEO_FORMAT_RGB8P: 8-bit paletted RGB
146 * @GST_VIDEO_FORMAT_YUV9: planar 4:1:0 YUV
147 * @GST_VIDEO_FORMAT_YVU9: planar 4:1:0 YUV (like YUV9 but UV planes swapped)
148 * @GST_VIDEO_FORMAT_IYU1: packed 4:1:1 YUV (Cb-Y0-Y1-Cr-Y2-Y3 ...)
149 * @GST_VIDEO_FORMAT_ARGB64: rgb with alpha channel first, 16 bits per channel
150 * @GST_VIDEO_FORMAT_AYUV64: packed 4:4:4 YUV with alpha channel, 16 bits per channel (A0-Y0-U0-V0 ...)
151 * @GST_VIDEO_FORMAT_r210: packed 4:4:4 RGB, 10 bits per channel
152 * @GST_VIDEO_FORMAT_I420_10BE: planar 4:2:0 YUV, 10 bits per channel
153 * @GST_VIDEO_FORMAT_I420_10LE: planar 4:2:0 YUV, 10 bits per channel
154 * @GST_VIDEO_FORMAT_I422_10BE: planar 4:2:2 YUV, 10 bits per channel
155 * @GST_VIDEO_FORMAT_I422_10LE: planar 4:2:2 YUV, 10 bits per channel
156 * @GST_VIDEO_FORMAT_Y444_10BE: planar 4:4:4 YUV, 10 bits per channel (Since: 1.2)
157 * @GST_VIDEO_FORMAT_Y444_10LE: planar 4:4:4 YUV, 10 bits per channel (Since: 1.2)
158 * @GST_VIDEO_FORMAT_GBR: planar 4:4:4 RGB, 8 bits per channel (Since: 1.2)
159 * @GST_VIDEO_FORMAT_GBR_10BE: planar 4:4:4 RGB, 10 bits per channel (Since: 1.2)
160 * @GST_VIDEO_FORMAT_GBR_10LE: planar 4:4:4 RGB, 10 bits per channel (Since: 1.2)
161 * @GST_VIDEO_FORMAT_NV16: planar 4:2:2 YUV with interleaved UV plane (Since: 1.2)
162 * @GST_VIDEO_FORMAT_NV16_10LE32: 10-bit variant of @GST_VIDEO_FORMAT_NV16, packed into 32bit words (MSB 2 bits padding) (Since: 1.14)
163 * @GST_VIDEO_FORMAT_NV24: planar 4:4:4 YUV with interleaved UV plane (Since: 1.2)
164 * @GST_VIDEO_FORMAT_NV12_64Z32: NV12 with 64x32 tiling in zigzag pattern (Since: 1.4)
165 * @GST_VIDEO_FORMAT_A420_10BE: planar 4:4:2:0 YUV, 10 bits per channel (Since: 1.6)
166 * @GST_VIDEO_FORMAT_A420_10LE: planar 4:4:2:0 YUV, 10 bits per channel (Since: 1.6)
167 * @GST_VIDEO_FORMAT_A422_10BE: planar 4:4:2:2 YUV, 10 bits per channel (Since: 1.6)
168 * @GST_VIDEO_FORMAT_A422_10LE: planar 4:4:2:2 YUV, 10 bits per channel (Since: 1.6)
169 * @GST_VIDEO_FORMAT_A444_10BE: planar 4:4:4:4 YUV, 10 bits per channel (Since: 1.6)
170 * @GST_VIDEO_FORMAT_A444_10LE: planar 4:4:4:4 YUV, 10 bits per channel (Since: 1.6)
171 * @GST_VIDEO_FORMAT_NV61: planar 4:2:2 YUV with interleaved VU plane (Since: 1.6)
172 * @GST_VIDEO_FORMAT_P010_10BE: planar 4:2:0 YUV with interleaved UV plane, 10 bits per channel (Since: 1.10)
173 * @GST_VIDEO_FORMAT_P010_10LE: planar 4:2:0 YUV with interleaved UV plane, 10 bits per channel (Since: 1.10)
174 * @GST_VIDEO_FORMAT_GBRA: planar 4:4:4:4 ARGB, 8 bits per channel (Since: 1.12)
175 * @GST_VIDEO_FORMAT_GBRA_10BE: planar 4:4:4:4 ARGB, 10 bits per channel (Since: 1.12)
176 * @GST_VIDEO_FORMAT_GBRA_10LE: planar 4:4:4:4 ARGB, 10 bits per channel (Since: 1.12)
177 * @GST_VIDEO_FORMAT_GBR_12BE: planar 4:4:4 RGB, 12 bits per channel (Since: 1.12)
178 * @GST_VIDEO_FORMAT_GBR_12LE: planar 4:4:4 RGB, 12 bits per channel (Since: 1.12)
179 * @GST_VIDEO_FORMAT_GBRA_12BE: planar 4:4:4:4 ARGB, 12 bits per channel (Since: 1.12)
180 * @GST_VIDEO_FORMAT_GBRA_12LE: planar 4:4:4:4 ARGB, 12 bits per channel (Since: 1.12)
181 * @GST_VIDEO_FORMAT_I420_12BE: planar 4:2:0 YUV, 12 bits per channel (Since: 1.12)
182 * @GST_VIDEO_FORMAT_I420_12LE: planar 4:2:0 YUV, 12 bits per channel (Since: 1.12)
183 * @GST_VIDEO_FORMAT_I422_12BE: planar 4:2:2 YUV, 12 bits per channel (Since: 1.12)
184 * @GST_VIDEO_FORMAT_I422_12LE: planar 4:2:2 YUV, 12 bits per channel (Since: 1.12)
185 * @GST_VIDEO_FORMAT_Y444_12BE: planar 4:4:4 YUV, 12 bits per channel (Since: 1.12)
186 * @GST_VIDEO_FORMAT_Y444_12LE: planar 4:4:4 YUV, 12 bits per channel (Since: 1.12)
187 * @GST_VIDEO_FORMAT_NV12_10LE40: Fully packed variant of NV12_10LE32 (Since: 1.16)
188 * @GST_VIDEO_FORMAT_Y210: packed 4:2:2 YUV, 10 bits per channel (Since: 1.16)
189 * @GST_VIDEO_FORMAT_Y410: packed 4:4:4 YUV, 10 bits per channel(A-V-Y-U...) (Since: 1.16)
190 * @GST_VIDEO_FORMAT_VUYA: packed 4:4:4 YUV with alpha channel (V0-U0-Y0-A0...) (Since: 1.16)
191 * @GST_VIDEO_FORMAT_BGR10A2_LE: packed 4:4:4 RGB with alpha channel(B-G-R-A), 10 bits for R/G/B channel and MSB 2 bits for alpha channel (Since: 1.16)
192 * @GST_VIDEO_FORMAT_RGB10A2_LE: packed 4:4:4 RGB with alpha channel(R-G-B-A), 10 bits for R/G/B channel and MSB 2 bits for alpha channel (Since: 1.18)
193 * @GST_VIDEO_FORMAT_Y444_16BE: planar 4:4:4 YUV, 16 bits per channel (Since: 1.18)
194 * @GST_VIDEO_FORMAT_Y444_16LE: planar 4:4:4 YUV, 16 bits per channel (Since: 1.18)
195 * @GST_VIDEO_FORMAT_P016_BE: planar 4:2:0 YUV with interleaved UV plane, 16 bits per channel (Since: 1.18)
196 * @GST_VIDEO_FORMAT_P016_LE: planar 4:2:0 YUV with interleaved UV plane, 16 bits per channel (Since: 1.18)
197 * @GST_VIDEO_FORMAT_P012_BE: planar 4:2:0 YUV with interleaved UV plane, 12 bits per channel (Since: 1.18)
198 * @GST_VIDEO_FORMAT_P012_LE: planar 4:2:0 YUV with interleaved UV plane, 12 bits per channel (Since: 1.18)
199 * @GST_VIDEO_FORMAT_Y212_BE: packed 4:2:2 YUV, 12 bits per channel (Y-U-Y-V) (Since: 1.18)
200 * @GST_VIDEO_FORMAT_Y212_LE: packed 4:2:2 YUV, 12 bits per channel (Y-U-Y-V) (Since: 1.18)
201 * @GST_VIDEO_FORMAT_Y412_BE: packed 4:4:4:4 YUV, 12 bits per channel(U-Y-V-A...) (Since: 1.18)
202 * @GST_VIDEO_FORMAT_Y412_LE: packed 4:4:4:4 YUV, 12 bits per channel(U-Y-V-A...) (Since: 1.18)
203 * @GST_VIDEO_FORMAT_NV12_4L4: NV12 with 4x4 tiles in linear order (Since: 1.18)
204 * @GST_VIDEO_FORMAT_NV12_32L32: NV12 with 32x32 tiles in linear order (Since: 1.18)
205 * @GST_VIDEO_FORMAT_RGBP: planar 4:4:4 RGB, 8 bits per channel (Since: 1.20)
206 * @GST_VIDEO_FORMAT_BGRP: planar 4:4:4 RGB, 8 bits per channel (Since: 1.20)
207 * @GST_VIDEO_FORMAT_AV12: Planar 4:2:0 YUV with interleaved UV plane with alpha as 3rd plane (Since: 1.20)
208 */
209
210 format_map["A420"] = AV_PIX_FMT_YUVA420P;
211 format_map["A420_10BE"] = AV_PIX_FMT_YUVA420P10BE;
212 format_map["A420_10LE"] = AV_PIX_FMT_YUVA420P10LE;
213 format_map["A422_10BE"] = AV_PIX_FMT_YUVA422P10BE;
214 format_map["A422_10LE"] = AV_PIX_FMT_YUVA422P10LE;
215 format_map["A444_10BE"] = AV_PIX_FMT_YUVA444P10BE;
216 format_map["A444_10LE"] = AV_PIX_FMT_YUVA444P10LE;
217 format_map["ABGR"] = AV_PIX_FMT_ABGR;
218 // format_map["ABGR64_BE"] = AV_PIX_FMT_ABGR64BE;
219 // format_map["ABGR64_LE"] = AV_PIX_FMT_ABGR64LE;
220 format_map["ARGB"] = AV_PIX_FMT_ARGB;
221 // format_map["ARGB64"] = AV_PIX_FMT_ARGB64;
222 // format_map["ARGB64_BE"] = AV_PIX_FMT_ARGB64BE;
223 // format_map["ARGB64_LE"] = AV_PIX_FMT_ARGB64LE;
224 // format_map["AV12"] = AV_PIX_FMT_AV12;
225 // format_map["AYUV"] = AV_PIX_FMT_AYUV;
226 format_map["AYUV64"] = AV_PIX_FMT_AYUV64;
227 // format_map["BGR"] = AV_PIX_FMT_BGR;
228 // format_map["BGR10A2_LE"] = AV_PIX_FMT_BGR10A2LE;
229 // format_map["BGR15"] = AV_PIX_FMT_BGR15;
230 // format_map["BGR16"] = AV_PIX_FMT_BGR16;
231 format_map["BGRA"] = AV_PIX_FMT_BGRA;
232 // format_map["BGRA64_BE"] = AV_PIX_FMT_BGRA64BE;
233 // format_map["BGRA64_LE"] = AV_PIX_FMT_BGRA64LE;
234 // format_map["BGRP"] = AV_PIX_FMT_BGRP;
235 format_map["BGRx"] = AV_PIX_FMT_BGR0;
236 // format_map["ENCODED"] = AV_PIX_FMT_ENCODED;
237 format_map["GBR"] = AV_PIX_FMT_GBRP;
238 format_map["GBRA"] = AV_PIX_FMT_GBRAP;
239 // format_map["GBRA_10BE"] = AV_PIX_FMT_GBRA_10BE;
240 // format_map["GBRA_10LE"] = AV_PIX_FMT_GBRA_10LE;
241 // format_map["GBRA_12BE"] = AV_PIX_FMT_GBRA_12BE;
242 // format_map["GBRA_12LE"] = AV_PIX_FMT_GBRA_12LE;
243 // format_map["GBR_10BE"] = AV_PIX_FMT_GBR_10BE;
244 // format_map["GBR_10LE"] = AV_PIX_FMT_GBR_10LE;
245 // format_map["GBR_12BE"] = AV_PIX_FMT_GBR_12BE;
246 // format_map["GBR_12LE"] = AV_PIX_FMT_GBR_12LE;
247 // format_map["GRAY10_LE32"] = AV_PIX_FMT_GRAY10_LE32;
248 format_map["GRAY16_BE"] = AV_PIX_FMT_GRAY16BE;
249 format_map["GRAY16_LE"] = AV_PIX_FMT_GRAY16LE;
250 format_map["GRAY8"] = AV_PIX_FMT_GRAY8;
251 format_map["I420"] = AV_PIX_FMT_YUV420P;
252 format_map["I420_10BE"] = AV_PIX_FMT_YUV420P10BE;
253 format_map["I420_10LE"] = AV_PIX_FMT_YUV420P10LE;
254 format_map["I420_12BE"] = AV_PIX_FMT_YUV420P12BE;
255 format_map["I420_12LE"] = AV_PIX_FMT_YUV420P12LE;
256 format_map["I422_10BE"] = AV_PIX_FMT_YUV422P10BE;
257 format_map["I422_10LE"] = AV_PIX_FMT_YUV422P10LE;
258 format_map["I422_12BE"] = AV_PIX_FMT_YUV422P12BE;
259 format_map["I422_12LE"] = AV_PIX_FMT_YUV422P12LE;
260 // format_map["IYU1"] = AV_PIX_FMT_IYU1;
261 // format_map["IYU2"] = AV_PIX_FMT_IYU2;
262 format_map["NV12"] = AV_PIX_FMT_NV12;
263 // format_map["NV12_10LE32"] = AV_PIX_FMT_NV12_10LE32;
264 // format_map["NV12_10LE40"] = AV_PIX_FMT_NV12_10LE40;
265 // format_map["NV12_32L32"] = AV_PIX_FMT_NV12_32L32;
266 // format_map["NV12_4L4"] = AV_PIX_FMT_NV12_4L4;
267 // format_map["NV12_64Z32"] = AV_PIX_FMT_NV12_64Z32;
268 format_map["NV16"] = AV_PIX_FMT_NV16;
269 // format_map["NV16_10LE32"] = AV_PIX_FMT_NV16_10LE32;
270 format_map["NV21"] = AV_PIX_FMT_NV21;
271 format_map["NV24"] = AV_PIX_FMT_NV24;
272 // format_map["NV61"] = AV_PIX_FMT_NV61;
273 format_map["P010_10BE"] = AV_PIX_FMT_P010BE;
274 format_map["P010_10LE"] = AV_PIX_FMT_P010LE;
275 // format_map["P012_BE"] = AV_PIX_FMT_P012BE;
276 // format_map["P012_LE"] = AV_PIX_FMT_P012LE;
277 format_map["P016_BE"] = AV_PIX_FMT_P016BE;
278 format_map["P016_LE"] = AV_PIX_FMT_P016LE;
279 // format_map["R210"] = AV_PIX_FMT_R210;
280 format_map["RGB"] = AV_PIX_FMT_RGB24;
281 // format_map["RGB10A2_LE"] = AV_PIX_FMT_RGB10A2LE;
282 // format_map["RGB15"] = AV_PIX_FMT_RGB15;
283 // format_map["RGB16"] = AV_PIX_FMT_RGB16;
284 // format_map["RGB8P"] = AV_PIX_FMT_RGB8P;
285 format_map["RGBA"] = AV_PIX_FMT_RGBA;
286 format_map["RGBA64_BE"] = AV_PIX_FMT_RGBA64BE;
287 format_map["RGBA64_LE"] = AV_PIX_FMT_RGBA64LE;
288 // GStreamer RGBP is PLANAR: three separate R, G, B planes. libav has no
289 // R-G-B plane order, only GBRP -- see gstreamerPlaneOrder().
290 format_map["RGBP"] = AV_PIX_FMT_GBRP;
291 format_map["RGBx"] = AV_PIX_FMT_RGB0;
292 // format_map["UNKNOWN"] = AV_PIX_FMT_UNKNOWN;
293 // format_map["UYVP"] = AV_PIX_FMT_UYVP;
294 format_map["UYVY"] = AV_PIX_FMT_UYVY422;
295 // format_map["V210"] = AV_PIX_FMT_V210;
296 // format_map["V216"] = AV_PIX_FMT_V216;
297 // format_map["V308"] = AV_PIX_FMT_V308;
298 // format_map["VUYA"] = AV_PIX_FMT_VUYA;
299 // format_map["VYUY"] = AV_PIX_FMT_VYUY;
300 format_map["xBGR"] = AV_PIX_FMT_0BGR;
301 format_map["xRGB"] = AV_PIX_FMT_0RGB;
302 format_map["Y210"] = AV_PIX_FMT_Y210;
303 // format_map["Y212_BE"] = AV_PIX_FMT_Y212BE;
304 // format_map["Y212_LE"] = AV_PIX_FMT_Y212LE;
305 // GStreamer Y410 is PACKED 4:4:4 10-bit (A-V-Y-U in one 32-bit word).
306 // AV_PIX_FMT_XV30 is libav's name for it with the alpha left undefined;
307 // AV_PIX_FMT_YUV410P is planar 4:1:0 8-bit, i.e. GStreamer "YUV9".
308#if defined(AV_PIX_FMT_XV30)
309 format_map["Y410"] = AV_PIX_FMT_XV30;
310#endif
311 // format_map["Y412_BE"] = AV_PIX_FMT_Y412BE;
312 // format_map["Y412_LE"] = AV_PIX_FMT_Y412LE;
313 format_map["Y41B"] = AV_PIX_FMT_YUV411P;
314 format_map["Y42B"] = AV_PIX_FMT_YUV422P;
315 format_map["Y444"] = AV_PIX_FMT_YUV444P;
316 format_map["Y444_10BE"] = AV_PIX_FMT_YUV444P10BE;
317 format_map["Y444_10LE"] = AV_PIX_FMT_YUV444P10LE;
318 format_map["Y444_12BE"] = AV_PIX_FMT_YUV444P12BE;
319 format_map["Y444_12LE"] = AV_PIX_FMT_YUV444P12LE;
320 format_map["Y444_16BE"] = AV_PIX_FMT_YUV444P16BE;
321 format_map["Y444_16LE"] = AV_PIX_FMT_YUV444P16LE;
322 // format_map["YUV9"] = AV_PIX_FMT_YUV9;
323 format_map["YUY2"] = AV_PIX_FMT_YUYV422;
324 // format_map["YV12"] = AV_PIX_FMT_YV12;
325 // format_map["YVU9"] = AV_PIX_FMT_YVU9;
326 format_map["YVYU"] = AV_PIX_FMT_YVYU422;
327
328 return format_map;
329 }();
330
331 return map;
332}
333
334// Where libav plane N lives in the GStreamer buffer, when the two disagree on
335// plane ORDER for the same set of planes. Identity for every format whose only
336// libav counterpart already agrees.
337//
338// GStreamer RGBP is R,G,B; the only libav planar 8-bit RGB is GBRP, which is
339// G,B,R. Same three planes, same strides, rotated by one.
340using PlaneOrder = std::array<int, 4>;
341inline constexpr PlaneOrder identityPlaneOrder{0, 1, 2, 3};
342
343inline PlaneOrder gstreamerPlaneOrder(std::string_view gstFormat) noexcept
344{
345 if(gstFormat == "RGBP")
346 return {1, 2, 0, 3};
347 return identityPlaneOrder;
348}
349
350// Lays out the planes of `frame` over a flat buffer of `sz` bytes, for the
351// input devices that hand us pixels with no stride information at all.
352//
353// `align` is the row alignment the producer used: 1 for a tightly packed
354// buffer, 4 for the row padding GStreamer applies in its default layout.
355// libav owns every stride and every plane offset here -- av_image_fill_arrays()
356// rounds subsampled planes UP, which is what a frame of odd width needs, and
357// knows the plane count of the semi-planar and packed families.
358[[nodiscard]]
359inline bool
360initFrameFromRawData(AVFrame* frame, uint8_t* p, std::size_t sz, int align)
361{
362 const auto fmt = (AVPixelFormat)frame->format;
363 const int needed
364 = av_image_get_buffer_size(fmt, frame->width, frame->height, align);
365 if(needed < 0 || std::size_t(needed) > sz)
366 {
367 qDebug() << "unhandled video format" << av_get_pix_fmt_name(fmt) << ":" << sz
368 << "bytes for a buffer that needs" << needed;
369 return false;
370 }
371
372 if(av_image_fill_arrays(
373 frame->data, frame->linesize, p, fmt, frame->width, frame->height, align)
374 < 0)
375 {
376 qDebug() << "could not lay out video format" << av_get_pix_fmt_name(fmt);
377 return false;
378 }
379 return true;
380}
381
382[[nodiscard]]
383inline bool initFrameFromRawData(AVFrame* frame, uint8_t* p, std::size_t sz)
384{
385 return initFrameFromRawData(frame, p, sz, 1);
386}
387
388}
389#endif
Definition GStreamerCompatibility.hpp:27