Browse Source

obs-filters: Warn if NVIDIA Video FX is oudated

This checks if the redistributable for NVIDIA Video FX is the latest.
If it is not, a warning is displayed in the Property window for the
filter.
Also removed the label RTX from the logs, just keeping NVIDIA Video FX.
The NVIDIA Video FX loader has been updated to sdk 7.1.0.
The new functions of the sdk are not loaded though.

Signed-off-by: pkv <[email protected]>
pkv 3 years ago
parent
commit
c30868f056

+ 1 - 0
plugins/obs-filters/data/locale/en-US.ini

@@ -124,6 +124,7 @@ Greenscreen.Mode="Mode"
 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."
 Upward.Compressor="Upward Compressor"
 3BandEq="3-Band Equalizer"
 3BandEq.low="Low"

+ 52 - 24
plugins/obs-filters/nvidia-greenscreen-filter.c

@@ -6,9 +6,9 @@
 #include "nvvfx-load.h"
 /* -------------------------------------------------------- */
 
-#define do_log(level, format, ...)                                             \
-	blog(level,                                                            \
-	     "[NVIDIA RTX AI Greenscreen (Background removal): '%s'] " format, \
+#define do_log(level, format, ...)                                         \
+	blog(level,                                                        \
+	     "[NVIDIA AI Greenscreen (Background removal): '%s'] " format, \
 	     obs_source_get_name(filter->context), ##__VA_ARGS__)
 
 #define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
@@ -33,8 +33,10 @@
 #define TEXT_MODE_QUALITY MT_("Greenscreen.Quality")
 #define TEXT_MODE_PERF MT_("Greenscreen.Performance")
 #define TEXT_MODE_THRESHOLD MT_("Greenscreen.Threshold")
+#define TEXT_DEPRECATION MT_("Greenscreen.Deprecation")
 
 bool nvvfx_loaded = false;
+bool nvvfx_new_sdk = false;
 struct nv_greenscreen_data {
 	obs_source_t *context;
 	bool images_allocated;
@@ -54,6 +56,7 @@ struct nv_greenscreen_data {
 	NvCVImage *A_dst_img;   // mask img on GPU
 	NvCVImage *dst_img;     // mask texture
 	NvCVImage *stage;       // planar stage img used for transfer to texture
+	unsigned int version;
 
 	/* alpha mask effect */
 	gs_effect_t *effect;
@@ -445,13 +448,15 @@ static void *nv_greenscreen_filter_create(obs_data_t *settings,
 		nv_greenscreen_filter_destroy(filter);
 		return NULL;
 	}
-	/* log sdk version */
-	unsigned int version;
-	if (NvVFX_GetVersion(&version) == NVCV_SUCCESS) {
-		uint8_t major = (version >> 24) & 0xff;
-		uint8_t minor = (version >> 16) & 0x00ff;
-		uint8_t build = (version >> 8) & 0x0000ff;
-		info("RTX VIDEO FX version: %i.%i.%i", major, minor, build);
+	/* check sdk version */
+	if (NvVFX_GetVersion(&filter->version) == NVCV_SUCCESS) {
+		uint8_t major = (filter->version >> 24) & 0xff;
+		uint8_t minor = (filter->version >> 16) & 0x00ff;
+		uint8_t build = (filter->version >> 8) & 0x0000ff;
+		uint8_t revision = (filter->version >> 0) & 0x000000ff;
+		// sanity check
+		nvvfx_new_sdk = filter->version >= (MIN_VFX_SDK_VERSION) &&
+				nvvfx_new_sdk;
 	}
 
 	/* 3. Load alpha mask effect. */
@@ -486,6 +491,7 @@ static void *nv_greenscreen_filter_create(obs_data_t *settings,
 
 static obs_properties_t *nv_greenscreen_filter_properties(void *data)
 {
+	struct nv_greenscreen_data *filter = (struct nv_greenscreen_data *)data;
 	obs_properties_t *props = obs_properties_create();
 	obs_property_t *mode = obs_properties_add_list(props, S_MODE, TEXT_MODE,
 						       OBS_COMBO_TYPE_LIST,
@@ -494,8 +500,14 @@ 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);
+	unsigned int version = get_lib_version();
+	if (version < (MIN_VFX_SDK_VERSION)) {
+		obs_property_t *warning = obs_properties_add_text(
+			props, "deprecation", NULL, OBS_TEXT_INFO);
+		obs_property_text_set_info_type(warning, OBS_TEXT_INFO_WARNING);
+		obs_property_set_long_description(warning, TEXT_DEPRECATION);
+	}
 
-	UNUSED_PARAMETER(data);
 	return props;
 }
 
@@ -815,20 +827,33 @@ static void nv_greenscreen_filter_render(void *data, gs_effect_t *effect)
 
 bool load_nvvfx(void)
 {
+	bool old_sdk_loaded = false;
+	unsigned int version = get_lib_version();
+	uint8_t major = (version >> 24) & 0xff;
+	uint8_t minor = (version >> 16) & 0x00ff;
+	uint8_t build = (version >> 8) & 0x0000ff;
+	uint8_t revision = (version >> 0) & 0x000000ff;
+	blog(LOG_INFO,
+	     "[NVIDIA VIDEO FX]: NVIDIA VIDEO FX version: %i.%i.%i.%i", major,
+	     minor, build, revision);
+	if (version < (MIN_VFX_SDK_VERSION)) {
+		blog(LOG_INFO,
+		     "[NVIDIA VIDEO FX]: NVIDIA VIDEO Effects SDK is outdated; please update both audio & video SDK.");
+	}
 	if (!load_nv_vfx_libs()) {
 		blog(LOG_INFO,
-		     "[NVIDIA RTX VIDEO FX]: FX disabled, redistributable not found.");
+		     "[NVIDIA VIDEO FX]: FX disabled, redistributable not found or could not be loaded.");
 		return false;
 	}
 
-#define LOAD_SYM_FROM_LIB(sym, lib, dll)                            \
-	if (!(sym = (sym##_t)GetProcAddress(lib, #sym))) {          \
-		DWORD err = GetLastError();                         \
-		printf("[NVIDIA RTX VIDEO FX]: Couldn't load " #sym \
-		       " from " dll ": %lu (0x%lx)",                \
-		       err, err);                                   \
-		release_nv_vfx();                                   \
-		goto unload_everything;                             \
+#define LOAD_SYM_FROM_LIB(sym, lib, dll)                                     \
+	if (!(sym = (sym##_t)GetProcAddress(lib, #sym))) {                   \
+		DWORD err = GetLastError();                                  \
+		printf("[NVIDIA VIDEO FX]: Couldn't load " #sym " from " dll \
+		       ": %lu (0x%lx)",                                      \
+		       err, err);                                            \
+		release_nv_vfx();                                            \
+		goto unload_everything;                                      \
 	}
 
 #define LOAD_SYM(sym) LOAD_SYM_FROM_LIB(sym, nv_videofx, "NVVideoEffects.dll")
@@ -857,6 +882,7 @@ bool load_nvvfx(void)
 	LOAD_SYM(NvVFX_Load);
 	LOAD_SYM(NvVFX_CudaStreamCreate);
 	LOAD_SYM(NvVFX_CudaStreamDestroy);
+	old_sdk_loaded = true;
 #undef LOAD_SYM
 #define LOAD_SYM(sym) LOAD_SYM_FROM_LIB(sym, nv_cvimage, "NVCVImage.dll")
 	LOAD_SYM(NvCV_GetErrorStringFromCode);
@@ -900,20 +926,22 @@ bool load_nvvfx(void)
 	if (err != NVCV_SUCCESS) {
 		if (err == NVCV_ERR_UNSUPPORTEDGPU) {
 			blog(LOG_INFO,
-			     "[NVIDIA RTX VIDEO FX]: disabled, unsupported GPU");
+			     "[NVIDIA VIDEO FX]: disabled, unsupported GPU");
 		} else {
-			blog(LOG_ERROR,
-			     "[NVIDIA RTX VIDEO FX]: disabled, error %i", err);
+			blog(LOG_ERROR, "[NVIDIA VIDEO FX]: disabled, error %i",
+			     err);
 		}
 		goto unload_everything;
 	}
 	NvVFX_DestroyEffect(h);
 	nvvfx_loaded = true;
-	blog(LOG_INFO, "[NVIDIA RTX VIDEO FX]: enabled, redistributable found");
+	blog(LOG_INFO, "[NVIDIA VIDEO FX]: enabled, redistributable found");
 	return true;
 
 unload_everything:
 	nvvfx_loaded = false;
+	blog(LOG_INFO,
+	     "[NVIDIA VIDEO FX]: disabled, redistributable not found");
 	release_nv_vfx();
 	return false;
 }

+ 54 - 5
plugins/obs-filters/nvvfx-load.h

@@ -6,6 +6,7 @@
 #include <stdint.h>
 #include <util/platform.h>
 #include <dxgitype.h>
+#include <util/windows/win-version.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -38,7 +39,7 @@ extern "C" {
 #define CUDARTAPI
 
 #ifdef LIBNVVFX_ENABLED
-// allows for future loading of a second fx
+#define MIN_VFX_SDK_VERSION 0 << 24 | 7 << 16 | 1 << 8 | 0 << 0
 static HMODULE nv_videofx = NULL;
 static HMODULE nv_cvimage = NULL;
 static HMODULE nv_cudart = NULL;
@@ -139,8 +140,14 @@ typedef enum NvCV_Status {
 #define NVVFX_CUDA_STREAM "CudaStream" //!< The CUDA stream to use
 #define NVVFX_CUDA_GRAPH "CudaGraph"   //!< Enable CUDA graph to use
 #define NVVFX_INFO "Info"              //!< Get info about the effects
-#define NVVFX_SCALE "Scale"            //!< Scale factor
-#define NVVFX_STRENGTH "Strength"      //!< Strength for different filters
+#define NVVFX_MAX_INPUT_WIDTH \
+	"MaxInputWidth" //!< Maximum width of the input supported
+#define NVVFX_MAX_INPUT_HEIGHT \
+	"MaxInputHeight" //!< Maximum height of the input supported
+#define NVVFX_MAX_NUMBER_STREAMS \
+	"MaxNumberStreams"  //!< Maximum number of concurrent input streams
+#define NVVFX_SCALE "Scale" //!< Scale factor
+#define NVVFX_STRENGTH "Strength" //!< Strength for different filters
 #define NVVFX_STRENGTH_LEVELS "StrengthLevels" //!< Number of strength levels
 #define NVVFX_MODE "Mode"                      //!< Mode for different filters
 #define NVVFX_TEMPORAL "Temporal"    //!< Temporal mode: 0=image, 1=video
@@ -149,6 +156,8 @@ typedef enum NvCV_Status {
 #define NVVFX_MODEL_BATCH "ModelBatch"
 #define NVVFX_STATE "State"          //!< State variable
 #define NVVFX_STATE_SIZE "StateSize" //!< Number of bytes needed to store state
+#define NVVFX_STATE_COUNT \
+	"NumStateObjects" //!< Number of active state object handles
 
 //! The format of pixels in an image.
 typedef enum NvCVImage_PixelFormat {
@@ -324,6 +333,8 @@ typedef struct CUstream_st *CUstream;
 typedef const char *NvVFX_EffectSelector;
 typedef const char *NvVFX_ParameterSelector;
 typedef void *NvVFX_Handle;
+/* requires sdk version >= 0.7.0 */
+typedef void *NvVFX_StateObjectHandle;
 
 /* nvvfx functions */
 typedef NvCV_Status NvVFX_API (*NvVFX_GetVersion_t)(unsigned int *version);
@@ -346,6 +357,11 @@ typedef NvCV_Status
 				    unsigned long long val);
 typedef NvCV_Status NvVFX_API (*NvVFX_SetObject_t)(
 	NvVFX_Handle effect, NvVFX_ParameterSelector param_name, void *ptr);
+/* requires sdk version >= 0.7.0 */
+typedef NvCV_Status NvVFX_API (*NvVFX_SetStateObjectHandleArray_t)(
+	NvVFX_Handle effect, NvVFX_ParameterSelector param_name,
+	NvVFX_StateObjectHandle *handle);
+/* ----------------------------- */
 typedef NvCV_Status
 	NvVFX_API (*NvVFX_SetCudaStream_t)(NvVFX_Handle effect,
 					   NvVFX_ParameterSelector param_name,
@@ -387,6 +403,17 @@ typedef NvCV_Status NvVFX_API (*NvVFX_Load_t)(NvVFX_Handle effect);
 typedef NvCV_Status NvVFX_API (*NvVFX_CudaStreamCreate_t)(CUstream *stream);
 typedef NvCV_Status NvVFX_API (*NvVFX_CudaStreamDestroy_t)(CUstream stream);
 
+/* requires sdk version >= 0.7.0 */
+typedef NvCV_Status
+	NvVFX_API (*NvVFX_AllocateState_t)(NvVFX_Handle effect,
+					   NvVFX_StateObjectHandle *handle);
+typedef NvCV_Status
+	NvVFX_API (*NvVFX_DeallocateState_t)(NvVFX_Handle effect,
+					     NvVFX_StateObjectHandle handle);
+typedef NvCV_Status
+	NvVFX_API (*NvVFX_ResetState_t)(NvVFX_Handle effect,
+					NvVFX_StateObjectHandle handle);
+
 /* NvCVImage functions */
 typedef NvCV_Status NvCV_API (*NvCVImage_Init_t)(
 	NvCVImage *im, unsigned width, unsigned height, int pitch, void *pixels,
@@ -643,6 +670,12 @@ static NvVFX_Load_t NvVFX_Load = NULL;
 static NvVFX_CudaStreamCreate_t NvVFX_CudaStreamCreate = NULL;
 static NvVFX_CudaStreamDestroy_t NvVFX_CudaStreamDestroy = NULL;
 
+/* nvvfx sdk >= 0.7.0 */
+static NvVFX_SetStateObjectHandleArray_t NvVFX_SetStateObjectHandleArray = NULL;
+static NvVFX_AllocateState_t NvVFX_AllocateState = NULL;
+static NvVFX_DeallocateState_t NvVFX_DeallocateState = NULL;
+static NvVFX_ResetState_t NvVFX_ResetState = NULL;
+
 /*nvcvimage */
 static NvCVImage_Init_t NvCVImage_Init = NULL;
 static NvCVImage_InitView_t NvCVImage_InitView = NULL;
@@ -707,6 +740,10 @@ static inline void release_nv_vfx()
 	NvVFX_SetString = NULL;
 	NvVFX_SetU32 = NULL;
 	NvVFX_SetU64 = NULL;
+	NvVFX_SetStateObjectHandleArray = NULL;
+	NvVFX_AllocateState = NULL;
+	NvVFX_DeallocateState = NULL;
+	NvVFX_ResetState = NULL;
 	if (nv_videofx) {
 		FreeLibrary(nv_videofx);
 		nv_videofx = NULL;
@@ -761,8 +798,7 @@ static inline void nvvfx_get_sdk_path(char *buffer, const size_t len)
 
 		size_t max_len = sizeof(path) / sizeof(char);
 		snprintf(buffer, max_len,
-			 "%s\\NVIDIA Corporation\\NVIDIA Video Effects\\",
-			 path);
+			 "%s\\NVIDIA Corporation\\NVIDIA Video Effects", path);
 	}
 }
 
@@ -771,6 +807,7 @@ static inline bool load_nv_vfx_libs()
 	char fullPath[MAX_PATH];
 	nvvfx_get_sdk_path(fullPath, MAX_PATH);
 	SetDllDirectoryA(fullPath);
+
 	nv_videofx = LoadLibrary(L"NVVideoEffects.dll");
 	nv_cvimage = LoadLibrary(L"NVCVImage.dll");
 	nv_cudart = LoadLibrary(L"cudart64_110.dll");
@@ -778,6 +815,18 @@ static inline bool load_nv_vfx_libs()
 	return !!nv_videofx && !!nv_cvimage && !!nv_cudart;
 }
 
+static unsigned int get_lib_version(void)
+{
+	char path[MAX_PATH];
+	nvvfx_get_sdk_path(path, sizeof(path));
+
+	SetDllDirectoryA(path);
+	struct win_version_info nto_ver = {0};
+	get_dll_ver(L"NVVideoEffects.dll", &nto_ver);
+	unsigned int version = nto_ver.major << 24 | nto_ver.minor << 16 |
+			       nto_ver.build << 8 | nto_ver.revis << 0;
+	return version;
+}
 #endif
 
 #ifdef __cplusplus