From 4c42086f0941a75554cc96077f1c08cee6168f48 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 27 Oct 2024 20:32:05 -0500 Subject: [PATCH] feat(vaapi): add option to enable strict enforcement of frame size --- docs/configuration.md | 27 ++++++++++++++++++ src/config.cpp | 6 ++++ src/config.h | 4 +++ src/platform/linux/vaapi.cpp | 12 ++++---- src_assets/common/assets/web/config.html | 11 ++++++-- .../web/configs/tabs/ContainerEncoders.vue | 8 ++++++ .../configs/tabs/encoders/VAAPIEncoder.vue | 28 +++++++++++++++++++ .../assets/web/public/assets/locale/en.json | 2 ++ 8 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 src_assets/common/assets/web/configs/tabs/encoders/VAAPIEncoder.vue diff --git a/docs/configuration.md b/docs/configuration.md index 2b282d1c7a1..d5803037943 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2303,6 +2303,33 @@ editing the `conf` file in a text editor. Use the examples as reference. +## VAAPI Encoder + +### vaapi_strict_rc_buffer + + + + + + + + + + + + + + +
Description + Enabling this option can avoid dropped frames over the network during scene changes, but video quality may + be reduced during motion. + @note{This option only applies when using Linux.} +
Default@code{} + disabled + @endcode
Example@code{} + vaapi_strict_rc_buffer = enabled + @endcode
+ ## Software Encoder ### sw_preset diff --git a/src/config.cpp b/src/config.cpp index 8475a5e3370..a61b69b96f1 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -377,6 +377,10 @@ namespace config { -1, }, // vt + { + false, // strict_rc_buffer + }, // vaapi + {}, // capture {}, // encoder {}, // adapter_name @@ -1014,6 +1018,8 @@ namespace config { int_f(vars, "vt_software", video.vt.vt_require_sw, vt::force_software_from_view); int_f(vars, "vt_realtime", video.vt.vt_realtime, vt::rt_from_view); + bool_f(vars, "vaapi_strict_rc_buffer", video.vaapi.strict_rc_buffer); + string_f(vars, "capture", video.capture); string_f(vars, "encoder", video.encoder); string_f(vars, "adapter_name", video.adapter_name); diff --git a/src/config.h b/src/config.h index e599afae454..891a4079772 100644 --- a/src/config.h +++ b/src/config.h @@ -71,6 +71,10 @@ namespace config { int vt_coder; } vt; + struct { + bool strict_rc_buffer; + } vaapi; + std::string capture; std::string encoder; std::string adapter_name; diff --git a/src/platform/linux/vaapi.cpp b/src/platform/linux/vaapi.cpp index ada6370034a..b0f8cb670f3 100644 --- a/src/platform/linux/vaapi.cpp +++ b/src/platform/linux/vaapi.cpp @@ -131,11 +131,13 @@ namespace va { void init_codec_options(AVCodecContext *ctx, AVDictionary *options) override { - // Don't set the RC buffer size when using H.264 on Intel GPUs. It causes - // major encoding quality degradation. - auto vendor = vaQueryVendorString(va_display); - if (ctx->codec_id != AV_CODEC_ID_H264 || (vendor && !strstr(vendor, "Intel"))) { - ctx->rc_buffer_size = ctx->bit_rate * ctx->framerate.den / ctx->framerate.num; + if (config::video.vaapi.strict_rc_buffer) { + // Don't set the RC buffer size when using H.264 on Intel GPUs. It causes + // major encoding quality degradation. + auto vendor = vaQueryVendorString(va_display); + if (ctx->codec_id != AV_CODEC_ID_H264 || (vendor && !strstr(vendor, "Intel"))) { + ctx->rc_buffer_size = ctx->bit_rate * ctx->framerate.den / ctx->framerate.num; + } } } diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index c9c0a6ddf71..d247a9b4115 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -257,6 +257,13 @@

{{ $t('config.configuration') }}

"vt_realtime": "enabled", }, }, + { + id: "vaapi", + name: "VAAPI Encoder", + options: { + "vaapi_strict_rc_buffer": "disabled", + }, + }, { id: "sw", name: "Software Encoder", @@ -283,7 +290,7 @@

{{ $t('config.configuration') }}

var app = document.getElementById("app"); if (this.platform === "windows") { this.tabs = this.tabs.filter((el) => { - return el.id !== "vt"; + return el.id !== "vt" && el.id !== "vaapi"; }); } if (this.platform === "linux") { @@ -293,7 +300,7 @@

{{ $t('config.configuration') }}

} if (this.platform === "macos") { this.tabs = this.tabs.filter((el) => { - return el.id !== "amd" && el.id !== "nv" && el.id !== "qsv"; + return el.id !== "amd" && el.id !== "nv" && el.id !== "qsv" && el.id !== "vaapi"; }); } diff --git a/src_assets/common/assets/web/configs/tabs/ContainerEncoders.vue b/src_assets/common/assets/web/configs/tabs/ContainerEncoders.vue index 084c3001f57..1dce1403adf 100644 --- a/src_assets/common/assets/web/configs/tabs/ContainerEncoders.vue +++ b/src_assets/common/assets/web/configs/tabs/ContainerEncoders.vue @@ -5,6 +5,7 @@ import IntelQuickSyncEncoder from './encoders/IntelQuickSyncEncoder.vue' import AmdAmfEncoder from './encoders/AmdAmfEncoder.vue' import VideotoolboxEncoder from './encoders/VideotoolboxEncoder.vue' import SoftwareEncoder from './encoders/SoftwareEncoder.vue' +import VAAPIEncoder from './encoders/VAAPIEncoder.vue' const props = defineProps([ 'platform', @@ -45,6 +46,13 @@ const config = ref(props.config) :config="config" /> + + + +import { ref } from 'vue' + +const props = defineProps([ + 'platform', + 'config', +]) + +const config = ref(props.config) + + + + + diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json index 12844fcf874..a0d4250f80a 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "If disabled, touchpad presence will not be taken into account during gamepad type selection.", "upnp": "UPnP", "upnp_desc": "Automatically configure port forwarding for streaming over the Internet", + "vaapi_strict_rc_buffer": "Strictly enforce frame bitrate limits", + "vaapi_strict_rc_buffer_desc": "Enabling this option can avoid dropped frames over the network during scene changes, but video quality may be reduced during motion.", "virtual_sink": "Virtual Sink", "virtual_sink_desc": "Manually specify a virtual audio device to use. If unset, the device is chosen automatically. We strongly recommend leaving this field blank to use automatic device selection!", "virtual_sink_placeholder": "Steam Streaming Speakers",