2#include <QJsonDocument>
14static bool vectorContains(
const std::vector<std::string> &v,
const std::string & s){
15 for(
unsigned i = 0; i < v.size(); i++){
23#define X(type, str) case type: return str;
34#define X(type, str) if(sv == str) return type; else
36 return SETTING_TYPE_UNKNOWN;
44 constexpr std::string_view module_cap_prefix =
"[cap][";
46 line.remove_prefix(module_cap_prefix.size());
50 auto module_type =
tokenize(line,
']');
53 if(!module_type.empty() && !module_name.empty())
59 constexpr std::string_view devStr =
"[capability][device]";
60 constexpr std::string_view codecStr =
"[capability][video_compress]";
61 constexpr std::string_view endMarkerStr =
"[capability][end]";
64 line.remove_prefix(devStr.size());
67 line.remove_prefix(codecStr.size());
76 std::string_view verStr =
"[capability][start] version ";
79 line.remove_prefix(verStr.size());
82 const int expectedVersion = 4;
83 if(ver != expectedVersion){
85 QString
msg =
"Capabilities start marker with expected version not found"
88 msg +=
" Version found: " + QString::number(ver);
90 msgBox.setIcon(QMessageBox::Critical);
122 return a.priority < b.priority;
137 if(obj.contains(
key) && obj[
key].isString()){
138 result = obj[
key].toString().toStdString();
143 std::vector<CapabOpt> opts;
145 if(obj.contains(
"options") && obj[
"options"].isArray()){
146 for(
const QJsonValue &
val : obj[
"options"].toArray()){
147 QJsonObject optJson =
val.toObject();
155 if(optJson.contains(
"is_boolean") && optJson[
"is_boolean"].isString()){
156 capabOpt.
booleanOpt = optJson[
"is_boolean"].toString() ==
"t";
159 opts.emplace_back(std::move(capabOpt));
167 QJsonDocument
doc = QJsonDocument::fromJson(QByteArray::fromRawData(line.data(), line.size()));
172 QJsonObject obj =
doc.object();
178 if(obj.contains(
"codecs") && obj[
"codecs"].isArray()){
179 for(
const QJsonValue &
val : obj[
"codecs"].toArray()){
180 QJsonObject codecJson =
val.toObject();
185 if(codecJson.contains(
"priority") && codecJson[
"priority"].isDouble()){
189 if(codecJson.contains(
"encoders") && codecJson[
"encoders"].isArray()){
190 for(
const QJsonValue &
val : codecJson[
"encoders"].toArray()){
191 QJsonObject encoderJson =
val.toObject();
213 static std::map<std::string, SettingType> settingTypeMap = {
214 {
"video_cap", VIDEO_SRC},
215 {
"video_disp", VIDEO_DISPLAY},
216 {
"audio_play", AUDIO_PLAYBACK},
217 {
"audio_cap", AUDIO_SRC},
220 QJsonDocument
doc = QJsonDocument::fromJson(QByteArray::fromRawData(line.data(), line.size()));
225 QJsonObject obj =
doc.object();
230 if(obj.contains(
"extra") && obj[
"extra"].isObject()){
231 const auto& extraObj = obj[
"extra"].toObject();
232 for(
auto it = extraObj.constBegin(); it != extraObj.constEnd(); it++){
233 if(it.value().isString()){
234 dev.
extra[it.key().toStdString()] = it.value().toString().toStdString();
239 if(obj.contains(
"modes") && obj[
"modes"].isArray()){
240 for(
const QJsonValue &
val : obj[
"modes"].toArray()){
242 QJsonObject modeJson =
val.toObject();
248 if(modeJson.contains(
"opts") && modeJson[
"opts"].isObject()){
249 QJsonObject modeOpts = modeJson[
"opts"].toObject();
250 for(
const QString &
key : modeOpts.keys()){
251 if(modeOpts[
key].isString()){
253 modeOpts[
key].toString().toStdString()});
265 if(obj.contains(
"purpose") && obj[
"purpose"].isString()){
266 settingType = settingTypeMap[obj[
"purpose"].toString().toStdString()];
269 devices[settingType].push_back(std::move(dev));
static bool vectorContains(const std::vector< std::string > &v, const std::string &s)
const char * settingTypeToStr(SettingType type)
SettingType strToSettingType(std::string_view sv)
static void maybeWriteString(const QJsonObject &obj, const char *key, std::string &result)
std::vector< CapabOpt > parseCapabOpts(const QJsonObject &obj)
#define SETTING_TYPE_LIST
SettingType strToSettingType(std::string_view sv)
void parseStateVersion(std::string_view line)
void queryLine(std::string_view line)
void queryVideoCompress(std::string_view line)
std::vector< CompressModule > videoCompressModules
bool isAvailable(const std::string &name, SettingType type) const
std::vector< Codec > videoCompressCodecs
std::vector< std::string > available[SETTING_TYPE_COUNT]
const std::vector< Device > & getDevices(SettingType type) const
std::vector< Device > devices[SETTING_TYPE_COUNT]
const std::vector< std::string > & getAvailableSettings(SettingType type) const
void(AvailableSettings::* parseFunc)(std::string_view str)
void queryDevice(std::string_view line)
void queryProcessLine(std::string_view line)
std::string_view tokenize(std::string_view &str, char delim, char quot)
Tokenizer for string_view.
std::string_view sv_trim_whitespace(std::string_view sv)
bool parse_num(std::string_view sv, T &res, int base=10)
bool sv_is_prefix(std::string_view haystack, std::string_view needle)
std::vector< CapabOpt > opts
std::map< std::string, std::string > extra
std::vector< CapabOpt > opts
std::vector< DeviceMode > modes
std::vector< encoder > encoders