Compare commits

..

4 Commits

Author SHA1 Message Date
WarmUpTill
267855fded Cleanup
* Use OBSSourceAutoRelease
* Do not return true if source selection is invalid
2023-12-17 10:40:29 +01:00
WarmUpTill
4bdebb7feb Fix crash when asking for settings backup
This dialog cannot be modal since other plugins might attempt to display
content which might result in a deadlock.
2023-12-16 19:02:38 +01:00
Michael Kirsch
ab5f69d2ef Decrease the minimal interval time to 10ms 2023-12-13 19:29:14 +01:00
Michael Kirsch
63ee36ddfe Enable Area Selection in ScreenshotHelper class 2023-12-13 14:19:17 +01:00
8 changed files with 90 additions and 67 deletions

View File

@@ -119,7 +119,7 @@
<string notr="true">ms</string>
</property>
<property name="minimum">
<number>50</number>
<number>10</number>
</property>
<property name="maximum">
<number>20000</number>

View File

@@ -10,6 +10,7 @@
#include <QMainWindow>
#include <QAction>
#include <QFileDialog>
#include <QTextStream>
#include <QDirIterator>
#include <regex>
#include <filesystem>
@@ -135,7 +136,7 @@ bool AdvSceneSwitcher::eventFilter(QObject *obj, QEvent *event)
/******************************************************************************
* Saving and loading
******************************************************************************/
static void AskForBackup(obs_data_t *obj);
static void AskForBackup(const QString &json);
static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
{
@@ -156,16 +157,25 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
switcher->Stop();
switcher->m.lock();
obs_data_t *obj =
OBSDataAutoRelease obj =
obs_data_get_obj(save_data, "advanced-scene-switcher");
if (!obj) {
obj = obs_data_create();
}
if (switcher->VersionChanged(obj, g_GIT_SHA1)) {
AskForBackup(obj);
auto json = obs_data_get_json(obj);
static QString jsonQString = json ? json : "";
std::thread t([]() {
obs_queue_task(
OBS_TASK_UI,
[](void *) {
AskForBackup(jsonQString);
},
nullptr, false);
});
t.detach();
}
switcher->LoadSettings(obj);
obs_data_release(obj);
switcher->m.unlock();
if (!switcher->stop) {
@@ -174,12 +184,12 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
}
}
static void AskForBackup(obs_data_t *obj)
static void AskForBackup(const QString &json)
{
bool backupSettings = DisplayMessage(
obs_module_text("AdvSceneSwitcher.askBackup"), true);
const bool backupWasConfirmed = DisplayMessage(
obs_module_text("AdvSceneSwitcher.askBackup"), true, false);
if (!backupSettings) {
if (!backupWasConfirmed) {
return;
}
@@ -198,8 +208,8 @@ static void AskForBackup(obs_data_t *obj)
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
return;
}
obs_data_save_json(obj, file.fileName().toUtf8().constData());
auto out = QTextStream(&file);
out << json;
}
/******************************************************************************

View File

@@ -32,7 +32,7 @@ void MacroActionScreenshot::CustomScreenshot(OBSWeakSource &source)
}
auto s = obs_weak_source_get_source(source);
_screenshot.~ScreenshotHelper();
new (&_screenshot) ScreenshotHelper(s, false, 0, true, _path);
new (&_screenshot) ScreenshotHelper(s, QRect(), false, 0, true, _path);
obs_source_release(s);
}

View File

@@ -62,17 +62,17 @@ MacroConditionAudio::~MacroConditionAudio()
bool MacroConditionAudio::CheckOutputCondition()
{
bool ret = false;
auto s = obs_weak_source_get_source(_audioSource.GetSource());
OBSSourceAutoRelease source =
obs_weak_source_get_source(_audioSource.GetSource());
// peak will have a value from -60 db to 0 db so we need to scale it
double curVolume = ((double)_peak + 60) * 1.7;
switch (_outputCondition) {
case OutputCondition::ABOVE:
// peak will have a value from -60 db to 0 db
ret = curVolume > _volume;
break;
case OutputCondition::BELOW:
// peak will have a value from -60 db to 0 db
ret = curVolume < _volume;
break;
default:
@@ -84,21 +84,21 @@ bool MacroConditionAudio::CheckOutputCondition()
// Reset for next check
_peak = -std::numeric_limits<float>::infinity();
obs_source_release(s);
if (_audioSource.GetType() == SourceSelection::Type::VARIABLE) {
ResetVolmeter();
}
return ret;
return ret && source;
}
bool MacroConditionAudio::CheckVolumeCondition()
{
bool ret = false;
auto s = obs_weak_source_get_source(_audioSource.GetSource());
OBSSourceAutoRelease source =
obs_weak_source_get_source(_audioSource.GetSource());
float curVolume = obs_source_get_volume(s);
bool muted = obs_source_muted(s);
float curVolume = obs_source_get_volume(source);
bool muted = obs_source_muted(source);
switch (_volumeCondition) {
case VolumeCondition::ABOVE:
@@ -126,10 +126,9 @@ bool MacroConditionAudio::CheckVolumeCondition()
}
SetTempVarValue("configured_volume", std::to_string(curVolume));
SetTempVarValue("muted", muted ? "true" : "false");
SetTempVarValue("muted", (source && muted) ? "true" : "false");
obs_source_release(s);
return ret;
return ret && source;
}
bool MacroConditionAudio::CheckSyncOffset()
@@ -139,8 +138,9 @@ bool MacroConditionAudio::CheckSyncOffset()
}
bool ret = false;
auto s = obs_weak_source_get_source(_audioSource.GetSource());
auto curOffset = obs_source_get_sync_offset(s) / nsPerMs;
OBSSourceAutoRelease source =
obs_weak_source_get_source(_audioSource.GetSource());
auto curOffset = obs_source_get_sync_offset(source) / nsPerMs;
if (_outputCondition == OutputCondition::ABOVE) {
ret = curOffset > _syncOffset;
} else {
@@ -148,8 +148,7 @@ bool MacroConditionAudio::CheckSyncOffset()
}
SetVariableValue(std::to_string(curOffset));
SetTempVarValue("sync_offset", std::to_string(curOffset));
obs_source_release(s);
return ret;
return ret && source;
}
bool MacroConditionAudio::CheckMonitor()
@@ -159,13 +158,13 @@ bool MacroConditionAudio::CheckMonitor()
}
bool ret = false;
auto s = obs_weak_source_get_source(_audioSource.GetSource());
ret = obs_source_get_monitoring_type(s) == _monitorType;
OBSSourceAutoRelease source =
obs_weak_source_get_source(_audioSource.GetSource());
ret = obs_source_get_monitoring_type(source) == _monitorType;
SetVariableValue("");
SetTempVarValue("monitor",
std::to_string(obs_source_get_monitoring_type(s)));
obs_source_release(s);
return ret;
std::to_string(obs_source_get_monitoring_type(source)));
return ret && source;
}
bool MacroConditionAudio::CheckBalance()
@@ -175,8 +174,9 @@ bool MacroConditionAudio::CheckBalance()
}
bool ret = false;
auto s = obs_weak_source_get_source(_audioSource.GetSource());
auto curBalance = obs_source_get_balance_value(s);
OBSSourceAutoRelease source =
obs_weak_source_get_source(_audioSource.GetSource());
auto curBalance = obs_source_get_balance_value(source);
if (_outputCondition == OutputCondition::ABOVE) {
ret = curBalance > _balance;
} else {
@@ -184,8 +184,7 @@ bool MacroConditionAudio::CheckBalance()
}
SetVariableValue(std::to_string(curBalance));
SetTempVarValue("balance", std::to_string(curBalance));
obs_source_release(s);
return ret;
return ret && source;
}
bool MacroConditionAudio::CheckCondition()
@@ -239,13 +238,12 @@ obs_volmeter_t *AddVolmeterToSource(MacroConditionAudio *entry,
obs_volmeter_t *volmeter = obs_volmeter_create(OBS_FADER_LOG);
obs_volmeter_add_callback(volmeter, MacroConditionAudio::SetVolumeLevel,
entry);
obs_source_t *as = obs_weak_source_get_source(source);
if (!obs_volmeter_attach_source(volmeter, as)) {
const char *name = obs_source_get_name(as);
OBSSourceAutoRelease audioSource = obs_weak_source_get_source(source);
if (!obs_volmeter_attach_source(volmeter, audioSource)) {
const char *name = obs_source_get_name(audioSource);
blog(LOG_WARNING, "failed to attach volmeter to source %s",
name);
}
obs_source_release(as);
return volmeter;
}
@@ -455,10 +453,9 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
void MacroConditionAudioEdit::UpdateVolmeterSource()
{
delete _volMeter;
obs_source_t *soruce = obs_weak_source_get_source(
OBSSourceAutoRelease soruce = obs_weak_source_get_source(
_entryData->_audioSource.GetSource());
_volMeter = new VolControl(soruce);
obs_source_release(soruce);
_volMeter = new VolControl(soruce.Get());
QLayout *layout = this->layout();
layout->addWidget(_volMeter);

View File

@@ -215,8 +215,15 @@ void MacroConditionVideo::GetScreenshot(bool blocking)
{
auto source = obs_weak_source_get_source(_video.GetVideo());
_screenshotData.~ScreenshotHelper();
new (&_screenshotData)
ScreenshotHelper(source, blocking, GetSwitcher()->interval);
QRect screenshotArea;
if (_areaParameters.enable && _condition != VideoCondition::NO_IMAGE) {
screenshotArea.setRect(_areaParameters.area.x,
_areaParameters.area.y,
_areaParameters.area.width,
_areaParameters.area.height);
}
new (&_screenshotData) ScreenshotHelper(
source, screenshotArea, blocking, GetSwitcher()->interval);
obs_source_release(source);
_getNextScreenshot = false;
}
@@ -361,13 +368,6 @@ bool MacroConditionVideo::CheckColor()
bool MacroConditionVideo::Compare()
{
if (_areaParameters.enable && _condition != VideoCondition::NO_IMAGE) {
_screenshotData.image = _screenshotData.image.copy(
_areaParameters.area.x, _areaParameters.area.y,
_areaParameters.area.width,
_areaParameters.area.height);
}
if (_condition != VideoCondition::OCR) {
SetVariableValue("");
}

View File

@@ -255,7 +255,13 @@ void PreviewImage::CreateImage(const VideoInput &video, PreviewType type,
VideoCondition condition)
{
auto source = obs_weak_source_get_source(video.GetVideo());
ScreenshotHelper screenshot(source, true);
QRect screenshotArea;
if (areaParams.enable && type == PreviewType::SHOW_MATCH) {
screenshotArea.setRect(areaParams.area.x, areaParams.area.y,
areaParams.area.width,
areaParams.area.height);
}
ScreenshotHelper screenshot(source, screenshotArea, true);
obs_source_release(source);
if (!video.ValidSelection() || !screenshot.done) {
@@ -274,11 +280,6 @@ void PreviewImage::CreateImage(const VideoInput &video, PreviewType type,
if (type == PreviewType::SHOW_MATCH) {
std::unique_lock<std::mutex> lock(_mtx);
if (areaParams.enable) {
screenshot.image = screenshot.image.copy(
areaParams.area.x, areaParams.area.y,
areaParams.area.width, areaParams.area.height);
}
// Will emit status label update
MarkMatch(screenshot.image, patternMatchParams,
patternImageData, objDetectParams, ocrParams,

View File

@@ -7,10 +7,11 @@ namespace advss {
static void ScreenshotTick(void *param, float);
ScreenshotHelper::ScreenshotHelper(obs_source_t *source, bool blocking,
int timeout, bool saveToFile,
ScreenshotHelper::ScreenshotHelper(obs_source_t *source, const QRect &subarea,
bool blocking, int timeout, bool saveToFile,
std::string path)
: weakSource(OBSGetWeakRef(source)),
_subarea(subarea),
_blocking(blocking),
_saveToFile(saveToFile),
_path(path)
@@ -62,7 +63,12 @@ void ScreenshotHelper::Screenshot()
cy = ovi.base_height;
}
if (!cx || !cy) {
QRect renderArea(0, 0, cx, cy);
if (!_subarea.isEmpty()) {
renderArea &= _subarea;
}
if (renderArea.isEmpty()) {
vblog(LOG_WARNING,
"Cannot screenshot \"%s\", invalid target size",
obs_source_get_name(source));
@@ -71,16 +77,24 @@ void ScreenshotHelper::Screenshot()
return;
}
cx = renderArea.width();
cy = renderArea.height();
texrender = gs_texrender_create(GS_RGBA, GS_ZS_NONE);
stagesurf = gs_stagesurface_create(cx, cy, GS_RGBA);
stagesurf = gs_stagesurface_create(renderArea.width(),
renderArea.height(), GS_RGBA);
gs_texrender_reset(texrender);
if (gs_texrender_begin(texrender, cx, cy)) {
if (gs_texrender_begin(texrender, renderArea.width(),
renderArea.height())) {
vec4 zero;
vec4_zero(&zero);
gs_clear(GS_CLEAR_COLOR, &zero, 0.0f, 0);
gs_ortho(0.0f, (float)cx, 0.0f, (float)cy, -100.0f, 100.0f);
gs_ortho((float)(renderArea.left()),
(float)(renderArea.right() + 1),
(float)(renderArea.top()),
(float)(renderArea.bottom() + 1), -100.0f, 100.0f);
gs_blend_state_push();
gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO);

View File

@@ -12,9 +12,9 @@ namespace advss {
class ScreenshotHelper {
public:
ScreenshotHelper() = default;
ScreenshotHelper(obs_source_t *source, bool blocking = false,
int timeout = 1000, bool saveToFile = false,
std::string path = "");
ScreenshotHelper(obs_source_t *source, const QRect &subarea = QRect(),
bool blocking = false, int timeout = 1000,
bool saveToFile = false, std::string path = "");
ScreenshotHelper &operator=(const ScreenshotHelper &) = delete;
ScreenshotHelper(const ScreenshotHelper &) = delete;
~ScreenshotHelper();
@@ -39,6 +39,7 @@ public:
private:
std::atomic_bool _initDone = false;
QRect _subarea = QRect();
bool _blocking = false;
std::thread _saveThread;
bool _saveToFile = false;