mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-10 22:05:06 +00:00
nvidia/vfx/denoising: Refactor onto effect class
This commit is contained in:
parent
092ba2cad5
commit
8d029c97a2
2 changed files with 54 additions and 92 deletions
|
@ -44,8 +44,6 @@ streamfx::nvidia::vfx::denoising::~denoising()
|
||||||
auto gctx = ::streamfx::obs::gs::context();
|
auto gctx = ::streamfx::obs::gs::context();
|
||||||
auto cctx = ::streamfx::nvidia::cuda::obs::get()->get_context()->enter();
|
auto cctx = ::streamfx::nvidia::cuda::obs::get()->get_context()->enter();
|
||||||
|
|
||||||
_fx.reset();
|
|
||||||
|
|
||||||
// Clean up state buffer.
|
// Clean up state buffer.
|
||||||
_nvcuda->get_cuda()->cuMemFree(_state);
|
_nvcuda->get_cuda()->cuMemFree(_state);
|
||||||
|
|
||||||
|
@ -57,51 +55,16 @@ streamfx::nvidia::vfx::denoising::~denoising()
|
||||||
_convert_to_u8.reset();
|
_convert_to_u8.reset();
|
||||||
_output.reset();
|
_output.reset();
|
||||||
_tmp.reset();
|
_tmp.reset();
|
||||||
|
|
||||||
// Release CUDA, CVImage, and Video Effects SDK.
|
|
||||||
_nvvfx.reset();
|
|
||||||
_nvcvi.reset();
|
|
||||||
_nvcuda.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
streamfx::nvidia::vfx::denoising::denoising()
|
streamfx::nvidia::vfx::denoising::denoising()
|
||||||
: _nvcuda(::streamfx::nvidia::cuda::obs::get()), _nvcvi(::streamfx::nvidia::cv::cv::get()),
|
: effect(EFFECT_DENOISING), _dirty(true), _input(), _convert_to_fp32(), _source(), _destination(), _convert_to_u8(),
|
||||||
_nvvfx(::streamfx::nvidia::vfx::vfx::get()), _state(0), _state_size(0), _strength(1.), _input(), _source(),
|
_output(), _tmp(), _state(0), _state_size(0), _strength(1.)
|
||||||
_destination(), _convert_to_u8(), _output(), _tmp(), _dirty(true)
|
|
||||||
{
|
{
|
||||||
// Enter Graphics and CUDA context.
|
// Enter Graphics and CUDA context.
|
||||||
auto gctx = ::streamfx::obs::gs::context();
|
auto gctx = ::streamfx::obs::gs::context();
|
||||||
auto cctx = ::streamfx::nvidia::cuda::obs::get()->get_context()->enter();
|
auto cctx = ::streamfx::nvidia::cuda::obs::get()->get_context()->enter();
|
||||||
|
|
||||||
{ // Try & Create the Denoising effect.
|
|
||||||
::streamfx::nvidia::vfx::handle_t handle;
|
|
||||||
if (auto res = _nvvfx->NvVFX_CreateEffect(::streamfx::nvidia::vfx::EFFECT_DENOISING, &handle);
|
|
||||||
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
|
||||||
D_LOG_ERROR("Failed to create effect due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
|
||||||
throw std::runtime_error("CreateEffect failed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_fx = std::shared_ptr<void>(handle, [](::streamfx::nvidia::vfx::handle_t handle) {
|
|
||||||
::streamfx::nvidia::vfx::vfx::get()->NvVFX_DestroyEffect(handle);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign the appropriate CUDA stream.
|
|
||||||
if (auto res = _nvvfx->NvVFX_SetCudaStream(_fx.get(), ::streamfx::nvidia::vfx::PARAMETER_CUDA_STREAM,
|
|
||||||
_nvcuda->get_stream()->get());
|
|
||||||
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
|
||||||
D_LOG_ERROR("Failed to set CUDA stream due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
|
||||||
throw std::runtime_error("SetCudaStream failed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the proper model directory.
|
|
||||||
if (auto res = _nvvfx->NvVFX_SetString(_fx.get(), ::streamfx::nvidia::vfx::PARAMETER_MODEL_DIRECTORY,
|
|
||||||
_nvvfx->model_path().generic_u8string().c_str());
|
|
||||||
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
|
||||||
D_LOG_ERROR("Failed to set model directory due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
|
||||||
throw std::runtime_error("SetString failed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the strength, scale and buffers.
|
// Set the strength, scale and buffers.
|
||||||
set_strength(_strength);
|
set_strength(_strength);
|
||||||
resize(160, 90);
|
resize(160, 90);
|
||||||
|
@ -121,9 +84,8 @@ void streamfx::nvidia::vfx::denoising::set_strength(float strength)
|
||||||
// Update Effect
|
// Update Effect
|
||||||
auto gctx = ::streamfx::obs::gs::context();
|
auto gctx = ::streamfx::obs::gs::context();
|
||||||
auto cctx = _nvcuda->get_context()->enter();
|
auto cctx = _nvcuda->get_context()->enter();
|
||||||
if (auto res = _nvvfx->NvVFX_SetF32(_fx.get(), ::streamfx::nvidia::vfx::PARAMETER_STRENGTH, _strength);
|
if (auto res = set(PARAMETER_STRENGTH, _strength); res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
||||||
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
D_LOG_ERROR("Failed to set '%s' to %1.3f.", PARAMETER_STRENGTH, _strength);
|
||||||
D_LOG_ERROR("Failed to set '%s' to %1.3f.", ::streamfx::nvidia::vfx::PARAMETER_STRENGTH, _strength);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,16 +223,16 @@ void streamfx::nvidia::vfx::denoising::resize(uint32_t width, uint32_t height)
|
||||||
::streamfx::nvidia::cv::component_layout::PLANAR, ::streamfx::nvidia::cv::memory_location::GPU, 1);
|
::streamfx::nvidia::cv::component_layout::PLANAR, ::streamfx::nvidia::cv::memory_location::GPU, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input Size was changed.
|
if (!_input || (_input->get_image()->width != width) || (_input->get_image()->height != height)) {
|
||||||
if (!_input || !_source || !_destination || !_output || !_state || (width != _input->get_texture()->get_width())
|
|
||||||
|| (height != _input->get_texture()->get_height()) || (width != _output->get_texture()->get_width())
|
|
||||||
|| (height != _output->get_texture()->get_height())) {
|
|
||||||
if (_input) {
|
if (_input) {
|
||||||
_input->resize(width, height);
|
_input->resize(width, height);
|
||||||
} else {
|
} else {
|
||||||
_input = std::make_shared<::streamfx::nvidia::cv::texture>(width, height, GS_RGBA_UNORM);
|
_input = std::make_shared<::streamfx::nvidia::cv::texture>(width, height, GS_RGBA_UNORM);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_convert_to_fp32 || (_convert_to_fp32->get_image()->width != width)
|
||||||
|
|| (_convert_to_fp32->get_image()->height != height)) {
|
||||||
if (_convert_to_fp32) {
|
if (_convert_to_fp32) {
|
||||||
_convert_to_fp32->resize(width, height);
|
_convert_to_fp32->resize(width, height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -278,7 +240,9 @@ void streamfx::nvidia::vfx::denoising::resize(uint32_t width, uint32_t height)
|
||||||
width, height, ::streamfx::nvidia::cv::pixel_format::RGBA, ::streamfx::nvidia::cv::component_type::FP32,
|
width, height, ::streamfx::nvidia::cv::pixel_format::RGBA, ::streamfx::nvidia::cv::component_type::FP32,
|
||||||
::streamfx::nvidia::cv::component_layout::PLANAR, ::streamfx::nvidia::cv::memory_location::GPU, 1);
|
::streamfx::nvidia::cv::component_layout::PLANAR, ::streamfx::nvidia::cv::memory_location::GPU, 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_source || (_source->get_image()->width != width) || (_source->get_image()->height != height)) {
|
||||||
if (_source) {
|
if (_source) {
|
||||||
_source->resize(width, height);
|
_source->resize(width, height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -287,13 +251,17 @@ void streamfx::nvidia::vfx::denoising::resize(uint32_t width, uint32_t height)
|
||||||
::streamfx::nvidia::cv::component_layout::PLANAR, ::streamfx::nvidia::cv::memory_location::GPU, 1);
|
::streamfx::nvidia::cv::component_layout::PLANAR, ::streamfx::nvidia::cv::memory_location::GPU, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto res = _nvvfx->NvVFX_SetImage(_fx.get(), ::streamfx::nvidia::vfx::PARAMETER_INPUT_IMAGE_0,
|
if (auto res = set(::streamfx::nvidia::vfx::PARAMETER_INPUT_IMAGE_0, _source);
|
||||||
_source->get_image());
|
|
||||||
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
||||||
D_LOG_ERROR("Failed to set input image due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
D_LOG_ERROR("Failed to set input image due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
||||||
|
_source.reset();
|
||||||
throw std::runtime_error("SetImage failed.");
|
throw std::runtime_error("SetImage failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_destination || (_destination->get_image()->width != width) || (_destination->get_image()->height != height)) {
|
||||||
if (_destination) {
|
if (_destination) {
|
||||||
_destination->resize(width, height);
|
_destination->resize(width, height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -302,6 +270,18 @@ void streamfx::nvidia::vfx::denoising::resize(uint32_t width, uint32_t height)
|
||||||
::streamfx::nvidia::cv::component_layout::PLANAR, ::streamfx::nvidia::cv::memory_location::GPU, 1);
|
::streamfx::nvidia::cv::component_layout::PLANAR, ::streamfx::nvidia::cv::memory_location::GPU, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto res = set(::streamfx::nvidia::vfx::PARAMETER_OUTPUT_IMAGE_0, _destination);
|
||||||
|
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
||||||
|
D_LOG_ERROR("Failed to set output image due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
||||||
|
_destination.reset();
|
||||||
|
throw std::runtime_error("SetImage failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_convert_to_u8 || (_convert_to_u8->get_image()->width != width)
|
||||||
|
|| (_convert_to_u8->get_image()->height != height)) {
|
||||||
if (_convert_to_u8) {
|
if (_convert_to_u8) {
|
||||||
_convert_to_u8->resize(width, height);
|
_convert_to_u8->resize(width, height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -310,25 +290,22 @@ void streamfx::nvidia::vfx::denoising::resize(uint32_t width, uint32_t height)
|
||||||
::streamfx::nvidia::cv::component_type::UINT8, ::streamfx::nvidia::cv::component_layout::INTERLEAVED,
|
::streamfx::nvidia::cv::component_type::UINT8, ::streamfx::nvidia::cv::component_layout::INTERLEAVED,
|
||||||
::streamfx::nvidia::cv::memory_location::GPU, 1);
|
::streamfx::nvidia::cv::memory_location::GPU, 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_output || (_output->get_image()->width != width) || (_output->get_image()->height != height)) {
|
||||||
if (_output) {
|
if (_output) {
|
||||||
_output->resize(width, height);
|
_output->resize(width, height);
|
||||||
} else {
|
} else {
|
||||||
_output = std::make_shared<::streamfx::nvidia::cv::texture>(width, height, GS_RGBA_UNORM);
|
_output = std::make_shared<::streamfx::nvidia::cv::texture>(width, height, GS_RGBA_UNORM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto res = _nvvfx->NvVFX_SetImage(_fx.get(), ::streamfx::nvidia::vfx::PARAMETER_OUTPUT_IMAGE_0,
|
|
||||||
_destination->get_image());
|
|
||||||
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
|
||||||
D_LOG_ERROR("Failed to set output image due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
|
||||||
throw std::runtime_error("SetImage failed.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Reallocate and clean state.
|
if (!_state || _dirty) { // Reallocate and clean state.
|
||||||
_nvvfx->NvVFX_GetU32(_fx.get(), ::streamfx::nvidia::vfx::PARAMETER_STATE_SIZE, &_state_size);
|
|
||||||
if (_state) {
|
if (_state) {
|
||||||
//_nvcuda->get_cuda()->cuMemFree(_state);
|
_nvcuda->get_cuda()->cuMemFree(_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_nvvfx->NvVFX_GetU32(_fx.get(), ::streamfx::nvidia::vfx::PARAMETER_STATE_SIZE, &_state_size);
|
||||||
_nvcuda->get_cuda()->cuMemAlloc(&_state, _state_size);
|
_nvcuda->get_cuda()->cuMemAlloc(&_state, _state_size);
|
||||||
_nvcuda->get_cuda()->cuMemsetD8(_state, 0, _state_size);
|
_nvcuda->get_cuda()->cuMemsetD8(_state, 0, _state_size);
|
||||||
|
|
||||||
|
@ -339,7 +316,6 @@ void streamfx::nvidia::vfx::denoising::resize(uint32_t width, uint32_t height)
|
||||||
D_LOG_ERROR("Failed to set state due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
D_LOG_ERROR("Failed to set state due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
||||||
throw std::runtime_error("SetObject failed.");
|
throw std::runtime_error("SetObject failed.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
}
|
}
|
||||||
|
@ -348,23 +324,12 @@ void streamfx::nvidia::vfx::denoising::resize(uint32_t width, uint32_t height)
|
||||||
void streamfx::nvidia::vfx::denoising::load()
|
void streamfx::nvidia::vfx::denoising::load()
|
||||||
{
|
{
|
||||||
auto gctx = ::streamfx::obs::gs::context();
|
auto gctx = ::streamfx::obs::gs::context();
|
||||||
{
|
|
||||||
auto cctx = ::streamfx::nvidia::cuda::obs::get()->get_context()->enter();
|
auto cctx = ::streamfx::nvidia::cuda::obs::get()->get_context()->enter();
|
||||||
if (auto res = _nvvfx->NvVFX_SetCudaStream(_fx.get(), ::streamfx::nvidia::vfx::PARAMETER_CUDA_STREAM,
|
|
||||||
_nvcuda->get_stream()->get());
|
|
||||||
res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
|
||||||
D_LOG_ERROR("Failed to set CUDA stream due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
|
||||||
throw std::runtime_error("SetCudaStream failed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
if (auto res = effect::load(); res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
||||||
auto cctx = ::streamfx::nvidia::cuda::obs::get()->get_context()->enter();
|
|
||||||
if (auto res = _nvvfx->NvVFX_Load(_fx.get()); res != ::streamfx::nvidia::cv::result::SUCCESS) {
|
|
||||||
D_LOG_ERROR("Failed to initialize effect due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
D_LOG_ERROR("Failed to initialize effect due to error: %s", _nvcvi->NvCV_GetErrorStringFromCode(res));
|
||||||
throw std::runtime_error("Load failed.");
|
throw std::runtime_error("Load failed.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_dirty = false;
|
_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "nvidia-vfx-effect.hpp"
|
||||||
#include "nvidia-vfx.hpp"
|
#include "nvidia-vfx.hpp"
|
||||||
#include "nvidia/cuda/nvidia-cuda-gs-texture.hpp"
|
#include "nvidia/cuda/nvidia-cuda-gs-texture.hpp"
|
||||||
#include "nvidia/cuda/nvidia-cuda-obs.hpp"
|
#include "nvidia/cuda/nvidia-cuda-obs.hpp"
|
||||||
|
@ -28,11 +29,8 @@
|
||||||
#include "obs/gs/gs-texture.hpp"
|
#include "obs/gs/gs-texture.hpp"
|
||||||
|
|
||||||
namespace streamfx::nvidia::vfx {
|
namespace streamfx::nvidia::vfx {
|
||||||
class denoising {
|
class denoising : protected effect {
|
||||||
std::shared_ptr<::streamfx::nvidia::cuda::obs> _nvcuda;
|
bool _dirty;
|
||||||
std::shared_ptr<::streamfx::nvidia::cv::cv> _nvcvi;
|
|
||||||
std::shared_ptr<::streamfx::nvidia::vfx::vfx> _nvvfx;
|
|
||||||
std::shared_ptr<void> _fx;
|
|
||||||
|
|
||||||
std::shared_ptr<::streamfx::nvidia::cv::texture> _input;
|
std::shared_ptr<::streamfx::nvidia::cv::texture> _input;
|
||||||
std::shared_ptr<::streamfx::nvidia::cv::image> _convert_to_fp32;
|
std::shared_ptr<::streamfx::nvidia::cv::image> _convert_to_fp32;
|
||||||
|
@ -41,14 +39,13 @@ namespace streamfx::nvidia::vfx {
|
||||||
std::shared_ptr<::streamfx::nvidia::cv::image> _convert_to_u8;
|
std::shared_ptr<::streamfx::nvidia::cv::image> _convert_to_u8;
|
||||||
std::shared_ptr<::streamfx::nvidia::cv::texture> _output;
|
std::shared_ptr<::streamfx::nvidia::cv::texture> _output;
|
||||||
std::shared_ptr<::streamfx::nvidia::cv::image> _tmp;
|
std::shared_ptr<::streamfx::nvidia::cv::image> _tmp;
|
||||||
|
|
||||||
void* _states[1];
|
void* _states[1];
|
||||||
::streamfx::nvidia::cuda::device_ptr_t _state;
|
::streamfx::nvidia::cuda::device_ptr_t _state;
|
||||||
uint32_t _state_size;
|
uint32_t _state_size;
|
||||||
|
|
||||||
float _strength;
|
float _strength;
|
||||||
|
|
||||||
bool _dirty;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~denoising();
|
~denoising();
|
||||||
denoising();
|
denoising();
|
||||||
|
|
Loading…
Reference in a new issue