mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2026-07-17 16:36:49 +00:00
VNC-151 Add support for AV1 and H265 codecs, update encoder list, and debug print codec options with av_opt_next
This commit is contained in:
parent
6ddd9b798e
commit
1c80f6b9d0
2 changed files with 53 additions and 11 deletions
|
|
@ -8,11 +8,12 @@
|
|||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/opt.h>
|
||||
}
|
||||
#include "rfb/ffmpeg.h"
|
||||
|
||||
namespace rfb::video_encoders {
|
||||
const std::vector<KasmVideoEncoders::Encoder>& available_encoders = EncoderProbe::get(FFmpeg::get()).get_available_encoders();
|
||||
const std::vector<KasmVideoEncoders::Encoder> &available_encoders = EncoderProbe::get(FFmpeg::get()).get_available_encoders();
|
||||
const KasmVideoEncoders::Encoder best_encoder = EncoderProbe::get(FFmpeg::get()).select_best_encoder();
|
||||
const std::string_view drm_device_path = EncoderProbe::get(FFmpeg::get()).get_drm_device_path();
|
||||
|
||||
|
|
@ -22,9 +23,13 @@ namespace rfb::video_encoders {
|
|||
AVHWDeviceType hw_type;
|
||||
};
|
||||
|
||||
static std::array<EncoderCandidate, 3> candidates = {
|
||||
static std::array<EncoderCandidate, 6> candidates = {
|
||||
{//{KasmVideoEncoders::Encoder::h264_nvenc, AV_CODEC_ID_H264, AV_HWDEVICE_TYPE_VAAPI}
|
||||
{KasmVideoEncoders::Encoder::h264_vaapi, AV_CODEC_ID_H264, AV_HWDEVICE_TYPE_VAAPI},
|
||||
{KasmVideoEncoders::Encoder::av1_vaapi, AV_CODEC_ID_AV1, AV_HWDEVICE_TYPE_VAAPI},
|
||||
{KasmVideoEncoders::Encoder::hevc_vaapi, AV_CODEC_ID_HEVC, AV_HWDEVICE_TYPE_VAAPI}, // h265
|
||||
{KasmVideoEncoders::Encoder::h264_vaapi, AV_CODEC_ID_H264, AV_HWDEVICE_TYPE_VAAPI},
|
||||
{KasmVideoEncoders::Encoder::av1_software, AV_CODEC_ID_AV1, AV_HWDEVICE_TYPE_NONE},
|
||||
{KasmVideoEncoders::Encoder::h265_software, AV_CODEC_ID_HEVC, AV_HWDEVICE_TYPE_NONE},
|
||||
{KasmVideoEncoders::Encoder::h264_software, AV_CODEC_ID_H264, AV_HWDEVICE_TYPE_NONE}}};
|
||||
|
||||
EncoderProbe::EncoderProbe(FFmpeg &ffmpeg_) : ffmpeg(ffmpeg_) {
|
||||
|
|
@ -34,7 +39,13 @@ namespace rfb::video_encoders {
|
|||
if (!codec)
|
||||
continue;
|
||||
|
||||
if (codec->type != AVMEDIA_TYPE_VIDEO)
|
||||
continue;
|
||||
|
||||
if (encoder_candidate.hw_type != AV_HWDEVICE_TYPE_NONE) {
|
||||
if (!ffmpeg.av_codec_is_encoder(codec))
|
||||
continue;
|
||||
|
||||
FFmpeg::BufferGuard hw_ctx_guard;
|
||||
AVBufferRef *hw_ctx{};
|
||||
hw_ctx_guard.reset(hw_ctx);
|
||||
|
|
@ -42,10 +53,20 @@ namespace rfb::video_encoders {
|
|||
for (auto &drm_dev_path: drm_device_paths) {
|
||||
const auto err = ffmpeg.av_hwdevice_ctx_create(&hw_ctx, encoder_candidate.hw_type, drm_dev_path.data(), nullptr, 0);
|
||||
if (err < 0) {
|
||||
puts((ffmpeg.get_error_description(err) + '\n').c_str());
|
||||
puts(ffmpeg.get_error_description(err).c_str());
|
||||
} else {
|
||||
drm_device_path = drm_dev_path;
|
||||
|
||||
if (encoder_candidate.hw_type == AV_HWDEVICE_TYPE_VAAPI) {
|
||||
printf("DEBUG: Codec: %s\n", codec->name);
|
||||
const FFmpeg::ContextGuard ctx_guard{ffmpeg.avcodec_alloc_context3(codec)};
|
||||
|
||||
const AVOption *opt{};
|
||||
while (opt = ffmpeg.av_opt_next(ctx_guard->priv_data, opt), opt) {
|
||||
printf("DEBUG: Option: %s.%s (help: %s)\n", codec->name, opt->name, opt->help ? opt->help : "n/a");
|
||||
}
|
||||
}
|
||||
|
||||
available_encoders.push_back(encoder_candidate.encoder);
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -29,28 +29,48 @@ namespace rfb {
|
|||
static constexpr int GroupOfPictureSize = 10; // interval between I-frames
|
||||
|
||||
static constexpr std::array<std::string_view, 4> drm_device_paths = {
|
||||
"/dev/dri/renderD128",
|
||||
"/dev/dri/card0",
|
||||
"/dev/dri/renderD129",
|
||||
"/dev/dri/card1",
|
||||
"/dev/dri/renderD128",
|
||||
"/dev/dri/card0",
|
||||
"/dev/dri/renderD129",
|
||||
"/dev/dri/card1",
|
||||
};
|
||||
|
||||
struct SupportedVideoEncoders {
|
||||
enum class Codecs : uint8_t
|
||||
{
|
||||
H264
|
||||
H264,
|
||||
H265,
|
||||
AV1
|
||||
};
|
||||
|
||||
static inline std::array<std::string_view, 1> CodecNames = {"h264"};
|
||||
static inline std::array<std::string_view, 3> CodecNames = {"h264", "h265", "av1"};
|
||||
|
||||
static std::string_view to_string(Codecs codec) {
|
||||
return CodecNames[static_cast<uint8_t>(codec)];
|
||||
}
|
||||
|
||||
static bool is_supported(std::string_view codec) {
|
||||
if (codec.empty())
|
||||
return false;
|
||||
|
||||
for (auto supported_codec: CodecNames)
|
||||
if (supported_codec == codec)
|
||||
return true;
|
||||
|
||||
if (codec == "hevc")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct KasmVideoEncoders {
|
||||
enum class Encoder : uint8_t
|
||||
{
|
||||
av1_vaapi,
|
||||
av1_software,
|
||||
hevc_vaapi, // h265
|
||||
h265_software,
|
||||
h264_vaapi,
|
||||
h264_ffmpeg_vaapi,
|
||||
h264_nvenc,
|
||||
|
|
@ -58,7 +78,8 @@ namespace rfb {
|
|||
unavailable
|
||||
};
|
||||
|
||||
static inline std::array<std::string_view, 3> EncoderNames = {"h264_vaapi", "h264_nvenc", "libx264"};
|
||||
static inline std::array<std::string_view, 9> EncoderNames = {
|
||||
"av1_vaapi", "av1_software", "hevc_vaapi", "libx265", "h264_vaapi", "h264_vaapi", "h264_nvenc", "libx264", "unavailable"};
|
||||
|
||||
static std::string_view to_string(Encoder encoder) {
|
||||
return EncoderNames[static_cast<uint8_t>(encoder)];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue