From 7b19603a9ad5063ec626c64f2c1f9ab9432e7008 Mon Sep 17 00:00:00 2001 From: Conn O'Griofa Date: Fri, 19 Apr 2024 13:31:56 +0100 Subject: [PATCH] fix(windows/amf): Revert RC/HRD defaults; improve documentation & config parsing (#2419) --- docs/source/about/advanced_usage.rst | 114 ++++++++----- src/config.cpp | 66 ++++---- src/config.h | 14 +- src_assets/common/assets/web/config.html | 151 +++++++++++------- .../assets/web/public/assets/locale/en.json | 15 +- 5 files changed, 219 insertions(+), 141 deletions(-) diff --git a/docs/source/about/advanced_usage.rst b/docs/source/about/advanced_usage.rst index 1c3a0f64c56..6aa33feee43 100644 --- a/docs/source/about/advanced_usage.rst +++ b/docs/source/about/advanced_usage.rst @@ -1471,34 +1471,42 @@ keybindings `AMD AMF Encoder `__ --------------------------------------------------------------------- -`amd_quality `__ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`amd_usage `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Description** - The encoder preset to use. + The encoder usage profile is used to set the base set of encoding + parameters. .. note:: This option only applies when using amdvce `encoder`_. + .. note:: The other AMF options that follow will override a subset + of the settings applied by your usage profile, but there are + hidden parameters set in usage profiles that cannot be + overridden elsewhere. + **Choices** .. table:: :widths: auto - ========== =========== - Value Description - ========== =========== - speed prefer speed - balanced balanced - quality prefer quality - ========== =========== + ======================= =========== + Value Description + ======================= =========== + transcoding transcoding (slowest) + webcam webcam (slow) + lowlatency_high_quality low latency, high quality (fast) + lowlatency low latency (faster) + ultralowlatency ultra low latency (fastest) + ======================= =========== **Default** - ``balanced`` + ``ultralowlatency`` **Example** .. code-block:: text - amd_quality = balanced + amd_usage = ultralowlatency `amd_rc `__ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1508,6 +1516,11 @@ keybindings .. note:: This option only applies when using amdvce `encoder`_. + .. warning:: The 'vbr_latency' option generally works best, but + some bitrate overshoots may still occur. Enabling HRD allows + all bitrate based rate controls to better constrain peak bitrate, + but may result in encoding artifacts depending on your card. + **Choices** .. table:: @@ -1523,81 +1536,98 @@ keybindings =========== =========== **Default** - ``cbr`` + ``vbr_latency`` **Example** .. code-block:: text - amd_rc = cbr + amd_rc = vbr_latency -`amd_usage `__ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`amd_enforce_hrd `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Description** - The encoder usage profile, used to balance latency with encoding quality. + Enable Hypothetical Reference Decoder (HRD) enforcement to help constrain the target bitrate. .. note:: This option only applies when using amdvce `encoder`_. + .. warning:: HRD is known to cause encoding artifacts or negatively affect + encoding quality on certain cards. + **Choices** .. table:: :widths: auto - ======================= =========== - Value Description - ======================= =========== - transcoding transcoding (slowest) - webcam webcam (slow) - lowlatency_high_quality low latency, high quality (fast) - lowlatency low latency (faster) - ultralowlatency ultra low latency (fastest) - ======================= =========== + ======== =========== + Value Description + ======== =========== + enabled enable HRD + disabled disable HRD + ======== =========== **Default** - ``ultralowlatency`` + ``disabled`` **Example** .. code-block:: text - amd_usage = ultralowlatency + amd_enforce_hrd = disabled -`amd_preanalysis `__ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`amd_quality `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Description** - Preanalysis can increase encoding quality at the cost of latency. + The quality profile controls the tradeoff between + speed and quality of encoding. .. note:: This option only applies when using amdvce `encoder`_. +**Choices** + +.. table:: + :widths: auto + + ========== =========== + Value Description + ========== =========== + speed prefer speed + balanced balanced + quality prefer quality + ========== =========== + **Default** - ``disabled`` + ``balanced`` **Example** .. code-block:: text - amd_preanalysis = disabled + amd_quality = balanced -`amd_vbaq `__ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +`amd_preanalysis `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Description** - Variance Based Adaptive Quantization (VBAQ) can increase subjective visual quality. + Preanalysis can increase encoding quality at the cost of latency. .. note:: This option only applies when using amdvce `encoder`_. **Default** - ``enabled`` + ``disabled`` **Example** .. code-block:: text - amd_vbaq = enabled + amd_preanalysis = disabled -`amd_enforce_hrd `__ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`amd_vbaq `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Description** - Enable Hypothetical Reference Decoder (HRD) enforcement to help constrain the target bitrate. + Variance Based Adaptive Quantization (VBAQ) can increase subjective + visual quality by prioritizing allocation of more bits to smooth + areas compared to more textured areas. .. note:: This option only applies when using amdvce `encoder`_. @@ -1607,7 +1637,7 @@ keybindings **Example** .. code-block:: text - amd_enforce_hrd = enabled + amd_vbaq = enabled `amd_coder `__ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/config.cpp b/src/config.cpp index ab6dbfb5c37..40f8d065a81 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -124,24 +124,24 @@ namespace config { }; enum class rc_av1_e : int { + cbr = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR, cqp = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP, vbr_latency = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR, - vbr_peak = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR, - cbr = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR + vbr_peak = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }; enum class rc_hevc_e : int { + cbr = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR, cqp = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP, vbr_latency = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR, - vbr_peak = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR, - cbr = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR + vbr_peak = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }; enum class rc_h264_e : int { + cbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR, cqp = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP, vbr_latency = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR, - vbr_peak = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR, - cbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR + vbr_peak = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }; enum class usage_av1_e : int { @@ -176,41 +176,41 @@ namespace config { template std::optional - quality_from_view(const std::string_view &quality_type) { + quality_from_view(const std::string_view &quality_type, const std::optional(&original)) { #define _CONVERT_(x) \ if (quality_type == #x##sv) return (int) T::x + _CONVERT_(balanced); _CONVERT_(quality); _CONVERT_(speed); - _CONVERT_(balanced); #undef _CONVERT_ - return std::nullopt; + return original; } template std::optional - rc_from_view(const std::string_view &rc) { + rc_from_view(const std::string_view &rc, const std::optional(&original)) { #define _CONVERT_(x) \ if (rc == #x##sv) return (int) T::x + _CONVERT_(cbr); _CONVERT_(cqp); _CONVERT_(vbr_latency); _CONVERT_(vbr_peak); - _CONVERT_(cbr); #undef _CONVERT_ - return std::nullopt; + return original; } template std::optional - usage_from_view(const std::string_view &usage) { + usage_from_view(const std::string_view &usage, const std::optional(&original)) { #define _CONVERT_(x) \ if (usage == #x##sv) return (int) T::x - _CONVERT_(transcoding); - _CONVERT_(webcam); _CONVERT_(lowlatency); _CONVERT_(lowlatency_high_quality); + _CONVERT_(transcoding); _CONVERT_(ultralowlatency); + _CONVERT_(webcam); #undef _CONVERT_ - return std::nullopt; + return original; } int @@ -219,7 +219,7 @@ namespace config { if (coder == "cabac"sv || coder == "ac"sv) return cabac; if (coder == "cavlc"sv || coder == "vlc"sv) return cavlc; - return -1; + return _auto; } } // namespace amd @@ -350,18 +350,18 @@ namespace config { }, // qsv { - (int) amd::quality_h264_e::balanced, // quality (h264) - (int) amd::quality_hevc_e::balanced, // quality (hevc) - (int) amd::quality_av1_e::balanced, // quality (av1) - (int) amd::rc_h264_e::cbr, // rate control (h264) - (int) amd::rc_hevc_e::cbr, // rate control (hevc) - (int) amd::rc_av1_e::cbr, // rate control (av1) (int) amd::usage_h264_e::ultralowlatency, // usage (h264) (int) amd::usage_hevc_e::ultralowlatency, // usage (hevc) (int) amd::usage_av1_e::ultralowlatency, // usage (av1) + (int) amd::rc_h264_e::vbr_latency, // rate control (h264) + (int) amd::rc_hevc_e::vbr_latency, // rate control (hevc) + (int) amd::rc_av1_e::vbr_latency, // rate control (av1) + 0, // enforce_hrd + (int) amd::quality_h264_e::balanced, // quality (h264) + (int) amd::quality_hevc_e::balanced, // quality (hevc) + (int) amd::quality_av1_e::balanced, // quality (av1) 0, // preanalysis 1, // vbaq - 1, // enforce_hrd (int) amd::coder_e::_auto, // coder }, // amd @@ -982,26 +982,26 @@ namespace config { std::string quality; string_f(vars, "amd_quality", quality); if (!quality.empty()) { - video.amd.amd_quality_h264 = amd::quality_from_view(quality); - video.amd.amd_quality_hevc = amd::quality_from_view(quality); - video.amd.amd_quality_av1 = amd::quality_from_view(quality); + video.amd.amd_quality_h264 = amd::quality_from_view(quality, video.amd.amd_quality_h264); + video.amd.amd_quality_hevc = amd::quality_from_view(quality, video.amd.amd_quality_hevc); + video.amd.amd_quality_av1 = amd::quality_from_view(quality, video.amd.amd_quality_av1); } std::string rc; string_f(vars, "amd_rc", rc); int_f(vars, "amd_coder", video.amd.amd_coder, amd::coder_from_view); if (!rc.empty()) { - video.amd.amd_rc_h264 = amd::rc_from_view(rc); - video.amd.amd_rc_hevc = amd::rc_from_view(rc); - video.amd.amd_rc_av1 = amd::rc_from_view(rc); + video.amd.amd_rc_h264 = amd::rc_from_view(rc, video.amd.amd_rc_h264); + video.amd.amd_rc_hevc = amd::rc_from_view(rc, video.amd.amd_rc_hevc); + video.amd.amd_rc_av1 = amd::rc_from_view(rc, video.amd.amd_rc_av1); } std::string usage; string_f(vars, "amd_usage", usage); if (!usage.empty()) { - video.amd.amd_usage_h264 = amd::usage_from_view(usage); - video.amd.amd_usage_hevc = amd::usage_from_view(usage); - video.amd.amd_usage_av1 = amd::usage_from_view(usage); + video.amd.amd_usage_h264 = amd::usage_from_view(usage, video.amd.amd_usage_h264); + video.amd.amd_usage_hevc = amd::usage_from_view(usage, video.amd.amd_usage_hevc); + video.amd.amd_usage_av1 = amd::usage_from_view(usage, video.amd.amd_usage_av1); } bool_f(vars, "amd_preanalysis", (bool &) video.amd.amd_preanalysis); diff --git a/src/config.h b/src/config.h index 2c85096bac6..55098c0c5a1 100644 --- a/src/config.h +++ b/src/config.h @@ -48,18 +48,18 @@ namespace config { } qsv; struct { - std::optional amd_quality_h264; - std::optional amd_quality_hevc; - std::optional amd_quality_av1; - std::optional amd_rc_h264; - std::optional amd_rc_hevc; - std::optional amd_rc_av1; std::optional amd_usage_h264; std::optional amd_usage_hevc; std::optional amd_usage_av1; + std::optional amd_rc_h264; + std::optional amd_rc_hevc; + std::optional amd_rc_av1; + std::optional amd_enforce_hrd; + std::optional amd_quality_h264; + std::optional amd_quality_hevc; + std::optional amd_quality_av1; std::optional amd_preanalysis; std::optional amd_vbaq; - std::optional amd_enforce_hrd; int amd_coder; } amd; diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index a48e4a41404..869b2417846 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -875,74 +875,113 @@

- -
- - -
- - -
- - -
-
+
{{ $t('config.amd_usage_desc') }}
- -
- - -
+ +
+
+

+ +

+
+
+ +
+ + +
{{ $t('config.amd_rc_desc') }}
+
- -
- - + +
+ + +
{{ $t('config.amd_enforce_hrd_desc') }}
+
+
+
+
- -
- - -
+ +
+
+

+ +

+
+
+ +
+ + +
{{ $t('config.amd_quality_desc') }}
+
- -
- - + +
+ + +
{{ $t('config.amd_preanalysis_desc') }}
+
+ + +
+ + +
{{ $t('config.amd_vbaq_desc') }}
+
+ + +
+ + +
{{ $t('config.amd_coder_desc') }}
+
+
+
+
@@ -1156,12 +1195,12 @@

id: "amd", name: "AMD AMF Encoder", options: { - "amd_quality": "balanced", - "amd_rc": "cbr", "amd_usage": "ultralowlatency", + "amd_rc": "vbr_latency", + "amd_enforce_hrd": "disabled", + "amd_quality": "balanced", "amd_preanalysis": "disabled", "amd_vbaq": "enabled", - "amd_enforce_hrd": "enabled", "amd_coder": "auto", }, }, 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 f36b984c24e..4a56b2d659a 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -92,24 +92,33 @@ "always_send_scancodes": "Always Send Scancodes", "always_send_scancodes_desc": "Sending scancodes enhances compatibility with games and apps but may result in incorrect keyboard input from certain clients that aren't using a US English keyboard layout. Enable if keyboard input is not working at all in certain applications. Disable if keys on the client are generating the wrong input on the host.", "amd_coder": "AMF Coder (H264)", + "amd_coder_desc": "Allows you to select the entropy encoding to prioritize quality or encoding speed. H.264 only.", "amd_enforce_hrd": "AMF Hypothetical Reference Decoder (HRD) Enforcement", + "amd_enforce_hrd_desc": "Increases the constraints on rate control to meet HRD model requirements. This greatly reduces bitrate overflows, but may cause encoding artifacts or reduced quality on certain cards.", "amd_preanalysis": "AMF Preanalysis", + "amd_preanalysis_desc": "This enables rate-control preanalysis, which may increase quality at the expense of increased encoding latency.", "amd_quality": "AMF Quality", "amd_quality_balanced": "balanced -- balanced (default)", + "amd_quality_desc": "This controls the balance between encoding speed and quality.", + "amd_quality_group" : "AMF Quality Settings", "amd_quality_quality": "quality -- prefer quality", "amd_quality_speed": "speed -- prefer speed", "amd_rc": "AMF Rate Control", - "amd_rc_cbr": "cbr -- constant bitrate (default)", + "amd_rc_cbr": "cbr -- constant bitrate (recommended if HRD is enabled)", "amd_rc_cqp": "cqp -- constant qp mode", - "amd_rc_vbr_latency": "vbr_latency -- latency constrained variable bitrate", + "amd_rc_desc": "This controls the rate control method to ensure we are not exceeding the client bitrate target. 'cqp' is not suitable for bitrate targeting, and other options besides 'vbr_latency' depend on HRD Enforcement to help constrain bitrate overflows.", + "amd_rc_group" : "AMF Rate Control Settings", + "amd_rc_vbr_latency": "vbr_latency -- latency constrained variable bitrate (recommended if HRD is disabled; default)", "amd_rc_vbr_peak": "vbr_peak -- peak constrained variable bitrate", "amd_usage": "AMF Usage", + "amd_usage_desc": "This sets the base encoding profile. All options presented below will override a subset of the usage profile, but there are additional hidden settings applied that cannot be configured elsewhere.", "amd_usage_lowlatency": "lowlatency - low latency (fastest)", "amd_usage_lowlatency_high_quality": "lowlatency_high_quality - low latency, high quality (fast)", "amd_usage_transcoding": "transcoding -- transcoding (slowest)", - "amd_usage_ultralowlatency": "ultralowlatency - ultra low latency (fastest)", + "amd_usage_ultralowlatency": "ultralowlatency - ultra low latency (fastest; default)", "amd_usage_webcam": "webcam -- webcam (slow)", "amd_vbaq": "AMF Variance Based Adaptive Quantization (VBAQ)", + "amd_vbaq_desc": "The human visual system is typically less sensitive to artifacts in highly textured areas. In VBAQ mode, pixel variance is used to indicate the complexity of spatial textures, allowing the encoder to allocate more bits to smoother areas. Enabling this feature leads to improvements in subjective visual quality with some content.", "apply_note": "Click 'Apply' to restart Sunshine and apply changes. This will terminate any running sessions.", "audio_sink": "Audio Sink", "audio_sink_desc_linux": "The name of the audio sink used for Audio Loopback. If you do not specify this variable, pulseaudio will select the default monitor device. You can find the name of the audio sink using either command:",