#include "parameter-wrappers.hpp" #include #include namespace advss { bool PatternMatchParameters::Save(obs_data_t *obj) const { auto data = obs_data_create(); obs_data_set_bool(data, "useForChangedCheck", useForChangedCheck); threshold.Save(data, "threshold"); obs_data_set_bool(data, "useAlphaAsMask", useAlphaAsMask); obs_data_set_int(data, "matchMode", matchMode); obs_data_set_int(data, "version", 1); obs_data_set_obj(obj, "patternMatchData", data); obs_data_release(data); return true; } bool PatternMatchParameters::Load(obs_data_t *obj) { // TODO: Remove this fallback in a future version if (!obs_data_has_user_value(obj, "patternMatchData")) { useForChangedCheck = obs_data_get_bool(obj, "usePatternForChangedCheck"); threshold = obs_data_get_double(obj, "threshold"); useAlphaAsMask = obs_data_get_bool(obj, "useAlphaAsMask"); return true; } auto data = obs_data_get_obj(obj, "patternMatchData"); useForChangedCheck = obs_data_get_bool(data, "useForChangedCheck"); threshold.Load(data, "threshold"); // TODO: Remove this fallback in a future version if (!obs_data_has_user_value(data, "version")) { threshold = obs_data_get_double(data, "threshold"); } useAlphaAsMask = obs_data_get_bool(data, "useAlphaAsMask"); // TODO: Remove this fallback in a future version if (!obs_data_has_user_value(data, "matchMode")) { matchMode = cv::TM_CCORR_NORMED; } else { matchMode = static_cast( obs_data_get_int(data, "matchMode")); } obs_data_release(data); return true; } bool ObjDetectParameters::Save(obs_data_t *obj) const { auto data = obs_data_create(); obs_data_set_string(data, "modelPath", modelPath.c_str()); scaleFactor.Save(data, "scaleFactor"); obs_data_set_int(data, "minNeighbors", minNeighbors); minSize.Save(data, "minSize"); maxSize.Save(data, "maxSize"); obs_data_set_obj(obj, "objectMatchData", data); obs_data_set_int(data, "version", 1); obs_data_release(data); return true; } static bool isScaleFactorValid(double scaleFactor) { return scaleFactor > 1.; } static bool isMinNeighborsValid(int minNeighbors) { return minNeighbors >= minMinNeighbors && minNeighbors <= maxMinNeighbors; } bool ObjDetectParameters::Load(obs_data_t *obj) { // TODO: Remove this fallback in a future version if (!obs_data_has_user_value(obj, "patternMatchData")) { modelPath = obs_data_get_string(obj, "modelDataPath"); scaleFactor = obs_data_get_double(obj, "scaleFactor"); if (!isScaleFactorValid(scaleFactor)) { scaleFactor = 1.1; } minNeighbors = obs_data_get_int(obj, "minNeighbors"); if (!isMinNeighborsValid(minNeighbors)) { minNeighbors = minMinNeighbors; } minSize.Load(obj, "minSize"); maxSize.Load(obj, "maxSize"); return true; } auto data = obs_data_get_obj(obj, "objectMatchData"); modelPath = obs_data_get_string(data, "modelPath"); scaleFactor.Load(data, "scaleFactor"); // TODO: Remove this fallback in a future version if (!obs_data_has_user_value(data, "version")) { scaleFactor = obs_data_get_double(data, "scaleFactor"); } if (scaleFactor.IsFixedType() && !isScaleFactorValid(scaleFactor)) { scaleFactor = 1.1; } minNeighbors = obs_data_get_int(data, "minNeighbors"); if (!isMinNeighborsValid(minNeighbors)) { minNeighbors = minMinNeighbors; } minSize.Load(data, "minSize"); maxSize.Load(data, "maxSize"); obs_data_release(data); return true; } bool AreaParameters::Save(obs_data_t *obj) const { auto data = obs_data_create(); obs_data_set_bool(data, "enabled", enable); area.Save(data, "area"); obs_data_set_obj(obj, "areaData", data); obs_data_release(data); return true; } bool AreaParameters::Load(obs_data_t *obj) { // TODO: Remove this fallback in a future version if (!obs_data_has_user_value(obj, "areaData")) { enable = obs_data_get_bool(obj, "checkAreaEnabled"); area.Load(obj, "checkArea"); return true; } auto data = obs_data_get_obj(obj, "areaData"); enable = obs_data_get_bool(data, "enabled"); area.Load(data, "area"); obs_data_release(data); return true; } bool VideoInput::Save(obs_data_t *obj) const { auto data = obs_data_create(); obs_data_set_int(data, "type", static_cast(type)); source.Save(data); scene.Save(data); obs_data_set_obj(obj, "videoInputData", data); obs_data_release(data); return true; } bool VideoInput::Load(obs_data_t *obj) { // TODO: Remove this fallback in a future version if (obs_data_has_user_value(obj, "videoType")) { enum class VideoSelectionType { SOURCE, OBS_MAIN, }; auto oldType = static_cast( obs_data_get_int(obj, "videoType")); if (oldType == VideoSelectionType::SOURCE) { type = Type::SOURCE; auto name = obs_data_get_string(obj, "video"); source.SetSource(GetWeakSourceByName(name)); } else { type = Type::OBS_MAIN_OUTPUT; } return true; } auto data = obs_data_get_obj(obj, "videoInputData"); type = static_cast(obs_data_get_int(data, "type")); source.Load(data); scene.Load(data); obs_data_release(data); return true; } std::string VideoInput::ToString(bool resolve) const { switch (type) { case VideoInput::Type::OBS_MAIN_OUTPUT: return obs_module_text("AdvSceneSwitcher.OBSVideoOutput"); case VideoInput::Type::SOURCE: return source.ToString(resolve); case VideoInput::Type::SCENE: return scene.ToString(resolve); } return ""; } bool VideoInput::ValidSelection() const { switch (type) { case VideoInput::Type::OBS_MAIN_OUTPUT: return true; case VideoInput::Type::SOURCE: return !!source.GetSource(); case VideoInput::Type::SCENE: return !!scene.GetScene(); } return false; } OBSWeakSource VideoInput::GetVideo() const { switch (type) { case VideoInput::Type::OBS_MAIN_OUTPUT: return nullptr; case VideoInput::Type::SOURCE: return source.GetSource(); case VideoInput::Type::SCENE: return scene.GetScene(); } return nullptr; } static void SaveColor(obs_data_t *obj, const char *name, const QColor &color) { auto data = obs_data_create(); obs_data_set_int(data, "red", color.red()); obs_data_set_int(data, "green", color.green()); obs_data_set_int(data, "blue", color.blue()); obs_data_set_obj(obj, name, data); obs_data_release(data); } static QColor LoadColor(obs_data_t *obj, const char *name) { QColor color = Qt::black; auto data = obs_data_get_obj(obj, name); color.setRed(obs_data_get_int(data, "red")); color.setGreen(obs_data_get_int(data, "green")); color.setBlue(obs_data_get_int(data, "blue")); obs_data_release(data); return color; } OCRParameters::OCRParameters() { Setup(); } OCRParameters::~OCRParameters() { if (!initDone) { return; } ocr->End(); } OCRParameters::OCRParameters(const OCRParameters &other) : text(other.text), regex(other.regex), color(other.color), colorThreshold(other.colorThreshold), pageSegMode(other.pageSegMode), languageCode(other.languageCode) { if (!initDone) { Setup(); } if (initDone) { ocr->SetPageSegMode(pageSegMode); } } OCRParameters &OCRParameters::operator=(const OCRParameters &other) { text = other.text; regex = other.regex; color = other.color; colorThreshold = other.colorThreshold; pageSegMode = other.pageSegMode; languageCode = other.languageCode; if (!initDone) { Setup(); } if (initDone) { ocr->SetPageSegMode(pageSegMode); } return *this; } bool OCRParameters::Save(obs_data_t *obj) const { auto data = obs_data_create(); text.Save(data, "pattern"); regex.Save(data); languageCode.Save(data, "language"); SaveColor(data, "textColor", color); colorThreshold.Save(data, "colorThreshold"); obs_data_set_int(data, "pageSegMode", static_cast(pageSegMode)); obs_data_set_int(data, "version", 1); obs_data_set_obj(obj, "ocrData", data); obs_data_release(data); return true; } bool OCRParameters::Load(obs_data_t *obj) { auto data = obs_data_get_obj(obj, "ocrData"); text.Load(data, "pattern"); regex.Load(data); obs_data_set_default_string(data, "language", "eng"); languageCode.Load(data, "language"); color = LoadColor(data, "textColor"); if (obs_data_has_user_value(data, "version")) { colorThreshold.Load(data, "colorThreshold"); } pageSegMode = static_cast( obs_data_get_int(data, "pageSegMode")); obs_data_release(data); if (initDone) { ocr->SetPageSegMode(pageSegMode); } Setup(); return true; } void OCRParameters::SetPageMode(tesseract::PageSegMode mode) { pageSegMode = mode; ocr->SetPageSegMode(mode); } bool OCRParameters::SetLanguageCode(const std::string &value) { const auto dataPath = QString(obs_get_module_data_path(obs_current_module())) + QString("/res/ocr") + "/" + QString::fromStdString(value) + ".traineddata"; QFileInfo fileInfo(dataPath); if (!fileInfo.exists(dataPath)) { return false; } languageCode = value; Setup(); ocr->SetPageSegMode(pageSegMode); return true; } std::string OCRParameters::GetLanguageCode() const { return languageCode; } void OCRParameters::Setup() { ocr = std::make_unique(); if (!ocr) { initDone = false; return; } std::string dataPath = obs_get_module_data_path(obs_current_module()) + std::string("/res/ocr"); if (ocr->Init(dataPath.c_str(), languageCode.c_str()) != 0) { initDone = false; return; } initDone = true; } bool ColorParameters::Save(obs_data_t *obj) const { auto data = obs_data_create(); SaveColor(data, "color", color); colorThreshold.Save(data, "colorThreshold"); matchThreshold.Save(data, "matchThreshold"); obs_data_set_obj(obj, "colorData", data); obs_data_release(data); return true; } bool ColorParameters::Load(obs_data_t *obj) { auto data = obs_data_get_obj(obj, "colorData"); color = LoadColor(data, "color"); colorThreshold.Load(data, "colorThreshold"); matchThreshold.Load(data, "matchThreshold"); obs_data_release(data); return true; } } // namespace advss