From f0b0b0d33d29bd5df39daaa3ac177db96b64a5e8 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Tue, 26 Oct 2021 23:38:43 +0200 Subject: [PATCH] filter/denoising: Wait for internal task to be completed --- source/filters/filter-denoising.cpp | 43 +++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/source/filters/filter-denoising.cpp b/source/filters/filter-denoising.cpp index 8844dd8a..670ffe06 100644 --- a/source/filters/filter-denoising.cpp +++ b/source/filters/filter-denoising.cpp @@ -90,6 +90,8 @@ denoising_instance::denoising_instance(obs_data_t* data, obs_source_t* self) _size(1, 1), _provider_ready(false), _provider(denoising_provider::INVALID), _provider_lock(), _provider_task(), _input(), _output() { + D_LOG_DEBUG("Initializating... (Addr: 0x%" PRIuPTR ")", this); + { ::streamfx::obs::gs::context gctx; @@ -120,16 +122,28 @@ denoising_instance::denoising_instance(obs_data_t* data, obs_source_t* self) denoising_instance::~denoising_instance() { - // TODO: Make this asynchronous. - std::unique_lock ul(_provider_lock); - switch (_provider) { + D_LOG_DEBUG("Finalizing... (Addr: 0x%" PRIuPTR ")", this); + + { // Unload the underlying effect ASAP. + std::unique_lock ul(_provider_lock); + + // De-queue the underlying task. + if (_provider_task) { + streamfx::threadpool()->pop(_provider_task); + _provider_task->await_completion(); + _provider_task.reset(); + } + + // TODO: Make this asynchronous. + switch (_provider) { #ifdef ENABLE_FILTER_DENOISING_NVIDIA - case denoising_provider::NVIDIA_DENOISING: - nvvfx_denoising_unload(); - break; + case denoising_provider::NVIDIA_DENOISING: + nvvfx_denoising_unload(); + break; #endif - default: - break; + default: + break; + } } } @@ -370,17 +384,24 @@ void streamfx::filter::denoising::denoising_instance::switch_provider(denoising_ D_LOG_INFO("Instance '%s' is switching provider from '%s' to '%s'.", obs_source_get_name(_self), cstring(_provider), cstring(provider)); - // 1.If there is an existing task, attempt to cancel it. + // If there is an existing task, attempt to cancel it. if (_provider_task) { + // De-queue it. streamfx::threadpool()->pop(_provider_task); + + // Await the death of the task itself. + _provider_task->await_completion(); + + // Clear any memory associated with it. + _provider_task.reset(); } - // 2. Build data to pass into the task. + // Build data to pass into the task. auto spd = std::make_shared(); spd->provider = _provider; _provider = provider; - // 3. Then spawn a new task to switch provider. + // Then spawn a new task to switch provider. _provider_task = streamfx::threadpool()->push( std::bind(&denoising_instance::task_switch_provider, this, std::placeholders::_1), spd); }