From bc6cc2078e8032b28b2ec0e04b05bf8116de8386 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Fri, 5 Jan 2024 15:59:41 +0000 Subject: [PATCH] build(linux) make vaapi optional without dlopen (#1979) Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> --- cmake/FindLibva.cmake | 70 +++++++ cmake/compile_definitions/linux.cmake | 25 ++- cmake/prep/options.cmake | 2 + docs/source/building/linux.rst | 7 +- src/platform/linux/kmsgrab.cpp | 8 + src/platform/linux/misc.cpp | 1 - src/platform/linux/vaapi.cpp | 266 +++----------------------- src/platform/linux/vaapi.h | 3 - src/platform/linux/wlgrab.cpp | 4 + src/platform/linux/x11grab.cpp | 2 + 10 files changed, 136 insertions(+), 252 deletions(-) create mode 100644 cmake/FindLibva.cmake diff --git a/cmake/FindLibva.cmake b/cmake/FindLibva.cmake new file mode 100644 index 00000000000..f8dfddc1496 --- /dev/null +++ b/cmake/FindLibva.cmake @@ -0,0 +1,70 @@ +# - Try to find Libva +# This module defines the following variables: +# +# * LIBVA_FOUND - The component was found +# * LIBVA_INCLUDE_DIRS - The component include directory +# * LIBVA_LIBRARIES - The component library Libva +# * LIBVA_DRM_LIBRARIES - The component library Libva DRM + +# Use pkg-config to get the directories and then use these values in the +# find_path() and find_library() calls +# cmake-format: on + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(_LIBVA libva) + pkg_check_modules(_LIBVA_DRM libva-drm) +endif() + +find_path( + LIBVA_INCLUDE_DIR + NAMES va/va.h va/va_drm.h + HINTS ${_LIBVA_INCLUDE_DIRS} + PATHS /usr/include /usr/local/include /opt/local/include) + +find_library( + LIBVA_LIB + NAMES ${_LIBVA_LIBRARIES} libva + HINTS ${_LIBVA_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib /opt/local/lib) + +find_library( + LIBVA_DRM_LIB + NAMES ${_LIBVA_DRM_LIBRARIES} libva-drm + HINTS ${_LIBVA_DRM_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib /opt/local/lib) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Libva REQUIRED_VARS LIBVA_INCLUDE_DIR LIBVA_LIB LIBVA_DRM_LIB) +mark_as_advanced(LIBVA_INCLUDE_DIR LIBVA_LIB LIBVA_DRM_LIB) + +if(LIBVA_FOUND) + set(LIBVA_INCLUDE_DIRS ${LIBVA_INCLUDE_DIR}) + set(LIBVA_LIBRARIES ${LIBVA_LIB}) + set(LIBVA_DRM_LIBRARIES ${LIBVA_DRM_LIB}) + + if(NOT TARGET Libva::va) + if(IS_ABSOLUTE "${LIBVA_LIBRARIES}") + add_library(Libva::va UNKNOWN IMPORTED) + set_target_properties(Libva::va PROPERTIES IMPORTED_LOCATION "${LIBVA_LIBRARIES}") + else() + add_library(Libva::va INTERFACE IMPORTED) + set_target_properties(Libva::va PROPERTIES IMPORTED_LIBNAME "${LIBVA_LIBRARIES}") + endif() + + set_target_properties(Libva::va PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBVA_INCLUDE_DIRS}") + endif() + + if(NOT TARGET Libva::drm) + if(IS_ABSOLUTE "${LIBVA_DRM_LIBRARIES}") + add_library(Libva::drm UNKNOWN IMPORTED) + set_target_properties(Libva::drm PROPERTIES IMPORTED_LOCATION "${LIBVA_DRM_LIBRARIES}") + else() + add_library(Libva::drm INTERFACE IMPORTED) + set_target_properties(Libva::drm PROPERTIES IMPORTED_LIBNAME "${LIBVA_DRM_LIBRARIES}") + endif() + + set_target_properties(Libva::drm PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBVA_INCLUDE_DIRS}") + endif() + +endif() diff --git a/cmake/compile_definitions/linux.cmake b/cmake/compile_definitions/linux.cmake index af35a09d19f..d4ebb597312 100644 --- a/cmake/compile_definitions/linux.cmake +++ b/cmake/compile_definitions/linux.cmake @@ -120,6 +120,21 @@ elseif(NOT LIBDRM_FOUND) message(WARNING "Missing libcap") endif() +# vaapi +if(${SUNSHINE_ENABLE_VAAPI}) + find_package(Libva) +else() + set(LIBVA_FOUND OFF) +endif() +if(LIBVA_FOUND) + add_compile_definitions(SUNSHINE_BUILD_VAAPI) + include_directories(SYSTEM ${LIBVA_INCLUDE_DIR}) + list(APPEND PLATFORM_LIBRARIES ${LIBVA_LIBRARIES} ${LIBVA_DRM_LIBRARIES}) + list(APPEND PLATFORM_TARGET_FILES + src/platform/linux/vaapi.h + src/platform/linux/vaapi.cpp) +endif() + # wayland if(${SUNSHINE_ENABLE_WAYLAND}) find_package(Wayland) @@ -167,8 +182,12 @@ if(X11_FOUND) src/platform/linux/x11grab.cpp) endif() -if(NOT ${CUDA_FOUND} AND NOT ${WAYLAND_FOUND} AND NOT ${X11_FOUND} AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})) - message(FATAL_ERROR "Couldn't find either x11, wayland, cuda or (libdrm and libcap)") +if(NOT ${CUDA_FOUND} + AND NOT ${WAYLAND_FOUND} + AND NOT ${X11_FOUND} + AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND}) + AND NOT ${LIBVA_FOUND}) + message(FATAL_ERROR "Couldn't find either cuda, wayland, x11, (libdrm and libcap), or libva") endif() # tray icon @@ -206,8 +225,6 @@ endif() list(APPEND PLATFORM_TARGET_FILES src/platform/linux/publish.cpp - src/platform/linux/vaapi.h - src/platform/linux/vaapi.cpp src/platform/linux/graphics.h src/platform/linux/graphics.cpp src/platform/linux/misc.h diff --git a/cmake/prep/options.cmake b/cmake/prep/options.cmake index 0198decb2b1..7a8d728ba47 100644 --- a/cmake/prep/options.cmake +++ b/cmake/prep/options.cmake @@ -26,6 +26,8 @@ elseif(UNIX) # Linux "Enable cuda specific code." ON) option(SUNSHINE_ENABLE_DRM "Enable KMS grab if available." ON) + option(SUNSHINE_ENABLE_VAAPI + "Enable building vaapi specific code." ON) option(SUNSHINE_ENABLE_WAYLAND "Enable building wayland specific code." ON) option(SUNSHINE_ENABLE_X11 diff --git a/docs/source/building/linux.rst b/docs/source/building/linux.rst index e3d51f6a57f..9982998ca2d 100644 --- a/docs/source/building/linux.rst +++ b/docs/source/building/linux.rst @@ -32,7 +32,7 @@ Install Requirements libopus-dev \ libpulse-dev \ libssl-dev \ - libva-dev \ + libva-dev \ # VA-API libvdpau-dev \ libwayland-dev \ # Wayland libx11-dev \ # X11 @@ -67,7 +67,7 @@ Install Requirements libdrm-devel \ libevdev-devel \ libnotify-devel \ - libva-devel \ + libva-devel \ # VA-API libvdpau-devel \ libX11-devel \ # X11 libxcb-devel \ # X11 @@ -115,7 +115,7 @@ Install Requirements libopus-dev \ libpulse-dev \ libssl-dev \ - libva-dev \ + libva-dev \ # VA-API libvdpau-dev \ libwayland-dev \ # Wayland libx11-dev \ # X11 @@ -165,6 +165,7 @@ Install Requirements libopus-dev \ libpulse-dev \ libssl-dev \ + libva-dev \ # VA-API libwayland-dev \ # Wayland libx11-dev \ # X11 libxcb-shm0-dev \ # X11 diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index 8b9780ae068..2273c528a63 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -793,9 +793,11 @@ namespace platf { std::unique_ptr make_avcodec_encode_device(pix_fmt_e pix_fmt) override { +#ifdef SUNSHINE_BUILD_VAAPI if (mem_type == mem_type_e::vaapi) { return va::make_avcodec_encode_device(width, height, false); } +#endif return std::make_unique(); } @@ -862,9 +864,11 @@ namespace platf { std::unique_ptr make_avcodec_encode_device(pix_fmt_e pix_fmt) override { +#ifdef SUNSHINE_BUILD_VAAPI if (mem_type == mem_type_e::vaapi) { return va::make_avcodec_encode_device(width, height, dup(card.render_fd.el), img_offset_x, img_offset_y, true); } +#endif BOOST_LOG(error) << "Unsupported pixel format for egl::display_vram_t: "sv << platf::from_pix_fmt(pix_fmt); return nullptr; @@ -977,7 +981,11 @@ namespace platf { return -1; } +#ifdef SUNSHINE_BUILD_VAAPI if (!va::validate(card.render_fd.el)) { +#else + if (true) { +#endif BOOST_LOG(warning) << "Monitor "sv << display_name << " doesn't support hardware encoding. Reverting back to GPU -> RAM -> GPU"sv; return -1; } diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index aee35b9e28a..a4fe1167219 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -724,7 +724,6 @@ namespace platf { init() { // These are allowed to fail. gbm::init(); - va::init(); window_system = window_system_e::NONE; #ifdef SUNSHINE_BUILD_WAYLAND diff --git a/src/platform/linux/vaapi.cpp b/src/platform/linux/vaapi.cpp index 085ca7bb9c5..8bd0ef16f79 100644 --- a/src/platform/linux/vaapi.cpp +++ b/src/platform/linux/vaapi.cpp @@ -10,6 +10,7 @@ extern "C" { #include #include +#include #if !VA_CHECK_VERSION(1, 9, 0) // vaSyncBuffer stub allows Sunshine built against libva <2.9.0 to link against ffmpeg on libva 2.9.0 or later VAStatus @@ -85,209 +86,7 @@ namespace va { } layers[4]; }; - /** - * @brief Defined profiles - */ - enum class profile_e { - // Profile ID used for video processing. - ProfileNone = -1, - MPEG2Simple = 0, - MPEG2Main = 1, - MPEG4Simple = 2, - MPEG4AdvancedSimple = 3, - MPEG4Main = 4, - H264Baseline = 5, - H264Main = 6, - H264High = 7, - VC1Simple = 8, - VC1Main = 9, - VC1Advanced = 10, - H263Baseline = 11, - JPEGBaseline = 12, - H264ConstrainedBaseline = 13, - VP8Version0_3 = 14, - H264MultiviewHigh = 15, - H264StereoHigh = 16, - HEVCMain = 17, - HEVCMain10 = 18, - VP9Profile0 = 19, - VP9Profile1 = 20, - VP9Profile2 = 21, - VP9Profile3 = 22, - HEVCMain12 = 23, - HEVCMain422_10 = 24, - HEVCMain422_12 = 25, - HEVCMain444 = 26, - HEVCMain444_10 = 27, - HEVCMain444_12 = 28, - HEVCSccMain = 29, - HEVCSccMain10 = 30, - HEVCSccMain444 = 31, - AV1Profile0 = 32, - AV1Profile1 = 33, - HEVCSccMain444_10 = 34, - - // Profile ID used for protected video playback. - Protected = 35 - }; - - enum class entry_e { - VLD = 1, - IZZ = 2, - IDCT = 3, - MoComp = 4, - Deblocking = 5, - EncSlice = 6, /** slice level encode */ - EncPicture = 7, /** picture encode, JPEG, etc */ - /** - * For an implementation that supports a low power/high performance variant - * for slice level encode, it can choose to expose the - * VAEntrypointEncSliceLP entrypoint. Certain encoding tools may not be - * available with this entrypoint (e.g. interlace, MBAFF) and the - * application can query the encoding configuration attributes to find - * out more details if this entrypoint is supported. - */ - EncSliceLP = 8, - VideoProc = 10, /**< Video pre/post-processing. */ - /** - * @brief FEI - * - * The purpose of FEI (Flexible Encoding Infrastructure) is to allow applications to - * have more controls and trade off quality for speed with their own IPs. - * The application can optionally provide input to ENC for extra encode control - * and get the output from ENC. Application can chose to modify the ENC - * output/PAK input during encoding, but the performance impact is significant. - * - * On top of the existing buffers for normal encode, there will be - * one extra input buffer (VAEncMiscParameterFEIFrameControl) and - * three extra output buffers (VAEncFEIMVBufferType, VAEncFEIMBModeBufferType - * and VAEncFEIDistortionBufferType) for FEI entry function. - * If separate PAK is set, two extra input buffers - * (VAEncFEIMVBufferType, VAEncFEIMBModeBufferType) are needed for PAK input. - */ - FEI = 11, - /** - * @brief Stats - * - * A pre-processing function for getting some statistics and motion vectors is added, - * and some extra controls for Encode pipeline are provided. The application can - * optionally call the statistics function to get motion vectors and statistics like - * variances, distortions before calling Encode function via this entry point. - * - * Checking whether Statistics is supported can be performed with vaQueryConfigEntrypoints(). - * If Statistics entry point is supported, then the list of returned entry-points will - * include #Stats. Supported pixel format, maximum resolution and statistics - * specific attributes can be obtained via normal attribute query. One input buffer - * (VAStatsStatisticsParameterBufferType) and one or two output buffers - * (VAStatsStatisticsBufferType, VAStatsStatisticsBottomFieldBufferType (for interlace only) - * and VAStatsMVBufferType) are needed for this entry point. - */ - Stats = 12, - /** - * @brief ProtectedTEEComm - * - * A function for communicating with TEE (Trusted Execution Environment). - */ - ProtectedTEEComm = 13, - /** - * @brief ProtectedContent - * - * A function for protected content to decrypt encrypted content. - */ - ProtectedContent = 14, - }; - - typedef VAStatus (*queryConfigEntrypoints_fn)(VADisplay dpy, profile_e profile, entry_e *entrypoint_list, int *num_entrypoints); - typedef int (*maxNumEntrypoints_fn)(VADisplay dpy); - typedef VADisplay (*getDisplayDRM_fn)(int fd); - typedef VAStatus (*terminate_fn)(VADisplay dpy); - typedef VAStatus (*initialize_fn)(VADisplay dpy, int *major_version, int *minor_version); - typedef const char *(*errorStr_fn)(VAStatus error_status); - typedef void (*VAMessageCallback)(void *user_context, const char *message); - typedef VAMessageCallback (*setErrorCallback_fn)(VADisplay dpy, VAMessageCallback callback, void *user_context); - typedef VAMessageCallback (*setInfoCallback_fn)(VADisplay dpy, VAMessageCallback callback, void *user_context); - typedef const char *(*queryVendorString_fn)(VADisplay dpy); - typedef VAStatus (*exportSurfaceHandle_fn)( - VADisplay dpy, VASurfaceID surface_id, - uint32_t mem_type, uint32_t flags, - void *descriptor); - - static maxNumEntrypoints_fn maxNumEntrypoints; - static queryConfigEntrypoints_fn queryConfigEntrypoints; - static getDisplayDRM_fn getDisplayDRM; - static terminate_fn terminate; - static initialize_fn initialize; - static errorStr_fn errorStr; - static setErrorCallback_fn setErrorCallback; - static setInfoCallback_fn setInfoCallback; - static queryVendorString_fn queryVendorString; - static exportSurfaceHandle_fn exportSurfaceHandle; - - using display_t = util::dyn_safe_ptr_v2; - - int - init_main_va() { - static void *handle { nullptr }; - static bool funcs_loaded = false; - - if (funcs_loaded) return 0; - - if (!handle) { - handle = dyn::handle({ "libva.so.2", "libva.so" }); - if (!handle) { - return -1; - } - } - - std::vector> funcs { - { (dyn::apiproc *) &maxNumEntrypoints, "vaMaxNumEntrypoints" }, - { (dyn::apiproc *) &queryConfigEntrypoints, "vaQueryConfigEntrypoints" }, - { (dyn::apiproc *) &terminate, "vaTerminate" }, - { (dyn::apiproc *) &initialize, "vaInitialize" }, - { (dyn::apiproc *) &errorStr, "vaErrorStr" }, - { (dyn::apiproc *) &setErrorCallback, "vaSetErrorCallback" }, - { (dyn::apiproc *) &setInfoCallback, "vaSetInfoCallback" }, - { (dyn::apiproc *) &queryVendorString, "vaQueryVendorString" }, - { (dyn::apiproc *) &exportSurfaceHandle, "vaExportSurfaceHandle" }, - }; - - if (dyn::load(handle, funcs)) { - return -1; - } - - funcs_loaded = true; - return 0; - } - - int - init() { - if (init_main_va()) { - return -1; - } - - static void *handle { nullptr }; - static bool funcs_loaded = false; - - if (funcs_loaded) return 0; - - if (!handle) { - handle = dyn::handle({ "libva-drm.so.2", "libva-drm.so" }); - if (!handle) { - return -1; - } - } - - std::vector> funcs { - { (dyn::apiproc *) &getDisplayDRM, "vaGetDisplayDRM" }, - }; - - if (dyn::load(handle, funcs)) { - return -1; - } - - funcs_loaded = true; - return 0; - } + using display_t = util::safe_ptr_v2; int vaapi_init_avcodec_hardware_input_buffer(platf::avcodec_encode_device_t *encode_device, AVBufferRef **hw_device_buf); @@ -298,9 +97,8 @@ namespace va { init(int in_width, int in_height, file_t &&render_device) { file = std::move(render_device); - if (!va::initialize || !gbm::create_device) { - if (!va::initialize) BOOST_LOG(warning) << "libva not initialized"sv; - if (!gbm::create_device) BOOST_LOG(warning) << "libgbm not initialized"sv; + if (!gbm::create_device) { + BOOST_LOG(warning) << "libgbm not initialized"sv; return -1; } @@ -346,14 +144,14 @@ namespace va { va::DRMPRIMESurfaceDescriptor prime; va::VASurfaceID surface = (std::uintptr_t) frame->data[3]; - auto status = va::exportSurfaceHandle( + auto status = vaExportSurfaceHandle( this->va_display, surface, va::SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, va::EXPORT_SURFACE_WRITE_ONLY | va::EXPORT_SURFACE_SEPARATE_LAYERS, &prime); if (status) { - BOOST_LOG(error) << "Couldn't export va surface handle: ["sv << (int) surface << "]: "sv << va::errorStr(status); + BOOST_LOG(error) << "Couldn't export va surface handle: ["sv << (int) surface << "]: "sv << vaErrorStr(status); return -1; } @@ -524,23 +322,13 @@ namespace va { auto hwctx = (AVVAAPIDeviceContext *) ctx->hwctx; auto priv = (VAAPIDevicePriv *) ctx->user_opaque; - terminate(hwctx->display); + vaTerminate(hwctx->display); close(priv->drm_fd); av_freep(&priv); } int vaapi_init_avcodec_hardware_input_buffer(platf::avcodec_encode_device_t *base, AVBufferRef **hw_device_buf) { - if (!va::initialize) { - BOOST_LOG(warning) << "libva not loaded"sv; - return -1; - } - - if (!va::getDisplayDRM) { - BOOST_LOG(warning) << "libva-drm not loaded"sv; - return -1; - } - auto va = (va::va_t *) base; auto fd = dup(va->file.el); @@ -552,7 +340,7 @@ namespace va { av_free(priv); }); - va::display_t display { va::getDisplayDRM(fd) }; + va::display_t display { vaGetDisplayDRM(fd) }; if (!display) { auto render_device = config::video.adapter_name.empty() ? "/dev/dri/renderD128" : config::video.adapter_name.c_str(); @@ -562,17 +350,17 @@ namespace va { va->va_display = display.get(); - va::setErrorCallback(display.get(), __log, &error); - va::setErrorCallback(display.get(), __log, &info); + vaSetErrorCallback(display.get(), __log, &error); + vaSetErrorCallback(display.get(), __log, &info); int major, minor; - auto status = va::initialize(display.get(), &major, &minor); + auto status = vaInitialize(display.get(), &major, &minor); if (status) { - BOOST_LOG(error) << "Couldn't initialize va display: "sv << va::errorStr(status); + BOOST_LOG(error) << "Couldn't initialize va display: "sv << vaErrorStr(status); return -1; } - BOOST_LOG(debug) << "vaapi vendor: "sv << va::queryVendorString(display.get()); + BOOST_LOG(debug) << "vaapi vendor: "sv << vaQueryVendorString(display.get()); *hw_device_buf = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI); auto ctx = (AVHWDeviceContext *) (*hw_device_buf)->data; @@ -596,20 +384,20 @@ namespace va { } static bool - query(display_t::pointer display, profile_e profile) { - std::vector entrypoints; - entrypoints.resize(maxNumEntrypoints(display)); + query(display_t::pointer display, VAProfile profile) { + std::vector entrypoints; + entrypoints.resize(vaMaxNumEntrypoints(display)); int count; - auto status = queryConfigEntrypoints(display, profile, entrypoints.data(), &count); + auto status = vaQueryConfigEntrypoints(display, profile, entrypoints.data(), &count); if (status) { - BOOST_LOG(error) << "Couldn't query entrypoints: "sv << va::errorStr(status); + BOOST_LOG(error) << "Couldn't query entrypoints: "sv << vaErrorStr(status); return false; } entrypoints.resize(count); for (auto entrypoint : entrypoints) { - if (entrypoint == entry_e::EncSlice || entrypoint == entry_e::EncSliceLP) { + if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncSliceLP) { return true; } } @@ -619,11 +407,7 @@ namespace va { bool validate(int fd) { - if (init()) { - return false; - } - - va::display_t display { va::getDisplayDRM(fd) }; + va::display_t display { vaGetDisplayDRM(fd) }; if (!display) { char string[1024]; @@ -636,21 +420,21 @@ namespace va { } int major, minor; - auto status = initialize(display.get(), &major, &minor); + auto status = vaInitialize(display.get(), &major, &minor); if (status) { - BOOST_LOG(error) << "Couldn't initialize va display: "sv << va::errorStr(status); + BOOST_LOG(error) << "Couldn't initialize va display: "sv << vaErrorStr(status); return false; } - if (!query(display.get(), profile_e::H264Main)) { + if (!query(display.get(), VAProfileH264Main)) { return false; } - if (video::active_hevc_mode > 1 && !query(display.get(), profile_e::HEVCMain)) { + if (video::active_hevc_mode > 1 && !query(display.get(), VAProfileHEVCMain)) { return false; } - if (video::active_hevc_mode > 2 && !query(display.get(), profile_e::HEVCMain10)) { + if (video::active_hevc_mode > 2 && !query(display.get(), VAProfileHEVCMain10)) { return false; } diff --git a/src/platform/linux/vaapi.h b/src/platform/linux/vaapi.h index 95760e55bd4..50d58b7d8d0 100644 --- a/src/platform/linux/vaapi.h +++ b/src/platform/linux/vaapi.h @@ -28,7 +28,4 @@ namespace va { // Ensure the render device pointed to by fd is capable of encoding h264 with the hevc_mode configured bool validate(int fd); - - int - init(); } // namespace va diff --git a/src/platform/linux/wlgrab.cpp b/src/platform/linux/wlgrab.cpp index 2162fe61a74..0e22cbe2248 100644 --- a/src/platform/linux/wlgrab.cpp +++ b/src/platform/linux/wlgrab.cpp @@ -211,9 +211,11 @@ namespace wl { std::unique_ptr make_avcodec_encode_device(platf::pix_fmt_e pix_fmt) override { +#ifdef SUNSHINE_BUILD_VAAPI if (mem_type == platf::mem_type_e::vaapi) { return va::make_avcodec_encode_device(width, height, false); } +#endif return std::make_unique(); } @@ -321,9 +323,11 @@ namespace wl { std::unique_ptr make_avcodec_encode_device(platf::pix_fmt_e pix_fmt) override { +#ifdef SUNSHINE_BUILD_VAAPI if (mem_type == platf::mem_type_e::vaapi) { return va::make_avcodec_encode_device(width, height, 0, 0, true); } +#endif return std::make_unique(); } diff --git a/src/platform/linux/x11grab.cpp b/src/platform/linux/x11grab.cpp index 6bd3018cf74..9022a10741e 100644 --- a/src/platform/linux/x11grab.cpp +++ b/src/platform/linux/x11grab.cpp @@ -555,9 +555,11 @@ namespace platf { std::unique_ptr make_avcodec_encode_device(pix_fmt_e pix_fmt) override { +#ifdef SUNSHINE_BUILD_VAAPI if (mem_type == mem_type_e::vaapi) { return va::make_avcodec_encode_device(width, height, false); } +#endif #ifdef SUNSHINE_BUILD_CUDA if (mem_type == mem_type_e::cuda) {