2#include <Media/Libav.hpp>
4#include <ossia/detail/hash_map.hpp>
8#include <score_plugin_media_export.h>
18#include <libavformat/avformat.h>
19#include <libavutil/imgutils.h>
20#include <libavutil/pixdesc.h>
43inline std::optional<RawVideoCaps> parseRawVideoCaps(std::string_view caps)
45 auto trim = [](std::string_view v) {
46 while(!v.empty() && v.front() ==
' ')
48 while(!v.empty() && v.back() ==
' ')
52 auto value = [&](std::string_view v) {
54 if(!v.empty() && v.front() ==
'(')
55 if(
auto end = v.find(
')'); end != v.npos)
56 v.remove_prefix(end + 1);
59 auto to_int = [](std::string_view v) {
61 std::from_chars(v.data(), v.data() + v.size(), i);
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))
74 if(field !=
"video/x-raw")
78 const auto eq = field.find(
'=');
81 const auto key = trim(field.substr(0, eq));
82 const auto val = value(field.substr(eq + 1));
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")
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.;
97 if(res.format.empty() || res.width < 1 || res.height < 1 || res.rate <= 0.)
102inline const ossia::hash_map<std::string, AVPixelFormat>& gstreamerToLibav()
104 static const auto map = [] {
105 ossia::hash_map<std::string, AVPixelFormat> format_map;
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;
220 format_map[
"ARGB"] = AV_PIX_FMT_ARGB;
226 format_map[
"AYUV64"] = AV_PIX_FMT_AYUV64;
231 format_map[
"BGRA"] = AV_PIX_FMT_BGRA;
235 format_map[
"BGRx"] = AV_PIX_FMT_BGR0;
237 format_map[
"GBR"] = AV_PIX_FMT_GBRP;
238 format_map[
"GBRA"] = AV_PIX_FMT_GBRAP;
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;
262 format_map[
"NV12"] = AV_PIX_FMT_NV12;
268 format_map[
"NV16"] = AV_PIX_FMT_NV16;
270 format_map[
"NV21"] = AV_PIX_FMT_NV21;
271 format_map[
"NV24"] = AV_PIX_FMT_NV24;
273 format_map[
"P010_10BE"] = AV_PIX_FMT_P010BE;
274 format_map[
"P010_10LE"] = AV_PIX_FMT_P010LE;
277 format_map[
"P016_BE"] = AV_PIX_FMT_P016BE;
278 format_map[
"P016_LE"] = AV_PIX_FMT_P016LE;
280 format_map[
"RGB"] = AV_PIX_FMT_RGB24;
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;
290 format_map[
"RGBP"] = AV_PIX_FMT_GBRP;
291 format_map[
"RGBx"] = AV_PIX_FMT_RGB0;
294 format_map[
"UYVY"] = AV_PIX_FMT_UYVY422;
300 format_map[
"xBGR"] = AV_PIX_FMT_0BGR;
301 format_map[
"xRGB"] = AV_PIX_FMT_0RGB;
302 format_map[
"Y210"] = AV_PIX_FMT_Y210;
308#if defined(AV_PIX_FMT_XV30)
309 format_map[
"Y410"] = AV_PIX_FMT_XV30;
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;
323 format_map[
"YUY2"] = AV_PIX_FMT_YUYV422;
326 format_map[
"YVYU"] = AV_PIX_FMT_YVYU422;
340using PlaneOrder = std::array<int, 4>;
341inline constexpr PlaneOrder identityPlaneOrder{0, 1, 2, 3};
343inline PlaneOrder gstreamerPlaneOrder(std::string_view gstFormat)
noexcept
345 if(gstFormat ==
"RGBP")
347 return identityPlaneOrder;
360initFrameFromRawData(AVFrame* frame, uint8_t* p, std::size_t sz,
int align)
362 const auto fmt = (AVPixelFormat)frame->format;
364 = av_image_get_buffer_size(fmt, frame->width, frame->height, align);
365 if(needed < 0 || std::size_t(needed) > sz)
367 qDebug() <<
"unhandled video format" << av_get_pix_fmt_name(fmt) <<
":" << sz
368 <<
"bytes for a buffer that needs" << needed;
372 if(av_image_fill_arrays(
373 frame->data, frame->linesize, p, fmt, frame->width, frame->height, align)
376 qDebug() <<
"could not lay out video format" << av_get_pix_fmt_name(fmt);
383inline bool initFrameFromRawData(AVFrame* frame, uint8_t* p, std::size_t sz)
385 return initFrameFromRawData(frame, p, sz, 1);
Definition GStreamerCompatibility.hpp:27