diff --git a/docs/configuration.md b/docs/configuration.md index 98bab79a060..5b2bba679d7 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1774,6 +1774,46 @@ editing the `conf` file in a text editor. Use the examples as reference. +### [nvenc_split_encode](https://localhost:47990/config/#nvenc_split_encode) + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Description + Split the encoding of each video frame over multiple NVENC hardware units. + Significantly reduces encoding latency with a marginal compression efficiency penalty. + This option is ignored if your GPU has a singular NVENC unit. + @note{This option only applies when using NVENC [encoder](#encoderhttpslocalhost47990configencoder).} + @note{Applies to Windows only.} +
Default@code{} + driver_decides + @endcode
Example@code{} + nvenc_split_encode = driver_decides + @endcode
ChoicesdisabledDisabled
driver_decidesNVIDIA driver makes the decision whether to enable it
enabledEnabled
+ ### [nvenc_latency_over_power](https://localhost:47990/config/#nvenc_latency_over_power) diff --git a/src/config.cpp b/src/config.cpp index e8accb15a57..aed7875b065 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -56,6 +56,16 @@ namespace config { return nvenc::nvenc_two_pass::quarter_resolution; } + nvenc::nvenc_split_frame_encoding + split_encode_from_view(const std::string_view &preset) { + using enum nvenc::nvenc_split_frame_encoding; + if (preset == "disabled") return disabled; + if (preset == "driver_decides") return driver_decides; + if (preset == "enabled") return force_enabled; + BOOST_LOG(warning) << "config: unknown nvenc_split_encode value: " << preset; + return driver_decides; + } + } // namespace nv namespace amd { @@ -960,6 +970,7 @@ namespace config { bool_f(vars, "nvenc_spatial_aq", video.nv.adaptive_quantization); generic_f(vars, "nvenc_twopass", video.nv.two_pass, nv::twopass_from_view); bool_f(vars, "nvenc_h264_cavlc", video.nv.h264_cavlc); + generic_f(vars, "nvenc_split_encode", video.nv.split_frame_encoding, nv::split_encode_from_view); bool_f(vars, "nvenc_realtime_hags", video.nv_realtime_hags); bool_f(vars, "nvenc_opengl_vulkan_on_dxgi", video.nv_opengl_vulkan_on_dxgi); bool_f(vars, "nvenc_latency_over_power", video.nv_sunshine_high_power_mode); diff --git a/src/nvenc/common_impl/nvenc_base.cpp b/src/nvenc/common_impl/nvenc_base.cpp index 731ea449132..594ae10d796 100644 --- a/src/nvenc/common_impl/nvenc_base.cpp +++ b/src/nvenc/common_impl/nvenc_base.cpp @@ -223,6 +223,15 @@ namespace nvenc { init_params.frameRateNum = client_config.framerate; init_params.frameRateDen = 1; +#if NVENC_INT_VERSION >= 1202 + { + using enum nvenc_split_frame_encoding; + init_params.splitEncodeMode = config.split_frame_encoding == disabled ? NV_ENC_SPLIT_DISABLE_MODE : + config.split_frame_encoding == force_enabled ? NV_ENC_SPLIT_AUTO_FORCED_MODE : + NV_ENC_SPLIT_AUTO_MODE; + } +#endif + NV_ENC_PRESET_CONFIG preset_config = { .version = NV_ENC_PRESET_CONFIG_VER, .presetCfg = { .version = NV_ENC_CONFIG_VER }, @@ -257,8 +266,12 @@ namespace nvenc { auto set_h264_hevc_common_format_config = [&](auto &format_config) { format_config.repeatSPSPPS = 1; format_config.idrPeriod = NVENC_INFINITE_GOPLENGTH; - format_config.sliceMode = 3; - format_config.sliceModeData = client_config.slicesPerFrame; + if (client_config.slicesPerFrame > 1 || + NVENC_INT_VERSION < 1202 || + config.split_frame_encoding == nvenc_split_frame_encoding::disabled) { + format_config.sliceMode = 3; + format_config.sliceModeData = client_config.slicesPerFrame; + } if (buffer_is_yuv444()) { format_config.chromaFormatIDC = 3; } diff --git a/src/nvenc/nvenc_config.h b/src/nvenc/nvenc_config.h index 213a0d289fa..03922e52902 100644 --- a/src/nvenc/nvenc_config.h +++ b/src/nvenc/nvenc_config.h @@ -12,6 +12,12 @@ namespace nvenc { full_resolution, ///< Better overall statistics, slower and uses more extra vram }; + enum class nvenc_split_frame_encoding { + disabled, ///< Disable + driver_decides, ///< Let driver decide + force_enabled, ///< Force-enable + }; + /** * @brief NVENC encoder configuration. */ @@ -48,6 +54,9 @@ namespace nvenc { // Add filler data to encoded frames to stay at target bitrate, mainly for testing bool insert_filler_data = false; + + // Enable split-frame encoding if the gpu has multiple NVENC hardware clusters + nvenc_split_frame_encoding split_frame_encoding = nvenc_split_frame_encoding::driver_decides; }; } // namespace nvenc diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index 8386dbd3673..f6da228a472 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -222,6 +222,7 @@

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

"nvenc_spatial_aq": "disabled", "nvenc_vbv_increase": 0, "nvenc_realtime_hags": "enabled", + "nvenc_split_encode": "driver_decides", "nvenc_latency_over_power": "enabled", "nvenc_opengl_vulkan_on_dxgi": "enabled", "nvenc_h264_cavlc": "disabled", diff --git a/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue b/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue index aa6ad003ac2..bda55e0eea4 100644 --- a/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue +++ b/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue @@ -85,6 +85,17 @@ const config = ref(props.config) + +
+ + +
{{ $t('config.nvenc_split_encode_desc') }}
+
+
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..b369639aeaf 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -239,6 +239,9 @@ "nvenc_spatial_aq_desc": "Assign higher QP values to flat regions of the video. Recommended to enable when streaming at lower bitrates.", "nvenc_spatial_aq_disabled": "Disabled (faster, default)", "nvenc_spatial_aq_enabled": "Enabled (slower)", + "nvenc_split_encode": "Split frame encoding", + "nvenc_split_encode_desc": "Split the encoding of each video frame over multiple NVENC hardware units. Significantly reduces encoding latency with a marginal compression efficiency penalty. This option is ignored if your GPU has a singular NVENC unit.", + "nvenc_split_encode_driver_decides_def": "Driver decides (default)", "nvenc_twopass": "Two-pass mode", "nvenc_twopass_desc": "Adds preliminary encoding pass. This allows to detect more motion vectors, better distribute bitrate across the frame and more strictly adhere to bitrate limits. Disabling it is not recommended since this can lead to occasional bitrate overshoot and subsequent packet loss.", "nvenc_twopass_disabled": "Disabled (fastest, not recommended)",