style: adjust clang-format rules (#2186)
Co-authored-by: Vithorio Polten <reach@vithor.io>
This commit is contained in:
@@ -2,28 +2,30 @@
|
||||
* @file src/platform/linux/vaapi.cpp
|
||||
* @brief Definitions for VA-API hardware accelerated capture.
|
||||
*/
|
||||
// standard includes
|
||||
#include <fcntl.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/pixdesc.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
|
||||
vaSyncBuffer(
|
||||
VADisplay dpy,
|
||||
VABufferID buf_id,
|
||||
uint64_t timeout_ns) {
|
||||
return VA_STATUS_ERROR_UNIMPLEMENTED;
|
||||
}
|
||||
// vaSyncBuffer stub allows Sunshine built against libva <2.9.0 to link against ffmpeg on libva 2.9.0 or later
|
||||
VAStatus
|
||||
vaSyncBuffer(
|
||||
VADisplay dpy,
|
||||
VABufferID buf_id,
|
||||
uint64_t timeout_ns
|
||||
) {
|
||||
return VA_STATUS_ERROR_UNIMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// local includes
|
||||
#include "graphics.h"
|
||||
#include "misc.h"
|
||||
#include "src/config.h"
|
||||
@@ -69,6 +71,7 @@ namespace va {
|
||||
|
||||
// Number of layers making up the surface.
|
||||
uint32_t num_layers;
|
||||
|
||||
struct {
|
||||
// DRM format fourcc of this layer (DRM_FOURCC_*).
|
||||
uint32_t drm_format;
|
||||
@@ -89,13 +92,11 @@ namespace va {
|
||||
|
||||
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);
|
||||
int vaapi_init_avcodec_hardware_input_buffer(platf::avcodec_encode_device_t *encode_device, AVBufferRef **hw_device_buf);
|
||||
|
||||
class va_t: public platf::avcodec_encode_device_t {
|
||||
public:
|
||||
int
|
||||
init(int in_width, int in_height, file_t &&render_device) {
|
||||
int init(int in_width, int in_height, file_t &&render_device) {
|
||||
file = std::move(render_device);
|
||||
|
||||
if (!gbm::create_device) {
|
||||
@@ -135,8 +136,7 @@ namespace va {
|
||||
* @param profile The profile to match.
|
||||
* @return A valid encoding entrypoint or 0 on failure.
|
||||
*/
|
||||
VAEntrypoint
|
||||
select_va_entrypoint(VAProfile profile) {
|
||||
VAEntrypoint select_va_entrypoint(VAProfile profile) {
|
||||
std::vector<VAEntrypoint> entrypoints(vaMaxNumEntrypoints(va_display));
|
||||
int num_eps;
|
||||
auto status = vaQueryConfigEntrypoints(va_display, profile, entrypoints.data(), &num_eps);
|
||||
@@ -166,8 +166,7 @@ namespace va {
|
||||
* @param profile The profile to match.
|
||||
* @return Boolean value indicating if the profile is supported.
|
||||
*/
|
||||
bool
|
||||
is_va_profile_supported(VAProfile profile) {
|
||||
bool is_va_profile_supported(VAProfile profile) {
|
||||
std::vector<VAProfile> profiles(vaMaxNumProfiles(va_display));
|
||||
int num_profs;
|
||||
auto status = vaQueryConfigProfiles(va_display, profiles.data(), &num_profs);
|
||||
@@ -185,13 +184,11 @@ namespace va {
|
||||
* @param ctx The FFmpeg codec context.
|
||||
* @return The matching VA profile or `VAProfileNone` on failure.
|
||||
*/
|
||||
VAProfile
|
||||
get_va_profile(AVCodecContext *ctx) {
|
||||
VAProfile get_va_profile(AVCodecContext *ctx) {
|
||||
if (ctx->codec_id == AV_CODEC_ID_H264) {
|
||||
// There's no VAAPI profile for H.264 4:4:4
|
||||
return VAProfileH264High;
|
||||
}
|
||||
else if (ctx->codec_id == AV_CODEC_ID_HEVC) {
|
||||
} else if (ctx->codec_id == AV_CODEC_ID_HEVC) {
|
||||
switch (ctx->profile) {
|
||||
case FF_PROFILE_HEVC_REXT:
|
||||
switch (av_pix_fmt_desc_get(ctx->sw_pix_fmt)->comp[0].depth) {
|
||||
@@ -206,8 +203,7 @@ namespace va {
|
||||
case FF_PROFILE_HEVC_MAIN:
|
||||
return VAProfileHEVCMain;
|
||||
}
|
||||
}
|
||||
else if (ctx->codec_id == AV_CODEC_ID_AV1) {
|
||||
} else if (ctx->codec_id == AV_CODEC_ID_AV1) {
|
||||
switch (ctx->profile) {
|
||||
case FF_PROFILE_AV1_HIGH:
|
||||
return VAProfileAV1Profile1;
|
||||
@@ -220,8 +216,7 @@ namespace va {
|
||||
return VAProfileNone;
|
||||
}
|
||||
|
||||
void
|
||||
init_codec_options(AVCodecContext *ctx, AVDictionary **options) override {
|
||||
void init_codec_options(AVCodecContext *ctx, AVDictionary **options) override {
|
||||
auto va_profile = get_va_profile(ctx);
|
||||
if (va_profile == VAProfileNone || !is_va_profile_supported(va_profile)) {
|
||||
// Don't bother doing anything if the profile isn't supported
|
||||
@@ -239,19 +234,18 @@ namespace va {
|
||||
if (va_entrypoint == VAEntrypointEncSliceLP) {
|
||||
BOOST_LOG(info) << "Using LP encoding mode"sv;
|
||||
av_dict_set_int(options, "low_power", 1, 0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
BOOST_LOG(info) << "Using normal encoding mode"sv;
|
||||
}
|
||||
|
||||
VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
|
||||
VAConfigAttrib rc_attr = {VAConfigAttribRateControl};
|
||||
auto status = vaGetConfigAttributes(va_display, va_profile, va_entrypoint, &rc_attr, 1);
|
||||
if (status != VA_STATUS_SUCCESS) {
|
||||
// Stick to the default rate control (CQP)
|
||||
rc_attr.value = 0;
|
||||
}
|
||||
|
||||
VAConfigAttrib slice_attr = { VAConfigAttribEncMaxSlices };
|
||||
VAConfigAttrib slice_attr = {VAConfigAttribEncMaxSlices};
|
||||
status = vaGetConfigAttributes(va_display, va_profile, va_entrypoint, &slice_attr, 1);
|
||||
if (status != VA_STATUS_SUCCESS) {
|
||||
// Assume only a single slice is supported
|
||||
@@ -281,27 +275,22 @@ namespace va {
|
||||
if (rc_attr.value & VA_RC_VBR) {
|
||||
BOOST_LOG(info) << "Using VBR with single frame VBV size"sv;
|
||||
av_dict_set(options, "rc_mode", "VBR", 0);
|
||||
}
|
||||
else if (rc_attr.value & VA_RC_CBR) {
|
||||
} else if (rc_attr.value & VA_RC_CBR) {
|
||||
BOOST_LOG(info) << "Using CBR with single frame VBV size"sv;
|
||||
av_dict_set(options, "rc_mode", "CBR", 0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
BOOST_LOG(warning) << "Using CQP with single frame VBV size"sv;
|
||||
av_dict_set_int(options, "qp", config::video.qp, 0);
|
||||
}
|
||||
}
|
||||
else if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {
|
||||
} else if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {
|
||||
BOOST_LOG(warning) << "Using CQP rate control"sv;
|
||||
av_dict_set_int(options, "qp", config::video.qp, 0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
BOOST_LOG(info) << "Using default rate control"sv;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx_buf) override {
|
||||
int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx_buf) override {
|
||||
this->hwframe.reset(frame);
|
||||
this->frame = frame;
|
||||
|
||||
@@ -321,7 +310,8 @@ namespace va {
|
||||
surface,
|
||||
va::SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
|
||||
va::EXPORT_SURFACE_WRITE_ONLY | va::EXPORT_SURFACE_SEPARATE_LAYERS,
|
||||
&prime);
|
||||
&prime
|
||||
);
|
||||
if (status) {
|
||||
BOOST_LOG(error) << "Couldn't export va surface handle: ["sv << (int) surface << "]: "sv << vaErrorStr(status);
|
||||
|
||||
@@ -377,8 +367,7 @@ namespace va {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
apply_colorspace() override {
|
||||
void apply_colorspace() override {
|
||||
sws.apply_colorspace(colorspace);
|
||||
}
|
||||
|
||||
@@ -401,8 +390,7 @@ namespace va {
|
||||
|
||||
class va_ram_t: public va_t {
|
||||
public:
|
||||
int
|
||||
convert(platf::img_t &img) override {
|
||||
int convert(platf::img_t &img) override {
|
||||
sws.load_ram(img);
|
||||
|
||||
sws.convert(nv12->buf);
|
||||
@@ -412,15 +400,13 @@ namespace va {
|
||||
|
||||
class va_vram_t: public va_t {
|
||||
public:
|
||||
int
|
||||
convert(platf::img_t &img) override {
|
||||
int convert(platf::img_t &img) override {
|
||||
auto &descriptor = (egl::img_descriptor_t &) img;
|
||||
|
||||
if (descriptor.sequence == 0) {
|
||||
// For dummy images, use a blank RGB texture instead of importing a DMA-BUF
|
||||
rgb = egl::create_blank(img);
|
||||
}
|
||||
else if (descriptor.sequence > sequence) {
|
||||
} else if (descriptor.sequence > sequence) {
|
||||
sequence = descriptor.sequence;
|
||||
|
||||
rgb = egl::rgb_t {};
|
||||
@@ -440,8 +426,7 @@ namespace va {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
init(int in_width, int in_height, file_t &&render_device, int offset_x, int offset_y) {
|
||||
int init(int in_width, int in_height, file_t &&render_device, int offset_x, int offset_y) {
|
||||
if (va_t::init(in_width, in_height, std::move(render_device))) {
|
||||
return -1;
|
||||
}
|
||||
@@ -471,6 +456,7 @@ namespace va {
|
||||
void *xdisplay;
|
||||
int fd;
|
||||
} drm;
|
||||
|
||||
int drm_fd;
|
||||
} VAAPIDevicePriv;
|
||||
|
||||
@@ -494,13 +480,11 @@ namespace va {
|
||||
unsigned int driver_quirks;
|
||||
} AVVAAPIDeviceContext;
|
||||
|
||||
static void
|
||||
__log(void *level, const char *msg) {
|
||||
static void __log(void *level, const char *msg) {
|
||||
BOOST_LOG(*(boost::log::sources::severity_logger<int> *) level) << msg;
|
||||
}
|
||||
|
||||
static void
|
||||
vaapi_hwdevice_ctx_free(AVHWDeviceContext *ctx) {
|
||||
static void vaapi_hwdevice_ctx_free(AVHWDeviceContext *ctx) {
|
||||
auto hwctx = (AVVAAPIDeviceContext *) ctx->hwctx;
|
||||
auto priv = (VAAPIDevicePriv *) ctx->user_opaque;
|
||||
|
||||
@@ -509,8 +493,7 @@ namespace va {
|
||||
av_freep(&priv);
|
||||
}
|
||||
|
||||
int
|
||||
vaapi_init_avcodec_hardware_input_buffer(platf::avcodec_encode_device_t *base, AVBufferRef **hw_device_buf) {
|
||||
int vaapi_init_avcodec_hardware_input_buffer(platf::avcodec_encode_device_t *base, AVBufferRef **hw_device_buf) {
|
||||
auto va = (va::va_t *) base;
|
||||
auto fd = dup(va->file.el);
|
||||
|
||||
@@ -522,7 +505,7 @@ namespace va {
|
||||
av_free(priv);
|
||||
});
|
||||
|
||||
va::display_t display { vaGetDisplayDRM(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();
|
||||
|
||||
@@ -556,7 +539,7 @@ namespace va {
|
||||
|
||||
auto err = av_hwdevice_ctx_init(*hw_device_buf);
|
||||
if (err) {
|
||||
char err_str[AV_ERROR_MAX_STRING_SIZE] { 0 };
|
||||
char err_str[AV_ERROR_MAX_STRING_SIZE] {0};
|
||||
BOOST_LOG(error) << "Failed to create FFMpeg hardware device context: "sv << av_make_error_string(err_str, AV_ERROR_MAX_STRING_SIZE, err);
|
||||
|
||||
return err;
|
||||
@@ -565,8 +548,7 @@ namespace va {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
query(display_t::pointer display, VAProfile profile) {
|
||||
static bool query(display_t::pointer display, VAProfile profile) {
|
||||
std::vector<VAEntrypoint> entrypoints;
|
||||
entrypoints.resize(vaMaxNumEntrypoints(display));
|
||||
|
||||
@@ -587,15 +569,14 @@ namespace va {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
validate(int fd) {
|
||||
va::display_t display { vaGetDisplayDRM(fd) };
|
||||
bool validate(int fd) {
|
||||
va::display_t display {vaGetDisplayDRM(fd)};
|
||||
if (!display) {
|
||||
char string[1024];
|
||||
|
||||
auto bytes = readlink(("/proc/self/fd/" + std::to_string(fd)).c_str(), string, sizeof(string));
|
||||
|
||||
std::string_view render_device { string, (std::size_t) bytes };
|
||||
std::string_view render_device {string, (std::size_t) bytes};
|
||||
|
||||
BOOST_LOG(error) << "Couldn't open a va display from DRM with device: "sv << render_device;
|
||||
return false;
|
||||
@@ -623,8 +604,7 @@ namespace va {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<platf::avcodec_encode_device_t>
|
||||
make_avcodec_encode_device(int width, int height, file_t &&card, int offset_x, int offset_y, bool vram) {
|
||||
std::unique_ptr<platf::avcodec_encode_device_t> make_avcodec_encode_device(int width, int height, file_t &&card, int offset_x, int offset_y, bool vram) {
|
||||
if (vram) {
|
||||
auto egl = std::make_unique<va::va_vram_t>();
|
||||
if (egl->init(width, height, std::move(card), offset_x, offset_y)) {
|
||||
@@ -644,8 +624,7 @@ namespace va {
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<platf::avcodec_encode_device_t>
|
||||
make_avcodec_encode_device(int width, int height, int offset_x, int offset_y, bool vram) {
|
||||
std::unique_ptr<platf::avcodec_encode_device_t> make_avcodec_encode_device(int width, int height, int offset_x, int offset_y, bool vram) {
|
||||
auto render_device = config::video.adapter_name.empty() ? "/dev/dri/renderD128" : config::video.adapter_name.c_str();
|
||||
|
||||
file_t file = open(render_device, O_RDWR);
|
||||
@@ -659,8 +638,7 @@ namespace va {
|
||||
return make_avcodec_encode_device(width, height, std::move(file), offset_x, offset_y, vram);
|
||||
}
|
||||
|
||||
std::unique_ptr<platf::avcodec_encode_device_t>
|
||||
make_avcodec_encode_device(int width, int height, bool vram) {
|
||||
std::unique_ptr<platf::avcodec_encode_device_t> make_avcodec_encode_device(int width, int height, bool vram) {
|
||||
return make_avcodec_encode_device(width, height, 0, 0, vram);
|
||||
}
|
||||
} // namespace va
|
||||
|
||||
Reference in New Issue
Block a user