Add variable support to video condition

This commit is contained in:
WarmUpTill 2022-12-28 16:01:56 +01:00 committed by WarmUpTill
parent 8a2ccef8ec
commit 1fd6f75ee1
13 changed files with 203 additions and 204 deletions

View File

@ -199,7 +199,10 @@ AdvSceneSwitcher.condition.video.patternMatchSuccess="Pattern is highlighted in
AdvSceneSwitcher.condition.video.objectMatchFail="Object was not found!" AdvSceneSwitcher.condition.video.objectMatchFail="Object was not found!"
AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red" AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red"
AdvSceneSwitcher.condition.video.modelLoadFail="Model data could not be loaded!" AdvSceneSwitcher.condition.video.modelLoadFail="Model data could not be loaded!"
AdvSceneSwitcher.condition.video.entry="{{videoSources}} {{condition}} {{imagePath}}" AdvSceneSwitcher.condition.video.type.main="OBS's main output"
AdvSceneSwitcher.condition.video.type.source="Source"
AdvSceneSwitcher.condition.video.type.scene="Scene"
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
AdvSceneSwitcher.condition.video.entry.modelPath="Model data (haar cascade classifier): {{modelDataPath}}" AdvSceneSwitcher.condition.video.entry.modelPath="Model data (haar cascade classifier): {{modelDataPath}}"
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum neighbors: {{minNeighbors}}" AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum neighbors: {{minNeighbors}}"
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduce CPU load by performing check only every {{throttleCount}} milliseconds" AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduce CPU load by performing check only every {{throttleCount}} milliseconds"

View File

@ -162,7 +162,7 @@ AdvSceneSwitcher.condition.video.patternMatchSuccess="El patrón está resaltado
AdvSceneSwitcher.condition.video.objectMatchFail="¡No se encontró el objeto!" AdvSceneSwitcher.condition.video.objectMatchFail="¡No se encontró el objeto!"
AdvSceneSwitcher.condition.video.objectMatchSuccess="El objeto está resaltado en rojo" AdvSceneSwitcher.condition.video.objectMatchSuccess="El objeto está resaltado en rojo"
AdvSceneSwitcher.condition.video.modelLoadFail="¡No se pudieron cargar los datos del modelo!" AdvSceneSwitcher.condition.video.modelLoadFail="¡No se pudieron cargar los datos del modelo!"
AdvSceneSwitcher.condition.video.entry="{{videoSources}} {{condition}} {{imagePath}}" AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
AdvSceneSwitcher.condition.video.entry.modelPath="Datos del modelo (haar cascade classifier): {{modelDataPath}}" AdvSceneSwitcher.condition.video.entry.modelPath="Datos del modelo (haar cascade classifier): {{modelDataPath}}"
AdvSceneSwitcher.condition.video.entry.minNeighbor="Mínimo de vecinos: {{minNeighbors}}" AdvSceneSwitcher.condition.video.entry.minNeighbor="Mínimo de vecinos: {{minNeighbors}}"
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduzca la carga de la CPU realizando una comprobación solo cada {{throttleCount}} milisegundos" AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduzca la carga de la CPU realizando una comprobación solo cada {{throttleCount}} milisegundos"

View File

@ -147,7 +147,7 @@ AdvSceneSwitcher.condition.video.screenshotFail="Kaynağın ekran görüntüsü
AdvSceneSwitcher.condition.video.patternMatchFail="Desen bulunamadı!" AdvSceneSwitcher.condition.video.patternMatchFail="Desen bulunamadı!"
AdvSceneSwitcher.condition.video.objectMatchFail="Nesne bulunamadı!" AdvSceneSwitcher.condition.video.objectMatchFail="Nesne bulunamadı!"
AdvSceneSwitcher.condition.video.modelLoadFail="Model verileri yüklenemedi!" AdvSceneSwitcher.condition.video.modelLoadFail="Model verileri yüklenemedi!"
AdvSceneSwitcher.condition.video.entry="{{videoSources}} {{condition}} {{imagePath}}" AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
AdvSceneSwitcher.condition.video.entry.modelPath="Model verileri (haar kademeli sınıflandırıcı):{{modelDataPath}}" AdvSceneSwitcher.condition.video.entry.modelPath="Model verileri (haar kademeli sınıflandırıcı):{{modelDataPath}}"
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum komşular: {{minNeighbors}}" AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum komşular: {{minNeighbors}}"
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}} Yalnızca her seferinde kontrol gerçekleştirerek CPU yükünü azaltın {{throttleCount}} millisaniyeler" AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}} Yalnızca her seferinde kontrol gerçekleştirerek CPU yükünü azaltın {{throttleCount}} millisaniyeler"

View File

@ -180,7 +180,7 @@ AdvSceneSwitcher.condition.video.patternMatchSuccess="Pattern is highlighted in
AdvSceneSwitcher.condition.video.objectMatchFail="找不到对象!" AdvSceneSwitcher.condition.video.objectMatchFail="找不到对象!"
AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red" AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red"
AdvSceneSwitcher.condition.video.modelLoadFail="无法加载模型数据!" AdvSceneSwitcher.condition.video.modelLoadFail="无法加载模型数据!"
AdvSceneSwitcher.condition.video.entry="{{videoSources}} {{condition}} {{imagePath}}" AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
AdvSceneSwitcher.condition.video.entry.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}" AdvSceneSwitcher.condition.video.entry.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}"
AdvSceneSwitcher.condition.video.entry.minNeighbor="最小区域: {{minNeighbors}}" AdvSceneSwitcher.condition.video.entry.minNeighbor="最小区域: {{minNeighbors}}"
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}通过只执行每一次检查来减少CPU负载 {{throttleCount}} 毫秒" AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}通过只执行每一次检查来减少CPU负载 {{throttleCount}} 毫秒"

View File

@ -26,9 +26,7 @@ target_sources(
paramerter-wrappers.cpp paramerter-wrappers.cpp
paramerter-wrappers.hpp paramerter-wrappers.hpp
preview-dialog.cpp preview-dialog.cpp
preview-dialog.hpp preview-dialog.hpp)
video-selection.cpp
video-selection.hpp)
setup_advss_plugin(${PROJECT_NAME}) setup_advss_plugin(${PROJECT_NAME})
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")

View File

@ -18,7 +18,7 @@ bool MacroConditionVideo::_registered = MacroConditionFactory::Register(
{MacroConditionVideo::Create, MacroConditionVideoEdit::Create, {MacroConditionVideo::Create, MacroConditionVideoEdit::Create,
"AdvSceneSwitcher.condition.video"}); "AdvSceneSwitcher.condition.video"});
static std::map<VideoCondition, std::string> conditionTypes = { const static std::map<VideoCondition, std::string> conditionTypes = {
{VideoCondition::MATCH, {VideoCondition::MATCH,
"AdvSceneSwitcher.condition.video.condition.match"}, "AdvSceneSwitcher.condition.video.condition.match"},
{VideoCondition::DIFFER, {VideoCondition::DIFFER,
@ -37,6 +37,15 @@ static std::map<VideoCondition, std::string> conditionTypes = {
"AdvSceneSwitcher.condition.video.condition.brightness"}, "AdvSceneSwitcher.condition.video.condition.brightness"},
}; };
const static std::map<VideoInput::Type, std::string> videoInputTypes = {
{VideoInput::Type::OBS_MAIN_OUTPUT,
"AdvSceneSwitcher.condition.video.type.main"},
{VideoInput::Type::SOURCE,
"AdvSceneSwitcher.condition.video.type.source"},
{VideoInput::Type::SCENE,
"AdvSceneSwitcher.condition.video.type.scene"},
};
cv::CascadeClassifier initObjectCascade(std::string &path) cv::CascadeClassifier initObjectCascade(std::string &path)
{ {
cv::CascadeClassifier cascade; cv::CascadeClassifier cascade;
@ -127,9 +136,6 @@ bool MacroConditionVideo::Load(obs_data_t *obj)
{ {
MacroCondition::Load(obj); MacroCondition::Load(obj);
_video.Load(obj); _video.Load(obj);
if (obs_data_has_user_value(obj, "videoSource")) {
_video.Load(obj, "videoSource");
}
_condition = _condition =
static_cast<VideoCondition>(obs_data_get_int(obj, "condition")); static_cast<VideoCondition>(obs_data_get_int(obj, "condition"));
_file = obs_data_get_string(obj, "filePath"); _file = obs_data_get_string(obj, "filePath");
@ -268,6 +274,13 @@ bool MacroConditionVideo::Compare()
return false; return false;
} }
static inline void populateVideoInputSelection(QComboBox *list)
{
for (const auto &[_, name] : videoInputTypes) {
list->addItem(obs_module_text(name.c_str()));
}
}
static inline void populateConditionSelection(QComboBox *list) static inline void populateConditionSelection(QComboBox *list)
{ {
for (auto entry : conditionTypes) { for (auto entry : conditionTypes) {
@ -278,7 +291,10 @@ static inline void populateConditionSelection(QComboBox *list)
MacroConditionVideoEdit::MacroConditionVideoEdit( MacroConditionVideoEdit::MacroConditionVideoEdit(
QWidget *parent, std::shared_ptr<MacroConditionVideo> entryData) QWidget *parent, std::shared_ptr<MacroConditionVideo> entryData)
: QWidget(parent), : QWidget(parent),
_videoSelection(new VideoSelectionWidget(this)), _videoInputTypes(new QComboBox()),
_scenes(new SceneSelectionWidget(this, true, false, true, true,
true)),
_sources(new SourceSelectionWidget(this, QStringList(), true)),
_condition(new QComboBox()), _condition(new QComboBox()),
_reduceLatency(new QCheckBox(obs_module_text( _reduceLatency(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.condition.video.reduceLatency"))), "AdvSceneSwitcher.condition.video.reduceLatency"))),
@ -339,10 +355,17 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
_throttleCount->setMaximum(10 * GetSwitcher()->interval); _throttleCount->setMaximum(10 * GetSwitcher()->interval);
_throttleCount->setSingleStep(GetSwitcher()->interval); _throttleCount->setSingleStep(GetSwitcher()->interval);
QWidget::connect(_videoSelection, auto sources = GetVideoSourceNames();
SIGNAL(VideoSelectionChange(const VideoSelection &)), sources.sort();
this, _sources->SetSourceNameList(sources);
SLOT(VideoSelectionChanged(const VideoSelection &)));
QWidget::connect(_videoInputTypes, SIGNAL(currentIndexChanged(int)),
this, SLOT(VideoInputTypeChanged(int)));
QWidget::connect(_sources,
SIGNAL(SourceChanged(const SourceSelection &)), this,
SLOT(SourceChanged(const SourceSelection &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int))); SLOT(ConditionChanged(int)));
QWidget::connect(_reduceLatency, SIGNAL(stateChanged(int)), this, QWidget::connect(_reduceLatency, SIGNAL(stateChanged(int)), this,
@ -383,20 +406,23 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
SLOT(ShowMatchClicked())); SLOT(ShowMatchClicked()));
QWidget::connect(&_previewDialog, SIGNAL(SelectionAreaChanged(QRect)), QWidget::connect(&_previewDialog, SIGNAL(SelectionAreaChanged(QRect)),
this, SLOT(CheckAreaChanged(QRect))); this, SLOT(CheckAreaChanged(QRect)));
QWidget::connect(_videoSelection, QWidget::connect(this,
SIGNAL(VideoSelectionChange(const VideoSelection &)), SIGNAL(VideoSelectionChanged(const VideoInput &)),
&_previewDialog, &_previewDialog,
SLOT(VideoSelectionChanged(const VideoSelection &))); SLOT(VideoSelectionChanged(const VideoInput &)));
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)),
&_previewDialog, SLOT(ConditionChanged(int))); &_previewDialog, SLOT(ConditionChanged(int)));
QWidget::connect(_selectArea, SIGNAL(clicked()), this, QWidget::connect(_selectArea, SIGNAL(clicked()), this,
SLOT(SelectAreaClicked())); SLOT(SelectAreaClicked()));
populateVideoInputSelection(_videoInputTypes);
populateConditionSelection(_condition); populateConditionSelection(_condition);
QHBoxLayout *entryLine1Layout = new QHBoxLayout; QHBoxLayout *entryLine1Layout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{videoSources}}", _videoSelection}, {"{{videoInputTypes}}", _videoInputTypes},
{"{{sources}}", _sources},
{"{{scenes}}", _scenes},
{"{{condition}}", _condition}, {"{{condition}}", _condition},
{"{{reduceLatency}}", _reduceLatency}, {"{{reduceLatency}}", _reduceLatency},
{"{{imagePath}}", _imagePath}, {"{{imagePath}}", _imagePath},
@ -499,17 +525,38 @@ void MacroConditionVideoEdit::UpdatePreviewTooltip()
this->setToolTip(html); this->setToolTip(html);
} }
void MacroConditionVideoEdit::VideoSelectionChanged(const VideoSelection &v) void MacroConditionVideoEdit::SourceChanged(const SourceSelection &source)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(GetSwitcher()->m); std::lock_guard<std::mutex> lock(GetSwitcher()->m);
_entryData->_video = v; _entryData->_video.source = source;
_entryData->ResetLastMatch(); HandleVideoInputUpdate();
emit HeaderInfoChanged( }
QString::fromStdString(_entryData->GetShortDesc()));
void MacroConditionVideoEdit::SceneChanged(const SceneSelection &scene)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(GetSwitcher()->m);
_entryData->_video.scene = scene;
HandleVideoInputUpdate();
}
void MacroConditionVideoEdit::VideoInputTypeChanged(int type)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(GetSwitcher()->m);
_entryData->_video.type = static_cast<VideoInput::Type>(type);
HandleVideoInputUpdate();
SetWidgetVisibility();
} }
void MacroConditionVideoEdit::ConditionChanged(int cond) void MacroConditionVideoEdit::ConditionChanged(int cond)
@ -741,6 +788,14 @@ void MacroConditionVideoEdit::MinSizeChanged(advss::Size value)
_entryData->_objMatchParameters); _entryData->_objMatchParameters);
} }
void MacroConditionVideoEdit::HandleVideoInputUpdate()
{
_entryData->ResetLastMatch();
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
emit VideoSelectionChanged(_entryData->_video);
}
void MacroConditionVideoEdit::MaxSizeChanged(advss::Size value) void MacroConditionVideoEdit::MaxSizeChanged(advss::Size value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
@ -887,6 +942,9 @@ bool needsAreaControls(VideoCondition cond)
void MacroConditionVideoEdit::SetWidgetVisibility() void MacroConditionVideoEdit::SetWidgetVisibility()
{ {
_sources->setVisible(_entryData->_video.type ==
VideoInput::Type::SOURCE);
_scenes->setVisible(_entryData->_video.type == VideoInput::Type::SCENE);
_imagePath->setVisible(requiresFileInput(_entryData->_condition)); _imagePath->setVisible(requiresFileInput(_entryData->_condition));
_usePatternForChangedCheck->setVisible( _usePatternForChangedCheck->setVisible(
patternControlIsOptional(_entryData->_condition)); patternControlIsOptional(_entryData->_condition));
@ -930,7 +988,10 @@ void MacroConditionVideoEdit::UpdateEntryData()
return; return;
} }
_videoSelection->SetVideoSelection(_entryData->_video); _videoInputTypes->setCurrentIndex(
static_cast<int>(_entryData->_video.type));
_scenes->SetScene(_entryData->_video.scene);
_sources->SetSource(_entryData->_video.source);
_condition->setCurrentIndex(static_cast<int>(_entryData->_condition)); _condition->setCurrentIndex(static_cast<int>(_entryData->_condition));
_reduceLatency->setChecked(_entryData->_blockUntilScreenshotDone); _reduceLatency->setChecked(_entryData->_blockUntilScreenshotDone);
_imagePath->SetPath(QString::fromStdString(_entryData->_file)); _imagePath->SetPath(QString::fromStdString(_entryData->_file));

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "opencv-helpers.hpp" #include "opencv-helpers.hpp"
#include "area-selection.hpp" #include "area-selection.hpp"
#include "video-selection.hpp"
#include "preview-dialog.hpp" #include "preview-dialog.hpp"
#include "paramerter-wrappers.hpp" #include "paramerter-wrappers.hpp"
@ -40,7 +39,7 @@ public:
void ResetLastMatch() { _lastMatchResult = false; } void ResetLastMatch() { _lastMatchResult = false; }
double GetCurrentBrightness() const { return _currentBrigthness; } double GetCurrentBrightness() const { return _currentBrigthness; }
VideoSelection _video; VideoInput _video;
VideoCondition _condition = VideoCondition::MATCH; VideoCondition _condition = VideoCondition::MATCH;
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath"); std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
// Enabling this will reduce matching latency, but slow down the // Enabling this will reduce matching latency, but slow down the
@ -97,7 +96,9 @@ public:
void UpdatePreviewTooltip(); void UpdatePreviewTooltip();
private slots: private slots:
void VideoSelectionChanged(const VideoSelection &); void VideoInputTypeChanged(int);
void SourceChanged(const SourceSelection &);
void SceneChanged(const SceneSelection &);
void ConditionChanged(int cond); void ConditionChanged(int cond);
void ReduceLatencyChanged(int value); void ReduceLatencyChanged(int value);
@ -127,10 +128,16 @@ private slots:
void UpdateCurrentBrightness(); void UpdateCurrentBrightness();
signals: signals:
void VideoSelectionChanged(const VideoInput &);
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);
protected: private:
VideoSelectionWidget *_videoSelection; void SetWidgetVisibility();
void HandleVideoInputUpdate();
QComboBox *_videoInputTypes;
SceneSelectionWidget *_scenes;
SourceSelectionWidget *_sources;
QComboBox *_condition; QComboBox *_condition;
QCheckBox *_reduceLatency; QCheckBox *_reduceLatency;
@ -166,11 +173,8 @@ protected:
QPushButton *_showMatch; QPushButton *_showMatch;
PreviewDialog _previewDialog; PreviewDialog _previewDialog;
std::shared_ptr<MacroConditionVideo> _entryData;
private:
QTimer _updateBrightnessTimer; QTimer _updateBrightnessTimer;
void SetWidgetVisibility(); std::shared_ptr<MacroConditionVideo> _entryData;
bool _loading = true; bool _loading = true;
}; };

View File

@ -110,3 +110,81 @@ bool AreaParamters::Load(obs_data_t *obj)
obs_data_release(data); obs_data_release(data);
return true; return true;
} }
bool VideoInput::Save(obs_data_t *obj) const
{
auto data = obs_data_create();
obs_data_set_int(data, "type", static_cast<int>(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<VideoSelectionType>(
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<Type>(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;
}

View File

@ -2,6 +2,8 @@
#include "opencv-helpers.hpp" #include "opencv-helpers.hpp"
#include "area-selection.hpp" #include "area-selection.hpp"
#include <source-selection.hpp>
#include <scene-selection.hpp>
#include <obs.hpp> #include <obs.hpp>
#include <obs-module.h> #include <obs-module.h>
@ -16,6 +18,25 @@ enum class VideoCondition {
BRIGHTNESS, BRIGHTNESS,
}; };
class VideoInput {
public:
bool Save(obs_data_t *obj) const;
bool Load(obs_data_t *obj);
std::string ToString(bool resolve = false) const;
bool ValidSelection() const;
OBSWeakSource GetVideo() const;
enum class Type {
OBS_MAIN_OUTPUT,
SOURCE,
SCENE,
};
Type type = Type::OBS_MAIN_OUTPUT;
SourceSelection source;
SceneSelection scene;
};
class PatternMatchParameters { class PatternMatchParameters {
public: public:
bool Save(obs_data_t *obj) const; bool Save(obs_data_t *obj) const;

View File

@ -143,7 +143,7 @@ void PreviewDialog::ObjDetectParamtersChanged(const ObjDetectParamerts &params)
_objDetectParams = params; _objDetectParams = params;
} }
void PreviewDialog::VideoSelectionChanged(const VideoSelection &video) void PreviewDialog::VideoSelectionChanged(const VideoInput &video)
{ {
std::unique_lock<std::mutex> lock(_mtx); std::unique_lock<std::mutex> lock(_mtx);
_video = video; _video = video;

View File

@ -1,5 +1,4 @@
#pragma once #pragma once
#include "video-selection.hpp"
#include "paramerter-wrappers.hpp" #include "paramerter-wrappers.hpp"
#include <QDialog> #include <QDialog>
@ -28,7 +27,7 @@ public:
public slots: public slots:
void PatternMatchParamtersChanged(const PatternMatchParameters &); void PatternMatchParamtersChanged(const PatternMatchParameters &);
void ObjDetectParamtersChanged(const ObjDetectParamerts &); void ObjDetectParamtersChanged(const ObjDetectParamerts &);
void VideoSelectionChanged(const VideoSelection &); void VideoSelectionChanged(const VideoInput &);
void AreaParamtersChanged(const AreaParamters &); void AreaParamtersChanged(const AreaParamters &);
void ConditionChanged(int cond); void ConditionChanged(int cond);
private slots: private slots:
@ -46,7 +45,7 @@ private:
void mouseMoveEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event);
VideoSelection _video; VideoInput _video;
PatternMatchParameters _patternMatchParams; PatternMatchParameters _patternMatchParams;
PatternImageData _patternImageData; PatternImageData _patternImageData;
ObjDetectParamerts _objDetectParams; ObjDetectParamerts _objDetectParams;

View File

@ -1,122 +0,0 @@
#include "video-selection.hpp"
#include "utility.hpp"
void VideoSelection::Save(obs_data_t *obj, const char *name,
const char *typeName) const
{
obs_data_set_int(obj, typeName, static_cast<int>(_type));
switch (_type) {
case VideoSelectionType::SOURCE:
obs_data_set_string(obj, name,
GetWeakSourceName(_source).c_str());
break;
default:
break;
}
}
void VideoSelection::Load(obs_data_t *obj, const char *name,
const char *typeName)
{
_type = static_cast<VideoSelectionType>(
obs_data_get_int(obj, typeName));
auto target = obs_data_get_string(obj, name);
switch (_type) {
case VideoSelectionType::SOURCE:
_source = GetWeakSourceByName(target);
break;
case VideoSelectionType::OBS_MAIN:
_source = nullptr;
break;
default:
break;
}
}
OBSWeakSource VideoSelection::GetVideo() const
{
if (_type == VideoSelectionType::SOURCE) {
return _source;
}
return nullptr;
}
std::string VideoSelection::ToString() const
{
switch (_type) {
case VideoSelectionType::SOURCE:
return GetWeakSourceName(_source);
case VideoSelectionType::OBS_MAIN:
return obs_module_text("AdvSceneSwitcher.OBSVideoOutput");
default:
break;
}
return "";
}
bool VideoSelection::ValidSelection() const
{
return _type == VideoSelectionType::OBS_MAIN || !!_source;
}
VideoSelectionWidget::VideoSelectionWidget(QWidget *parent, bool addOBSVideoOut)
: QComboBox(parent)
{
setDuplicatesEnabled(true);
populateVideoSelection(this, addOBSVideoOut);
QWidget::connect(this, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SelectionChanged(const QString &)));
}
void VideoSelectionWidget::SetVideoSelection(VideoSelection &t)
{
int idx;
switch (t.GetType()) {
case VideoSelectionType::SOURCE:
setCurrentText(QString::fromStdString(t.ToString()));
break;
case VideoSelectionType::OBS_MAIN:
idx = findText(QString::fromStdString(obs_module_text(
obs_module_text("AdvSceneSwitcher.OBSVideoOutput"))));
if (idx != -1) {
setCurrentIndex(idx);
}
break;
default:
setCurrentIndex(0);
break;
}
}
static bool isFirstEntry(QComboBox *l, QString name, int idx)
{
for (int i = 0; i < l->count(); i++) {
if (l->itemText(i) == name) {
return idx == i;
}
}
return false;
}
bool VideoSelectionWidget::IsOBSVideoOutSelected(const QString &name)
{
if (name == QString::fromStdString(obs_module_text(
"AdvSceneSwitcher.OBSVideoOutput"))) {
return isFirstEntry(this, name, currentIndex());
}
return false;
}
void VideoSelectionWidget::SelectionChanged(const QString &name)
{
VideoSelection t;
if (IsOBSVideoOutSelected(name)) {
t._type = VideoSelectionType::OBS_MAIN;
} else {
auto source = GetWeakSourceByQString(name);
t._type = VideoSelectionType::SOURCE;
t._source = source;
}
emit VideoSelectionChange(t);
}

View File

@ -1,43 +0,0 @@
#pragma once
#include <QComboBox>
#include <obs-module.h>
#include <obs.hpp>
enum class VideoSelectionType {
SOURCE,
OBS_MAIN,
};
class VideoSelection {
public:
void Save(obs_data_t *obj, const char *name = "video",
const char *typeName = "videoType") const;
void Load(obs_data_t *obj, const char *name = "video",
const char *typeName = "videoType");
VideoSelectionType GetType() const { return _type; }
OBSWeakSource GetVideo() const;
std::string ToString() const;
bool ValidSelection() const;
private:
OBSWeakSource _source;
VideoSelectionType _type = VideoSelectionType::SOURCE;
friend class VideoSelectionWidget;
};
class VideoSelectionWidget : public QComboBox {
Q_OBJECT
public:
VideoSelectionWidget(QWidget *parent, bool addOBSVideoOut = true);
void SetVideoSelection(VideoSelection &);
signals:
void VideoSelectionChange(const VideoSelection &);
private slots:
void SelectionChanged(const QString &name);
private:
bool IsOBSVideoOutSelected(const QString &name);
};