14#include <Video/GStreamerCompatibility.hpp>
16#include <ossia/detail/parse_strict.hpp>
19#include <libavutil/pixfmt.h>
30namespace Gfx::GStreamer
39 AVPixelFormat pixfmt{AV_PIX_FMT_NONE};
42 std::string gst_format;
47 bool unsupported_format{};
51 bool unsupported_layout{};
52 std::function<void(
int,
int, AVPixelFormat)> on_format_change;
55inline constexpr auto appsink_name_rexp
56 = ctll::fixed_string{R
"(appsink\b[^!]*?\bname\s*=\s*([A-Za-z0-9_]+))"};
57inline constexpr auto elem_name_rexp
58 = ctll::fixed_string{R
"(\bname\s*=\s*([A-Za-z0-9_]+))"};
60inline std::vector<std::string> find_appsink_names(
const std::string& pipeline)
62 std::vector<std::string> names;
63 for(
auto m : ctre::search_all<appsink_name_rexp>(pipeline))
64 names.push_back(m.get<1>().to_string());
70inline std::vector<std::string> find_all_named_elements(
const std::string& pipeline)
72 std::vector<std::string> names;
73 for(
auto m : ctre::search_all<elem_name_rexp>(pipeline))
74 names.push_back(m.get<1>().to_string());
78inline constexpr auto channels_rexp
79 = ctll::fixed_string{R
"(channels=(?:\(int\))?\s*([0-9]+))"};
80inline constexpr auto rate_rexp
81 = ctll::fixed_string{R
"((?:^|[^A-Za-z0-9_\-])rate=(?:\(int\))?\s*([0-9]+))"};
82inline constexpr auto width_rexp
83 = ctll::fixed_string{R
"(width=(?:\(int\))?\s*([0-9]+))"};
84inline constexpr auto height_rexp
85 = ctll::fixed_string{R
"(height=(?:\(int\))?\s*([0-9]+))"};
86inline constexpr auto format_rexp
87 = ctll::fixed_string{R
"(format=(?:\(string\))?\s*([A-Za-z0-9]+))"};
89template <ctll::fixed_
string Rexp>
90inline int last_int_of(std::string_view str,
int fallback)
93 for(
auto m : ctre::search_all<Rexp>(str))
94 if(auto v = ossia::parse_strict<int>(m.template get<1>().to_view()))
102inline void classify_from_pipeline_string(
103 const std::string& pipeline,
const std::string& sink_name, AppsinkInfo& info)
105 std::size_t sink_pos = std::string::npos;
106 for(
auto m : ctre::search_all<appsink_name_rexp>(pipeline))
108 if(m.get<1>().to_view() == sink_name)
110 sink_pos = std::distance(pipeline.begin(), m.get<0>().begin());
114 const std::string_view before
115 = std::string_view{pipeline}.substr(0, sink_pos);
117 static constexpr std::string_view audio_tokens[]
118 = {
"audio/x-raw",
"audioconvert",
"audioresample",
"audiotestsrc"};
119 static constexpr std::string_view video_tokens[]
120 = {
"video/x-raw",
"videoconvert",
"videoscale",
"videotestsrc",
"videorate"};
122 std::size_t last_audio = std::string::npos, last_video = std::string::npos;
123 for(
auto tok : audio_tokens)
124 if(auto p = before.rfind(tok); p != std::string::npos)
125 last_audio = (last_audio == std::string::npos) ? p : std::max(last_audio, p);
126 for(
auto tok : video_tokens)
127 if(auto p = before.rfind(tok); p != std::string::npos)
128 last_video = (last_video == std::string::npos) ? p : std::max(last_video, p);
130 const bool is_audio = last_audio != std::string::npos
131 && (last_video == std::string::npos || last_audio > last_video);
134 info.is_video =
false;
135 info.channels = last_int_of<channels_rexp>(before, 2);
136 info.rate = last_int_of<rate_rexp>(before, 48000);
140 info.is_video =
true;
141 info.width = last_int_of<width_rexp>(before, 640);
142 info.height = last_int_of<height_rexp>(before, 480);
143 info.pixfmt = AV_PIX_FMT_RGBA;
145 for(
auto m : ctre::search_all<format_rexp>(before))
146 format = m.get<1>().to_string();
149 auto& map = ::Video::gstreamerToLibav();
150 if(
auto it = map.find(format); it != map.end())
152 info.pixfmt = it->second;
153 info.gst_format = format;
Definition GStreamerPipelineParse.hpp:34