build(linux) make vaapi optional without dlopen (#1979)

Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
This commit is contained in:
James Le Cuirot 2024-01-05 15:59:41 +00:00 committed by GitHub
commit bc6cc2078e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 136 additions and 252 deletions

70
cmake/FindLibva.cmake Normal file
View file

@ -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()

View file

@ -120,6 +120,21 @@ elseif(NOT LIBDRM_FOUND)
message(WARNING "Missing libcap") message(WARNING "Missing libcap")
endif() 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 # wayland
if(${SUNSHINE_ENABLE_WAYLAND}) if(${SUNSHINE_ENABLE_WAYLAND})
find_package(Wayland) find_package(Wayland)
@ -167,8 +182,12 @@ if(X11_FOUND)
src/platform/linux/x11grab.cpp) src/platform/linux/x11grab.cpp)
endif() endif()
if(NOT ${CUDA_FOUND} AND NOT ${WAYLAND_FOUND} AND NOT ${X11_FOUND} AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})) if(NOT ${CUDA_FOUND}
message(FATAL_ERROR "Couldn't find either x11, wayland, cuda or (libdrm and libcap)") 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() endif()
# tray icon # tray icon
@ -206,8 +225,6 @@ endif()
list(APPEND PLATFORM_TARGET_FILES list(APPEND PLATFORM_TARGET_FILES
src/platform/linux/publish.cpp src/platform/linux/publish.cpp
src/platform/linux/vaapi.h
src/platform/linux/vaapi.cpp
src/platform/linux/graphics.h src/platform/linux/graphics.h
src/platform/linux/graphics.cpp src/platform/linux/graphics.cpp
src/platform/linux/misc.h src/platform/linux/misc.h

View file

@ -26,6 +26,8 @@ elseif(UNIX) # Linux
"Enable cuda specific code." ON) "Enable cuda specific code." ON)
option(SUNSHINE_ENABLE_DRM option(SUNSHINE_ENABLE_DRM
"Enable KMS grab if available." ON) "Enable KMS grab if available." ON)
option(SUNSHINE_ENABLE_VAAPI
"Enable building vaapi specific code." ON)
option(SUNSHINE_ENABLE_WAYLAND option(SUNSHINE_ENABLE_WAYLAND
"Enable building wayland specific code." ON) "Enable building wayland specific code." ON)
option(SUNSHINE_ENABLE_X11 option(SUNSHINE_ENABLE_X11

View file

@ -32,7 +32,7 @@ Install Requirements
libopus-dev \ libopus-dev \
libpulse-dev \ libpulse-dev \
libssl-dev \ libssl-dev \
libva-dev \ libva-dev \ # VA-API
libvdpau-dev \ libvdpau-dev \
libwayland-dev \ # Wayland libwayland-dev \ # Wayland
libx11-dev \ # X11 libx11-dev \ # X11
@ -67,7 +67,7 @@ Install Requirements
libdrm-devel \ libdrm-devel \
libevdev-devel \ libevdev-devel \
libnotify-devel \ libnotify-devel \
libva-devel \ libva-devel \ # VA-API
libvdpau-devel \ libvdpau-devel \
libX11-devel \ # X11 libX11-devel \ # X11
libxcb-devel \ # X11 libxcb-devel \ # X11
@ -115,7 +115,7 @@ Install Requirements
libopus-dev \ libopus-dev \
libpulse-dev \ libpulse-dev \
libssl-dev \ libssl-dev \
libva-dev \ libva-dev \ # VA-API
libvdpau-dev \ libvdpau-dev \
libwayland-dev \ # Wayland libwayland-dev \ # Wayland
libx11-dev \ # X11 libx11-dev \ # X11
@ -165,6 +165,7 @@ Install Requirements
libopus-dev \ libopus-dev \
libpulse-dev \ libpulse-dev \
libssl-dev \ libssl-dev \
libva-dev \ # VA-API
libwayland-dev \ # Wayland libwayland-dev \ # Wayland
libx11-dev \ # X11 libx11-dev \ # X11
libxcb-shm0-dev \ # X11 libxcb-shm0-dev \ # X11

View file

@ -793,9 +793,11 @@ namespace platf {
std::unique_ptr<avcodec_encode_device_t> std::unique_ptr<avcodec_encode_device_t>
make_avcodec_encode_device(pix_fmt_e pix_fmt) override { make_avcodec_encode_device(pix_fmt_e pix_fmt) override {
#ifdef SUNSHINE_BUILD_VAAPI
if (mem_type == mem_type_e::vaapi) { if (mem_type == mem_type_e::vaapi) {
return va::make_avcodec_encode_device(width, height, false); return va::make_avcodec_encode_device(width, height, false);
} }
#endif
return std::make_unique<avcodec_encode_device_t>(); return std::make_unique<avcodec_encode_device_t>();
} }
@ -862,9 +864,11 @@ namespace platf {
std::unique_ptr<avcodec_encode_device_t> std::unique_ptr<avcodec_encode_device_t>
make_avcodec_encode_device(pix_fmt_e pix_fmt) override { make_avcodec_encode_device(pix_fmt_e pix_fmt) override {
#ifdef SUNSHINE_BUILD_VAAPI
if (mem_type == mem_type_e::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); 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); BOOST_LOG(error) << "Unsupported pixel format for egl::display_vram_t: "sv << platf::from_pix_fmt(pix_fmt);
return nullptr; return nullptr;
@ -977,7 +981,11 @@ namespace platf {
return -1; return -1;
} }
#ifdef SUNSHINE_BUILD_VAAPI
if (!va::validate(card.render_fd.el)) { 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; BOOST_LOG(warning) << "Monitor "sv << display_name << " doesn't support hardware encoding. Reverting back to GPU -> RAM -> GPU"sv;
return -1; return -1;
} }

View file

@ -724,7 +724,6 @@ namespace platf {
init() { init() {
// These are allowed to fail. // These are allowed to fail.
gbm::init(); gbm::init();
va::init();
window_system = window_system_e::NONE; window_system = window_system_e::NONE;
#ifdef SUNSHINE_BUILD_WAYLAND #ifdef SUNSHINE_BUILD_WAYLAND

View file

@ -10,6 +10,7 @@
extern "C" { extern "C" {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <va/va.h> #include <va/va.h>
#include <va/va_drm.h>
#if !VA_CHECK_VERSION(1, 9, 0) #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 // vaSyncBuffer stub allows Sunshine built against libva <2.9.0 to link against ffmpeg on libva 2.9.0 or later
VAStatus VAStatus
@ -85,209 +86,7 @@ namespace va {
} layers[4]; } layers[4];
}; };
/** using display_t = util::safe_ptr_v2<void, VAStatus, vaTerminate>;
* @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<void, VAStatus, &terminate>;
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<std::tuple<dyn::apiproc *, const char *>> 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<std::tuple<dyn::apiproc *, const char *>> funcs {
{ (dyn::apiproc *) &getDisplayDRM, "vaGetDisplayDRM" },
};
if (dyn::load(handle, funcs)) {
return -1;
}
funcs_loaded = true;
return 0;
}
int int
vaapi_init_avcodec_hardware_input_buffer(platf::avcodec_encode_device_t *encode_device, AVBufferRef **hw_device_buf); 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) { init(int in_width, int in_height, file_t &&render_device) {
file = std::move(render_device); file = std::move(render_device);
if (!va::initialize || !gbm::create_device) { if (!gbm::create_device) {
if (!va::initialize) BOOST_LOG(warning) << "libva not initialized"sv; BOOST_LOG(warning) << "libgbm not initialized"sv;
if (!gbm::create_device) BOOST_LOG(warning) << "libgbm not initialized"sv;
return -1; return -1;
} }
@ -346,14 +144,14 @@ namespace va {
va::DRMPRIMESurfaceDescriptor prime; va::DRMPRIMESurfaceDescriptor prime;
va::VASurfaceID surface = (std::uintptr_t) frame->data[3]; va::VASurfaceID surface = (std::uintptr_t) frame->data[3];
auto status = va::exportSurfaceHandle( auto status = vaExportSurfaceHandle(
this->va_display, this->va_display,
surface, surface,
va::SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, va::SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
va::EXPORT_SURFACE_WRITE_ONLY | va::EXPORT_SURFACE_SEPARATE_LAYERS, va::EXPORT_SURFACE_WRITE_ONLY | va::EXPORT_SURFACE_SEPARATE_LAYERS,
&prime); &prime);
if (status) { 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; return -1;
} }
@ -524,23 +322,13 @@ namespace va {
auto hwctx = (AVVAAPIDeviceContext *) ctx->hwctx; auto hwctx = (AVVAAPIDeviceContext *) ctx->hwctx;
auto priv = (VAAPIDevicePriv *) ctx->user_opaque; auto priv = (VAAPIDevicePriv *) ctx->user_opaque;
terminate(hwctx->display); vaTerminate(hwctx->display);
close(priv->drm_fd); close(priv->drm_fd);
av_freep(&priv); av_freep(&priv);
} }
int int
vaapi_init_avcodec_hardware_input_buffer(platf::avcodec_encode_device_t *base, AVBufferRef **hw_device_buf) { 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 va = (va::va_t *) base;
auto fd = dup(va->file.el); auto fd = dup(va->file.el);
@ -552,7 +340,7 @@ namespace va {
av_free(priv); av_free(priv);
}); });
va::display_t display { va::getDisplayDRM(fd) }; va::display_t display { vaGetDisplayDRM(fd) };
if (!display) { if (!display) {
auto render_device = config::video.adapter_name.empty() ? "/dev/dri/renderD128" : config::video.adapter_name.c_str(); 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->va_display = display.get();
va::setErrorCallback(display.get(), __log, &error); vaSetErrorCallback(display.get(), __log, &error);
va::setErrorCallback(display.get(), __log, &info); vaSetErrorCallback(display.get(), __log, &info);
int major, minor; int major, minor;
auto status = va::initialize(display.get(), &major, &minor); auto status = vaInitialize(display.get(), &major, &minor);
if (status) { 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; 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); *hw_device_buf = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI);
auto ctx = (AVHWDeviceContext *) (*hw_device_buf)->data; auto ctx = (AVHWDeviceContext *) (*hw_device_buf)->data;
@ -596,20 +384,20 @@ namespace va {
} }
static bool static bool
query(display_t::pointer display, profile_e profile) { query(display_t::pointer display, VAProfile profile) {
std::vector<entry_e> entrypoints; std::vector<VAEntrypoint> entrypoints;
entrypoints.resize(maxNumEntrypoints(display)); entrypoints.resize(vaMaxNumEntrypoints(display));
int count; int count;
auto status = queryConfigEntrypoints(display, profile, entrypoints.data(), &count); auto status = vaQueryConfigEntrypoints(display, profile, entrypoints.data(), &count);
if (status) { 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; return false;
} }
entrypoints.resize(count); entrypoints.resize(count);
for (auto entrypoint : entrypoints) { for (auto entrypoint : entrypoints) {
if (entrypoint == entry_e::EncSlice || entrypoint == entry_e::EncSliceLP) { if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncSliceLP) {
return true; return true;
} }
} }
@ -619,11 +407,7 @@ namespace va {
bool bool
validate(int fd) { validate(int fd) {
if (init()) { va::display_t display { vaGetDisplayDRM(fd) };
return false;
}
va::display_t display { va::getDisplayDRM(fd) };
if (!display) { if (!display) {
char string[1024]; char string[1024];
@ -636,21 +420,21 @@ namespace va {
} }
int major, minor; int major, minor;
auto status = initialize(display.get(), &major, &minor); auto status = vaInitialize(display.get(), &major, &minor);
if (status) { 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; return false;
} }
if (!query(display.get(), profile_e::H264Main)) { if (!query(display.get(), VAProfileH264Main)) {
return false; 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; 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; return false;
} }

View file

@ -28,7 +28,4 @@ namespace va {
// Ensure the render device pointed to by fd is capable of encoding h264 with the hevc_mode configured // Ensure the render device pointed to by fd is capable of encoding h264 with the hevc_mode configured
bool bool
validate(int fd); validate(int fd);
int
init();
} // namespace va } // namespace va

View file

@ -211,9 +211,11 @@ namespace wl {
std::unique_ptr<platf::avcodec_encode_device_t> std::unique_ptr<platf::avcodec_encode_device_t>
make_avcodec_encode_device(platf::pix_fmt_e pix_fmt) override { make_avcodec_encode_device(platf::pix_fmt_e pix_fmt) override {
#ifdef SUNSHINE_BUILD_VAAPI
if (mem_type == platf::mem_type_e::vaapi) { if (mem_type == platf::mem_type_e::vaapi) {
return va::make_avcodec_encode_device(width, height, false); return va::make_avcodec_encode_device(width, height, false);
} }
#endif
return std::make_unique<platf::avcodec_encode_device_t>(); return std::make_unique<platf::avcodec_encode_device_t>();
} }
@ -321,9 +323,11 @@ namespace wl {
std::unique_ptr<platf::avcodec_encode_device_t> std::unique_ptr<platf::avcodec_encode_device_t>
make_avcodec_encode_device(platf::pix_fmt_e pix_fmt) override { make_avcodec_encode_device(platf::pix_fmt_e pix_fmt) override {
#ifdef SUNSHINE_BUILD_VAAPI
if (mem_type == platf::mem_type_e::vaapi) { if (mem_type == platf::mem_type_e::vaapi) {
return va::make_avcodec_encode_device(width, height, 0, 0, true); return va::make_avcodec_encode_device(width, height, 0, 0, true);
} }
#endif
return std::make_unique<platf::avcodec_encode_device_t>(); return std::make_unique<platf::avcodec_encode_device_t>();
} }

View file

@ -555,9 +555,11 @@ namespace platf {
std::unique_ptr<avcodec_encode_device_t> std::unique_ptr<avcodec_encode_device_t>
make_avcodec_encode_device(pix_fmt_e pix_fmt) override { make_avcodec_encode_device(pix_fmt_e pix_fmt) override {
#ifdef SUNSHINE_BUILD_VAAPI
if (mem_type == mem_type_e::vaapi) { if (mem_type == mem_type_e::vaapi) {
return va::make_avcodec_encode_device(width, height, false); return va::make_avcodec_encode_device(width, height, false);
} }
#endif
#ifdef SUNSHINE_BUILD_CUDA #ifdef SUNSHINE_BUILD_CUDA
if (mem_type == mem_type_e::cuda) { if (mem_type == mem_type_e::cuda) {