diff --git a/plugins/obs-filters/data/locale/en-US.ini b/plugins/obs-filters/data/locale/en-US.ini index 6a630fc2f..99fb894ca 100644 --- a/plugins/obs-filters/data/locale/en-US.ini +++ b/plugins/obs-filters/data/locale/en-US.ini @@ -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" diff --git a/plugins/obs-filters/nvidia-greenscreen-filter.c b/plugins/obs-filters/nvidia-greenscreen-filter.c index ae8fb6fee..3ca335651 100644 --- a/plugins/obs-filters/nvidia-greenscreen-filter.c +++ b/plugins/obs-filters/nvidia-greenscreen-filter.c @@ -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; }