mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-01-27 03:35:36 +00:00
build(linux) make vaapi optional without dlopen (#1979)
Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
This commit is contained in:
parent
0dff8b16fd
commit
bc6cc2078e
70
cmake/FindLibva.cmake
Normal file
70
cmake/FindLibva.cmake
Normal 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()
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -793,9 +793,11 @@ namespace platf {
|
||||
|
||||
std::unique_ptr<avcodec_encode_device_t>
|
||||
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<avcodec_encode_device_t>();
|
||||
}
|
||||
@ -862,9 +864,11 @@ namespace platf {
|
||||
|
||||
std::unique_ptr<avcodec_encode_device_t>
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -10,6 +10,7 @@
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <va/va.h>
|
||||
#include <va/va_drm.h>
|
||||
#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<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;
|
||||
}
|
||||
using display_t = util::safe_ptr_v2<void, VAStatus, vaTerminate>;
|
||||
|
||||
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<entry_e> entrypoints;
|
||||
entrypoints.resize(maxNumEntrypoints(display));
|
||||
query(display_t::pointer display, VAProfile profile) {
|
||||
std::vector<VAEntrypoint> 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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -211,9 +211,11 @@ namespace wl {
|
||||
|
||||
std::unique_ptr<platf::avcodec_encode_device_t>
|
||||
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<platf::avcodec_encode_device_t>();
|
||||
}
|
||||
@ -321,9 +323,11 @@ namespace wl {
|
||||
|
||||
std::unique_ptr<platf::avcodec_encode_device_t>
|
||||
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<platf::avcodec_encode_device_t>();
|
||||
}
|
||||
|
@ -555,9 +555,11 @@ namespace platf {
|
||||
|
||||
std::unique_ptr<avcodec_encode_device_t>
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user