From 06e3fbcf73209a009748119bf3477633c95ef36f Mon Sep 17 00:00:00 2001 From: pkv Date: Sat, 29 Aug 2026 21:33:52 +0200 Subject: [PATCH] nv-filters: Enable Video FX SDK 1.3.0 for ARM This updates the video FX SDK to 1.3.0, which enables arm64 support. Backwards compatibility with SDK 0.7.6 has been kept. Signed-off-by: pkv --- plugins/nv-filters/data/locale/en-US.ini | 2 +- plugins/nv-filters/nv_sdk_versions.h | 2 + plugins/nv-filters/nvidia-videofx-filter.c | 47 ++---------- plugins/nv-filters/nvvfx-load.h | 86 ++++++++++------------ 4 files changed, 46 insertions(+), 91 deletions(-) diff --git a/plugins/nv-filters/data/locale/en-US.ini b/plugins/nv-filters/data/locale/en-US.ini index 520dd9239..ff23e23b8 100644 --- a/plugins/nv-filters/data/locale/en-US.ini +++ b/plugins/nv-filters/data/locale/en-US.ini @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Performance="Performance (lower GPU usage, good quality Nvvfx.Method.Greenscreen.Quality.Chair="Quality (higher GPU usage, better quality) + Chair removal" Nvvfx.Method.Greenscreen.Performance.Chair="Performance (lower GPU usage, good quality) + Chair removal" Nvvfx.Method.Greenscreen.Threshold="Threshold" -Nvvfx.OutdatedSDK="WARNING: Please upgrade both NVIDIA Video & Audio SDK. Your current version of Video SDK is outdated." +Nvvfx.OutdatedSDK="WARNING: Please upgrade both NVIDIA Video & Audio SDK. Your current version of Video SDK is outdated. This can break Audio FX, Video FX, or both." Nvvfx.Method.Greenscreen.Processing="Mask refresh frequency in frames" Nvvfx.Method.Greenscreen.Processing.Hint="This alleviates GPU load by generating a mask every N frames only (2 on default)." Nvvfx.Method.BlurFilter="NVIDIA Blur Filter" diff --git a/plugins/nv-filters/nv_sdk_versions.h b/plugins/nv-filters/nv_sdk_versions.h index 3ab27f404..53911530a 100644 --- a/plugins/nv-filters/nv_sdk_versions.h +++ b/plugins/nv-filters/nv_sdk_versions.h @@ -1,4 +1,6 @@ #define MIN_VFX_SDK_VERSION (0 << 24 | 7 << 16 | 6 << 8 | 0 << 0) +#define MIN_VFX_LOGGER_VERSION (0 << 24 | 7 << 16 | 6 << 8 | 0 << 0) +#define MIN_ARM_VFX_SDK_VERSION (1 << 24 | 3 << 16 | 0 << 8 | 0 << 0) #define MIN_AFX_SDK_VERSION (1 << 24 | 6 << 16 | 1 << 8 | 2 << 0) #define MIN_AFX_LOGGER_VERSION (1 << 24 | 6 << 16 | 1 << 8 | 2 << 0) // also gates VAD feature diff --git a/plugins/nv-filters/nvidia-videofx-filter.c b/plugins/nv-filters/nvidia-videofx-filter.c index 15341927f..24289c656 100644 --- a/plugins/nv-filters/nvidia-videofx-filter.c +++ b/plugins/nv-filters/nvidia-videofx-filter.c @@ -48,7 +48,6 @@ enum nvvfx_fx_id { S_FX_AIGS, S_FX_BLUR, S_FX_BG_BLUR }; bool nvvfx_loaded = false; -bool nvvfx_new_sdk = false; /* clang-format off */ struct nvvfx_data { @@ -317,7 +316,6 @@ static void *nvvfx_filter_create(obs_data_t *settings, obs_source_t *context, en uint8_t minor = (filter->version >> 16) & 0x00ff; uint8_t build = (filter->version >> 8) & 0x0000ff; uint8_t revision = (filter->version >> 0) & 0x000000ff; - nvvfx_new_sdk = filter->version >= MIN_VFX_SDK_VERSION && nvvfx_new_sdk; } #endif /* 1. Create FX */ @@ -343,7 +341,7 @@ static void *nvvfx_filter_create(obs_data_t *settings, obs_source_t *context, en obs_leave_graphics(); /* 4. Allocate state for the AIGS & background blur */ - if (nvvfx_new_sdk && id != S_FX_BLUR) { + if (get_lib_version() >= MIN_VFX_LOGGER_VERSION && id != S_FX_BLUR) { vfxErr = NvVFX_AllocateState(filter->handle, &filter->stateObjectHandle); if (NVCV_SUCCESS != vfxErr) return log_nverror_destroy(filter, vfxErr); @@ -360,7 +358,7 @@ static void *nvvfx_filter_create(obs_data_t *settings, obs_source_t *context, en nvvfx_filter_update(filter, settings); /* Setup NVIDIA logger */ - if (nvvfx_new_sdk) + if (get_lib_version() >= MIN_VFX_LOGGER_VERSION) vfxErr = NvVFX_ConfigureLogger(NVCV_LOG_ERROR, NULL, &nvvfx_logger_callback, filter); return filter; @@ -1087,7 +1085,6 @@ static void nvvfx_filter_defaults(obs_data_t *settings) bool load_nvidia_vfx(void) { - bool old_sdk_loaded = false; unsigned int version = get_lib_version(); uint8_t major = (version >> 24) & 0xff; uint8_t minor = (version >> 16) & 0x00ff; @@ -1101,7 +1098,7 @@ bool load_nvidia_vfx(void) "[NVIDIA VIDEO FX]: NVIDIA VIDEO Effects SDK is outdated. Please update both audio & video SDK."); } } - if (!load_nv_vfx_libs()) { + if (!load_nv_vfx_libs(version)) { blog(LOG_INFO, "[NVIDIA VIDEO FX]: FX disabled, redistributable not found or could not be loaded."); return false; } @@ -1110,19 +1107,9 @@ bool load_nvidia_vfx(void) 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_FROM_LIB2(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); \ - nvvfx_new_sdk = false; \ - } else { \ - nvvfx_new_sdk = true; \ - } - #define LOAD_SYM(sym) LOAD_SYM_FROM_LIB(sym, nv_videofx, "NVVideoEffects.dll") LOAD_SYM(NvVFX_GetVersion); LOAD_SYM(NvVFX_CreateEffect); @@ -1153,42 +1140,20 @@ bool load_nvidia_vfx(void) LOAD_SYM(NvVFX_AllocateState); LOAD_SYM(NvVFX_DeallocateState); LOAD_SYM(NvVFX_ResetState); - old_sdk_loaded = true; + LOAD_SYM(NvVFX_ConfigureLogger); #undef LOAD_SYM #define LOAD_SYM(sym) LOAD_SYM_FROM_LIB(sym, nv_cvimage, "NVCVImage.dll") LOAD_SYM(NvCV_GetErrorStringFromCode); LOAD_SYM(NvCVImage_Init); - LOAD_SYM(NvCVImage_InitView); LOAD_SYM(NvCVImage_Alloc); LOAD_SYM(NvCVImage_Realloc); - LOAD_SYM(NvCVImage_Dealloc); LOAD_SYM(NvCVImage_Create); LOAD_SYM(NvCVImage_Destroy); - LOAD_SYM(NvCVImage_ComponentOffsets); LOAD_SYM(NvCVImage_Transfer); - LOAD_SYM(NvCVImage_TransferRect); - LOAD_SYM(NvCVImage_TransferFromYUV); - LOAD_SYM(NvCVImage_TransferToYUV); LOAD_SYM(NvCVImage_MapResource); LOAD_SYM(NvCVImage_UnmapResource); - LOAD_SYM(NvCVImage_Composite); - LOAD_SYM(NvCVImage_CompositeRect); - LOAD_SYM(NvCVImage_CompositeOverConstant); - LOAD_SYM(NvCVImage_FlipY); - LOAD_SYM(NvCVImage_GetYUVPointers); LOAD_SYM(NvCVImage_InitFromD3D11Texture); - LOAD_SYM(NvCVImage_ToD3DFormat); - LOAD_SYM(NvCVImage_FromD3DFormat); - LOAD_SYM(NvCVImage_ToD3DColorSpace); - LOAD_SYM(NvCVImage_FromD3DColorSpace); -#undef LOAD_SYM - -#define LOAD_SYM(sym) LOAD_SYM_FROM_LIB2(sym, nv_videofx, "NVVideoEffects.dll") - LOAD_SYM(NvVFX_ConfigureLogger); - if (!nvvfx_new_sdk) { - blog(LOG_INFO, "[NVIDIA VIDEO FX]: SDK loaded but old redistributable detected. Please upgrade."); - } #undef LOAD_SYM int err; @@ -1212,13 +1177,13 @@ bool load_nvidia_vfx(void) unload_everything: nvvfx_loaded = false; blog(LOG_INFO, "[NVIDIA VIDEO FX]: disabled, redistributable not found"); - release_nv_vfx(); + release_vfx_lib(); return false; } void unload_nvidia_vfx(void) { - release_nv_vfx(); + release_vfx_lib(); } struct obs_source_info nvidia_greenscreen_filter_info = { diff --git a/plugins/nv-filters/nvvfx-load.h b/plugins/nv-filters/nvvfx-load.h index e27ad1e62..4191057a7 100644 --- a/plugins/nv-filters/nvvfx-load.h +++ b/plugins/nv-filters/nvvfx-load.h @@ -38,12 +38,13 @@ extern "C" { #endif //NvCV_API #define CUDARTAPI - #ifdef LIBNVVFX_ENABLED static HMODULE nv_videofx = NULL; static HMODULE nv_cvimage = NULL; static HMODULE nv_cudart = NULL; static HMODULE nv_cuda = NULL; +static HMODULE nv_greenscreen = NULL; +static HMODULE nv_blur = NULL; //! Status codes returned from APIs. typedef enum NvCV_Status { @@ -569,26 +570,12 @@ static NvCVImage_Init_t NvCVImage_Init = NULL; static NvCVImage_InitView_t NvCVImage_InitView = NULL; static NvCVImage_Alloc_t NvCVImage_Alloc = NULL; static NvCVImage_Realloc_t NvCVImage_Realloc = NULL; -static NvCVImage_Dealloc_t NvCVImage_Dealloc = NULL; static NvCVImage_Create_t NvCVImage_Create = NULL; static NvCVImage_Destroy_t NvCVImage_Destroy = NULL; -static NvCVImage_ComponentOffsets_t NvCVImage_ComponentOffsets = NULL; static NvCVImage_Transfer_t NvCVImage_Transfer = NULL; -static NvCVImage_TransferRect_t NvCVImage_TransferRect = NULL; -static NvCVImage_TransferFromYUV_t NvCVImage_TransferFromYUV = NULL; -static NvCVImage_TransferToYUV_t NvCVImage_TransferToYUV = NULL; static NvCVImage_MapResource_t NvCVImage_MapResource = NULL; static NvCVImage_UnmapResource_t NvCVImage_UnmapResource = NULL; -static NvCVImage_Composite_t NvCVImage_Composite = NULL; -static NvCVImage_CompositeRect_t NvCVImage_CompositeRect = NULL; -static NvCVImage_CompositeOverConstant_t NvCVImage_CompositeOverConstant = NULL; -static NvCVImage_FlipY_t NvCVImage_FlipY = NULL; -static NvCVImage_GetYUVPointers_t NvCVImage_GetYUVPointers = NULL; /* nvcvimage D3D*/ -static NvCVImage_ToD3DFormat_t NvCVImage_ToD3DFormat = NULL; -static NvCVImage_FromD3DFormat_t NvCVImage_FromD3DFormat = NULL; -static NvCVImage_ToD3DColorSpace_t NvCVImage_ToD3DColorSpace = NULL; -static NvCVImage_FromD3DColorSpace_t NvCVImage_FromD3DColorSpace = NULL; static NvCVImage_InitFromD3D11Texture_t NvCVImage_InitFromD3D11Texture = NULL; /* error codes */ static NvCV_GetErrorStringFromCode_t NvCV_GetErrorStringFromCode = NULL; @@ -599,8 +586,7 @@ static cudaStreamSynchronize_t cudaStreamSynchronize = NULL; static cudaFree_t cudaFree = NULL; static cudaMemcpy_t cudaMemcpy = NULL; static cudaMemsetAsync_t cudaMemsetAsync = NULL; - -static inline void release_nv_vfx() +static inline void release_vfx_lib(void) { NvVFX_CreateEffect = NULL; NvVFX_CudaStreamCreate = NULL; @@ -638,33 +624,27 @@ static inline void release_nv_vfx() nv_videofx = NULL; } NvCVImage_Alloc = NULL; - NvCVImage_ComponentOffsets = NULL; - NvCVImage_Composite = NULL; - NvCVImage_CompositeRect = NULL; - NvCVImage_CompositeOverConstant = NULL; NvCVImage_Create = NULL; - NvCVImage_Dealloc = NULL; NvCVImage_Destroy = NULL; NvCVImage_Init = NULL; NvCVImage_InitView = NULL; NvCVImage_Realloc = NULL; NvCVImage_Transfer = NULL; - NvCVImage_TransferRect = NULL; - NvCVImage_TransferFromYUV = NULL; - NvCVImage_TransferToYUV = NULL; NvCVImage_MapResource = NULL; NvCVImage_UnmapResource = NULL; NvCVImage_InitFromD3D11Texture = NULL; - NvCVImage_FlipY = NULL; - NvCVImage_GetYUVPointers = NULL; - NvCVImage_ToD3DFormat = NULL; - NvCVImage_FromD3DFormat = NULL; - NvCVImage_ToD3DColorSpace = NULL; - NvCVImage_FromD3DColorSpace = NULL; if (nv_cvimage) { FreeLibrary(nv_cvimage); nv_cvimage = NULL; } + if (nv_greenscreen) { + FreeLibrary(nv_greenscreen); + nv_greenscreen = NULL; + } + if (nv_blur) { + FreeLibrary(nv_blur); + nv_blur = NULL; + } } static inline bool nvvfx_get_sdk_path(char *buffer, const size_t len) @@ -688,31 +668,39 @@ static inline bool nvvfx_get_sdk_path(char *buffer, const size_t len) return true; } -static inline bool load_nv_vfx_libs() +static inline bool load_vfx_module(HMODULE *module, const char *sdk_path, const char *filename) { - char sdkPath[MAX_PATH]; - char effectsPath[MAX_PATH]; - char imagePath[MAX_PATH]; + char path[MAX_PATH]; - if (!nvvfx_get_sdk_path(sdkPath, MAX_PATH)) { + if (_snprintf_s(path, _countof(path), _TRUNCATE, "%s\\%s", sdk_path, filename) == -1) + return false; + + *module = LoadLibraryExA(path, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + return *module != NULL; +} + +static inline bool load_nv_vfx_libs(unsigned int version) +{ + char sdk_path[MAX_PATH]; + + if (!nvvfx_get_sdk_path(sdk_path, MAX_PATH)) + return false; + + if (!load_vfx_module(&nv_cvimage, sdk_path, "NVCVImage.dll") || + !load_vfx_module(&nv_videofx, sdk_path, "NVVideoEffects.dll")) { + release_vfx_lib(); return false; } - if (_snprintf_s(effectsPath, _countof(effectsPath), _TRUNCATE, "%s\\NVVideoEffects.dll", sdkPath) == -1) { + if (version < MIN_ARM_VFX_SDK_VERSION) + return true; + + if (!load_vfx_module(&nv_greenscreen, sdk_path, "nvVFXGreenScreen.dll") || + !load_vfx_module(&nv_blur, sdk_path, "nvVFXBackgroundBlur.dll")) { + release_vfx_lib(); return false; } - - if (_snprintf_s(imagePath, _countof(imagePath), _TRUNCATE, "%s\\NVCVImage.dll", sdkPath) == -1) { - return false; - } - - nv_videofx = - LoadLibraryExA(effectsPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - - nv_cvimage = - LoadLibraryExA(imagePath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - - return !!nv_videofx && !!nv_cvimage; + return true; } static unsigned int get_lib_version(void)