diff --git a/src/external-macro-modules/opencv/macro-condition-video.cpp b/src/external-macro-modules/opencv/macro-condition-video.cpp index 999d9796..5d8bb512 100644 --- a/src/external-macro-modules/opencv/macro-condition-video.cpp +++ b/src/external-macro-modules/opencv/macro-condition-video.cpp @@ -78,19 +78,21 @@ bool MacroConditionVideo::CheckCondition() return _lastMatchResult; } - if (_screenshotData && _screenshotData->done) { + if (_screenshotData.done) { match = Compare(); _lastMatchResult = match; if (!requiresFileInput(_condition)) { - _matchImage = std::move(_screenshotData->image); + _matchImage = std::move(_screenshotData.image); } - _screenshotData.reset(nullptr); + _getNextScreenshot = true; } else { match = _lastMatchResult; } - GetScreenshot(); + if (_getNextScreenshot) { + GetScreenshot(); + } return match; } @@ -178,8 +180,10 @@ std::string MacroConditionVideo::GetShortDesc() void MacroConditionVideo::GetScreenshot() { auto source = obs_weak_source_get_source(_videoSource); - _screenshotData = std::make_unique(source); + _screenshotData.~AdvSSScreenshotObj(); + new (&_screenshotData) AdvSSScreenshotObj(source); obs_source_release(source); + _getNextScreenshot = false; } // Assumption is that QImage uses Format_RGBA8888. @@ -285,7 +289,7 @@ void matchPattern(QImage &img, QImage &pattern, double threshold, bool MacroConditionVideo::ScreenshotContainsPattern() { cv::Mat result; - matchPattern(_screenshotData->image, _patternData, _patternThreshold, + matchPattern(_screenshotData.image, _patternData, _patternThreshold, result, _useAlphaAsMask); return countNonZero(result) > 0; } @@ -295,11 +299,11 @@ bool MacroConditionVideo::OutputChanged() if (_usePatternForChangedCheck) { cv::Mat result; _patternData = createPatternData(_matchImage); - matchPattern(_screenshotData->image, _patternData, + matchPattern(_screenshotData.image, _patternData, _patternThreshold, result, _useAlphaAsMask); return countNonZero(result) == 0; } - return _screenshotData->image != _matchImage; + return _screenshotData.image != _matchImage; } std::vector matchObject(QImage &img, cv::CascadeClassifier &cascade, @@ -322,7 +326,7 @@ std::vector matchObject(QImage &img, cv::CascadeClassifier &cascade, bool MacroConditionVideo::ScreenshotContainsObject() { - auto objects = matchObject(_screenshotData->image, _objectCascade, + auto objects = matchObject(_screenshotData.image, _objectCascade, _scaleFactor, _minNeighbors, {_minSizeX, _minSizeY}, {_maxSizeX, _maxSizeY}); @@ -333,15 +337,15 @@ bool MacroConditionVideo::Compare() { switch (_condition) { case VideoCondition::MATCH: - return _screenshotData->image == _matchImage; + return _screenshotData.image == _matchImage; case VideoCondition::DIFFER: - return _screenshotData->image != _matchImage; + return _screenshotData.image != _matchImage; case VideoCondition::HAS_CHANGED: return OutputChanged(); case VideoCondition::HAS_NOT_CHANGED: return !OutputChanged(); case VideoCondition::NO_IMAGE: - return _screenshotData->image.isNull(); + return _screenshotData.image.isNull(); case VideoCondition::PATTERN: return ScreenshotContainsPattern(); case VideoCondition::OBJECT: @@ -682,7 +686,7 @@ void MacroConditionVideoEdit::ImageBrowseButtonClicked() } else { auto source = obs_weak_source_get_source(_entryData->_videoSource); - auto screenshot = std::make_unique(source); + AdvSSScreenshotObj screenshot(source); obs_source_release(source); path = QFileDialog::getSaveFileName(this); @@ -693,16 +697,15 @@ void MacroConditionVideoEdit::ImageBrowseButtonClicked() if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return; } - if (!screenshot->done) { // Screenshot usually completed by now + if (!screenshot.done) { // Screenshot usually completed by now std::this_thread::sleep_for(std::chrono::seconds(1)); } - if (!screenshot->done) { + if (!screenshot.done) { DisplayMessage(obs_module_text( "AdvSceneSwitcher.condition.video.screenshotFail")); return; } - - screenshot->image.save(path); + screenshot.image.save(path); } _imagePath->SetPath(path); ImagePathChanged(path); diff --git a/src/external-macro-modules/opencv/macro-condition-video.hpp b/src/external-macro-modules/opencv/macro-condition-video.hpp index 1e16913e..bacee9d6 100644 --- a/src/external-macro-modules/opencv/macro-condition-video.hpp +++ b/src/external-macro-modules/opencv/macro-condition-video.hpp @@ -77,7 +77,8 @@ private: bool Compare(); bool CheckShouldBeSkipped(); - std::unique_ptr _screenshotData = nullptr; + bool _getNextScreenshot = true; + AdvSSScreenshotObj _screenshotData; QImage _matchImage; std::string _modelDataPath = obs_get_module_data_path(obs_current_module()) + diff --git a/src/headers/screenshot-helper.hpp b/src/headers/screenshot-helper.hpp index 72909cc6..a931a3b9 100644 --- a/src/headers/screenshot-helper.hpp +++ b/src/headers/screenshot-helper.hpp @@ -6,7 +6,10 @@ class AdvSSScreenshotObj { public: + AdvSSScreenshotObj() = default; AdvSSScreenshotObj(obs_source_t *source); + AdvSSScreenshotObj &operator=(const AdvSSScreenshotObj &) = delete; + AdvSSScreenshotObj(const AdvSSScreenshotObj &) = delete; ~AdvSSScreenshotObj(); void Screenshot(); @@ -17,7 +20,6 @@ public: gs_texrender_t *texrender = nullptr; gs_stagesurf_t *stagesurf = nullptr; OBSWeakSource weakSource; - std::string path; QImage image; uint32_t cx = 0; uint32_t cy = 0; @@ -26,4 +28,7 @@ public: bool done = false; std::chrono::high_resolution_clock::time_point time; + +private: + bool _initDone = false; }; diff --git a/src/screenshot-helper.cpp b/src/screenshot-helper.cpp index de395b54..ff7f0b74 100644 --- a/src/screenshot-helper.cpp +++ b/src/screenshot-helper.cpp @@ -6,17 +6,20 @@ static void ScreenshotTick(void *param, float); AdvSSScreenshotObj::AdvSSScreenshotObj(obs_source_t *source) : weakSource(OBSGetWeakRef(source)) { + _initDone = true; obs_add_tick_callback(ScreenshotTick, this); } AdvSSScreenshotObj::~AdvSSScreenshotObj() { - obs_enter_graphics(); - gs_stagesurface_destroy(stagesurf); - gs_texrender_destroy(texrender); - obs_leave_graphics(); + if (_initDone) { + obs_enter_graphics(); + gs_stagesurface_destroy(stagesurf); + gs_texrender_destroy(texrender); + obs_leave_graphics(); - obs_remove_tick_callback(ScreenshotTick, this); + obs_remove_tick_callback(ScreenshotTick, this); + } } void AdvSSScreenshotObj::Screenshot()