From 0e1377f359065aba4d810112d7b10a77150d5064 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Mon, 10 Aug 2020 01:18:36 +0200 Subject: [PATCH] encoders/handlers/nvenc: Don't list encoders on unsupported systems Removes the NVENC entry on systems without an NVIDIA GPU by checking if the library for it can be loaded. If it can't be loaded, it's likely that the user does not have a system with NVENC capabilities - and guaranteed that they can't use the encoder as FFmpeg relies on these libraries. --- .../encoders/handlers/nvenc_h264_handler.cpp | 4 ++- .../encoders/handlers/nvenc_hevc_handler.cpp | 4 ++- source/encoders/handlers/nvenc_shared.cpp | 26 ++++++++++++++----- source/encoders/handlers/nvenc_shared.hpp | 4 ++- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/source/encoders/handlers/nvenc_h264_handler.cpp b/source/encoders/handlers/nvenc_h264_handler.cpp index 6cb8d50..9a91ab3 100644 --- a/source/encoders/handlers/nvenc_h264_handler.cpp +++ b/source/encoders/handlers/nvenc_h264_handler.cpp @@ -59,9 +59,11 @@ static std::map levels{ {level::L4_1, "4.1"}, {level::L4_2, "4.2"}, {level::L5_0, "5.0"}, {level::L5_1, "5.1"}, }; -void nvenc_h264_handler::adjust_info(ffmpeg_factory*, const AVCodec*, std::string&, std::string& name, std::string&) +void nvenc_h264_handler::adjust_info(ffmpeg_factory* fac, const AVCodec*, std::string&, std::string& name, std::string&) { name = "NVIDIA NVENC H.264/AVC (via FFmpeg)"; + if (!nvenc::is_available()) + fac->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; } void nvenc_h264_handler::get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool) diff --git a/source/encoders/handlers/nvenc_hevc_handler.cpp b/source/encoders/handlers/nvenc_hevc_handler.cpp index 07b25d9..491473c 100644 --- a/source/encoders/handlers/nvenc_hevc_handler.cpp +++ b/source/encoders/handlers/nvenc_hevc_handler.cpp @@ -59,9 +59,11 @@ static std::map levels{ {level::L6_0, "6.0"}, {level::L6_1, "6.1"}, {level::L6_2, "6.2"}, }; -void nvenc_hevc_handler::adjust_info(ffmpeg_factory*, const AVCodec*, std::string&, std::string& name, std::string&) +void nvenc_hevc_handler::adjust_info(ffmpeg_factory* fac, const AVCodec*, std::string&, std::string& name, std::string&) { name = "NVIDIA NVENC H.265/HEVC (via FFmpeg)"; + if (!nvenc::is_available()) + fac->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; } void nvenc_hevc_handler::get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool) diff --git a/source/encoders/handlers/nvenc_shared.cpp b/source/encoders/handlers/nvenc_shared.cpp index ae9e24c..493c603 100644 --- a/source/encoders/handlers/nvenc_shared.cpp +++ b/source/encoders/handlers/nvenc_shared.cpp @@ -20,15 +20,10 @@ // SOFTWARE. #include "nvenc_shared.hpp" -#include "strings.hpp" -#include -#include "../codecs/hevc.hpp" -#include "../encoder-ffmpeg.hpp" +#include "encoders/encoder-ffmpeg.hpp" #include "ffmpeg/tools.hpp" -#include "plugin.hpp" extern "C" { -#include #pragma warning(push) #pragma warning(disable : 4244) #include @@ -155,6 +150,25 @@ std::map nvenc::b_ref_mode_to_opt{ {nvenc::b_ref_mode::MIDDLE, "middle"}, }; +bool streamfx::encoder::ffmpeg::handler::nvenc::is_available() +{ +#if defined(D_PLATFORM_WINDOWS) +#if defined(D_PLATFORM_64BIT) + std::filesystem::path lib_name = "nvEncodeAPI64.dll"; +#else + std::filesystem::path lib_name = "nvEncodeAPI.dll"; +#endif +#else + std::filesystem::path lib_name = "libnvidia-encode.so.1"; +#endif + try { + util::library::load(lib_name); + return true; + } catch (...) { + return false; + } +} + void nvenc::override_update(ffmpeg_instance* instance, obs_data_t*) { AVCodecContext* context = const_cast(instance->get_avcodeccontext()); diff --git a/source/encoders/handlers/nvenc_shared.hpp b/source/encoders/handlers/nvenc_shared.hpp index c38a472..cea4d38 100644 --- a/source/encoders/handlers/nvenc_shared.hpp +++ b/source/encoders/handlers/nvenc_shared.hpp @@ -20,7 +20,7 @@ // SOFTWARE. #pragma once -#include +#include "common.hpp" #include "handler.hpp" extern "C" { @@ -90,6 +90,8 @@ namespace streamfx::encoder::ffmpeg::handler::nvenc { extern std::map b_ref_mode_to_opt; + bool is_available(); + void override_update(ffmpeg_instance* instance, obs_data_t* settings); void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);