obs-filters: NVIDIA Background Removal variable mask refresh

This adds a slider to set variable mask refresh rate.
This is useful to alleviate the GPU load so that the mask generation
can optionally be done every n frames (n = 1-4).

Signed-off-by: pkv <pkv@obsproject.com>
This commit is contained in:
pkv
2022-10-23 22:22:45 +02:00
parent bed0175326
commit f7086f2ec0
2 changed files with 29 additions and 1 deletions
@@ -126,6 +126,8 @@ Greenscreen.Quality="Quality (higher GPU usage, better quality)"
Greenscreen.Performance="Performance (lower GPU usage, good quality)"
Greenscreen.Threshold="Threshold"
Greenscreen.Deprecation="WARNING: Please upgrade both NVIDIA Video & Audio SDK. Your current version of Video SDK is outdated."
Greenscreen.Processing="Mask refresh frequency in frames"
Greenscreen.Processing.Hint="This alleviates GPU load by generating a mask every N frames only (2 on default)."
Upward.Compressor="Upward Compressor"
3BandEq="3-Band Equalizer"
3BandEq.low="Low"
@@ -27,6 +27,7 @@
#define S_MODE_PERF 1
#define S_THRESHOLDFX "threshold"
#define S_THRESHOLDFX_DEFAULT 1.0
#define S_PROCESSING "processing_interval"
#define MT_ obs_module_text
#define TEXT_MODE MT_("Greenscreen.Mode")
@@ -34,6 +35,8 @@
#define TEXT_MODE_PERF MT_("Greenscreen.Performance")
#define TEXT_MODE_THRESHOLD MT_("Greenscreen.Threshold")
#define TEXT_DEPRECATION MT_("Greenscreen.Deprecation")
#define TEXT_PROCESSING MT_("Greenscreen.Processing")
#define TEXT_PROCESSING_HINT MT_("Greenscreen.Processing.Hint")
bool nvvfx_loaded = false;
bool nvvfx_new_sdk = false;
@@ -72,6 +75,13 @@ struct nv_greenscreen_data {
gs_eparam_t *threshold_param;
gs_eparam_t *multiplier_param;
float threshold;
/* Every nth frame is processed through the FX (where n =
* processing_interval) so that the same mask is used for n consecutive
* frames. This is to alleviate the GPU load. Default: 1 (process every frame).
*/
int processing_interval;
int processing_counter;
};
static const char *nv_greenscreen_filter_name(void *unused)
@@ -93,6 +103,8 @@ static void nv_greenscreen_filter_update(void *data, obs_data_t *settings)
error("Error loading AI Greenscreen FX %i", vfxErr);
}
filter->threshold = (float)obs_data_get_double(settings, S_THRESHOLDFX);
filter->processing_interval =
(int)obs_data_get_int(settings, S_PROCESSING);
}
static void nv_greenscreen_filter_actual_destroy(void *data)
@@ -423,6 +435,8 @@ static void *nv_greenscreen_filter_create(obs_data_t *settings,
filter->initial_render = false;
os_atomic_set_bool(&filter->processing_stop, false);
filter->handler = NULL;
filter->processing_interval = 1;
filter->processing_counter = 0;
/* 1. Create FX */
vfxErr = NvVFX_CreateEffect(NVVFX_FX_GREEN_SCREEN, &filter->handle);
@@ -533,6 +547,9 @@ static obs_properties_t *nv_greenscreen_filter_properties(void *data)
obs_property_list_add_int(mode, TEXT_MODE_PERF, S_MODE_PERF);
obs_property_t *threshold = obs_properties_add_float_slider(
props, S_THRESHOLDFX, TEXT_MODE_THRESHOLD, 0, 1, 0.05);
obs_property_t *partial = obs_properties_add_int_slider(
props, S_PROCESSING, TEXT_PROCESSING, 1, 4, 1);
obs_property_set_long_description(partial, TEXT_PROCESSING_HINT);
unsigned int version = get_lib_version();
if (version < (MIN_VFX_SDK_VERSION)) {
obs_property_t *warning = obs_properties_add_text(
@@ -549,7 +566,9 @@ static void nv_greenscreen_filter_defaults(obs_data_t *settings)
obs_data_set_default_int(settings, S_MODE, S_MODE_QUALITY);
obs_data_set_default_double(settings, S_THRESHOLDFX,
S_THRESHOLDFX_DEFAULT);
obs_data_set_default_int(settings, S_PROCESSING, 1);
}
static struct obs_source_frame *
nv_greenscreen_filter_video(void *data, struct obs_source_frame *frame)
{
@@ -844,7 +863,14 @@ static void nv_greenscreen_filter_render(void *data, gs_effect_t *effect)
if (filter->initial_render && filter->images_allocated) {
bool draw = true;
if (!async || filter->got_new_frame) {
draw = process_texture_greenscreen(filter);
if (filter->processing_counter %
filter->processing_interval ==
0) {
draw = process_texture_greenscreen(filter);
filter->processing_counter = 1;
} else {
filter->processing_counter++;
}
filter->got_new_frame = false;
}