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:
El 2025-10-07 09:35:12 +05:00
parent 6ddd9b798e
commit 1c80f6b9d0
No known key found for this signature in database
GPG key ID: 205388FEB607950A
2 changed files with 53 additions and 11 deletions

View file

@ -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;

View file

@ -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)];