From 7b43cd12fc62d55e2419a2d5660420a461039db8 Mon Sep 17 00:00:00 2001 From: El Date: Tue, 30 Dec 2025 13:53:26 +0000 Subject: [PATCH] VNC-151 Adjust stream mode logic to use appropriate video codec configurations and presets --- common/rfb/ConnParams.cxx | 6 ++++-- common/rfb/SMsgWriter.cxx | 14 +++++++++++++- common/rfb/encoders/KasmVideoEncoders.h | 11 +++++------ common/rfb/encoders/SupportedVideoEncoders.h | 11 ++++++++--- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/common/rfb/ConnParams.cxx b/common/rfb/ConnParams.cxx index edcad2a..25b1796 100644 --- a/common/rfb/ConnParams.cxx +++ b/common/rfb/ConnParams.cxx @@ -356,9 +356,11 @@ void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings) } if (encodings[i] >= pseudoEncodingStreamingVideoQualityLevel0 && encodings[i] <= pseudoEncodingStreamingVideoQualityLevel63) { + const auto &config = EncoderConfiguration::get_configuration(encoder); + const auto value = config.max_quality - encodings[i] + pseudoEncodingStreamingVideoQualityLevel0; if (can_apply) - Server::videoQualityCRFCQP.setParam(pseudoEncodingStreamingVideoQualityLevel63 - encodings[i]); - clientparlog("videoQualityCRFCQP", pseudoEncodingStreamingVideoQualityLevel63 - encodings[i], can_apply); + Server::videoQualityCRFCQP.setParam(value); + clientparlog("videoQualityCRFCQP", value, can_apply); } if (encodings[i] >=pseudoEncodingStreamingModeAV1QSV && encodings[i] <= pseudoEncodingStreamingModeJpegWebp) { diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx index 89812c5..f2c1f03 100644 --- a/common/rfb/SMsgWriter.cxx +++ b/common/rfb/SMsgWriter.cxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -782,9 +783,20 @@ void SMsgWriter::writeVideoEncoders(const std::vector &encoders) { const uint8_t size = conjunction.size(); os->writeU8(size); - for (auto encoder: conjunction) + for (auto encoder: conjunction) { os->writeS32(encoder); + const auto &config = EncoderConfiguration::get_configuration(KasmVideoEncoders::from_encoding(encoder)); + + os->writeS32(config.min_quality); + os->writeS32(config.max_quality); + + os->writeU8(config.presets.size()); + for (const auto &preset_value: config.presets) { + os->writeS32(preset_value); + } + } + endMsg(); } diff --git a/common/rfb/encoders/KasmVideoEncoders.h b/common/rfb/encoders/KasmVideoEncoders.h index 68bd10c..2fda9df 100644 --- a/common/rfb/encoders/KasmVideoEncoders.h +++ b/common/rfb/encoders/KasmVideoEncoders.h @@ -75,11 +75,6 @@ auto enum_range(T begin, T end) { namespace rfb { struct KasmVideoEncoders { - struct EncoderSettings { - int16_t min_quality{}; - int16_t max_quality{}; - std::array presets{}; - }; // Codecs are ordered by preferred usage quality enum class Encoder : uint8_t { @@ -98,7 +93,7 @@ namespace rfb { h264_nvenc, h264_software, - unavailable + unavailable // Keep this as the last entry - used for compile-time size checks }; using Encoders = std::vector; @@ -119,6 +114,8 @@ namespace rfb { "libx264", "unavailable"}); + static_assert(EncoderNames.size() == static_cast(Encoder::unavailable) + 1, "EncoderNames array size must match Encoder enum count."); + static inline auto Encodings = std::to_array({pseudoEncodingStreamingModeAV1VAAPI, pseudoEncodingStreamingModeAV1VAAPI, pseudoEncodingStreamingModeAV1NVENC, @@ -136,6 +133,8 @@ namespace rfb { pseudoEncodingStreamingModeJpegWebp}); + static_assert(Encodings.size() == static_cast(Encoder::unavailable) + 1, "Encodings array size must match Encoder enum count. "); + static bool is_accelerated(Encoder encoder) { return encoder != Encoder::h264_software && encoder != Encoder::h265_software && encoder != Encoder::av1_software; } diff --git a/common/rfb/encoders/SupportedVideoEncoders.h b/common/rfb/encoders/SupportedVideoEncoders.h index 5e1257b..353e698 100644 --- a/common/rfb/encoders/SupportedVideoEncoders.h +++ b/common/rfb/encoders/SupportedVideoEncoders.h @@ -1,5 +1,5 @@ /* Copyright (C) 2025 Kasm. All Rights Reserved. -* + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -17,8 +17,8 @@ */ #pragma once -#include #include +#include #include #include #include @@ -46,7 +46,7 @@ namespace rfb { av1_vaapi, av1_nvenc, auto_detect, - unavailable + unavailable // Keep this as the last entry - used for compile-time size checks }; static constexpr auto MappedCodecs = std::to_array({KasmVideoEncoders::Encoder::h264_software, @@ -70,6 +70,9 @@ namespace rfb { KasmVideoEncoders::Encoder::unavailable}); + static_assert( + MappedCodecs.size() == static_cast(Codecs::unavailable) + 1, "MappedCodecs array size must match Codecs enum count"); + static inline auto CodecNames = std::to_array({"h264", "h264_vaapi", "h264_nvenc", @@ -90,6 +93,8 @@ namespace rfb { "auto"}); + static_assert(CodecNames.size() == static_cast(Codecs::unavailable), "CodecNames array size must match Codecs enum count"); + static std::string_view to_string(Codecs codec) { return CodecNames[static_cast(codec)]; }