diff --git a/docs/source/about/advanced_usage.rst b/docs/source/about/advanced_usage.rst index 1c3a0f64c56..f9255b9b6b8 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,9 @@ keybindings .. note:: This option only applies when using amdvce `encoder`_. + .. warning:: the default rate control when 'auto' is selected + varies depending on the `amd_enforce_hrd`_ blacklist. + **Choices** .. table:: @@ -1516,6 +1527,7 @@ keybindings =========== =========== Value Description =========== =========== + auto cbr, or vbr_latency if HRD is blacklisted cqp constant qp mode cbr constant bitrate vbr_latency variable bitrate, latency constrained @@ -1523,81 +1535,101 @@ keybindings =========== =========== **Default** - ``cbr`` + ``auto`` **Example** .. code-block:: text - amd_rc = cbr + amd_rc = auto -`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:: 'auto' will disable HRD if Sunshine detects a Polaris card that is + known to exhibit artifacts. If you experience encoding issues on 'auto' that can be + resolved by disabling HRD explicitly, please file an issue so that your card's + Device ID can be added to the blacklist in future releases. + **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 + ======== =========== + auto enable HRD if card is not blacklisted + enabled enable HRD + disabled disable HRD + ======== =========== **Default** - ``ultralowlatency`` + ``auto`` **Example** .. code-block:: text - amd_usage = ultralowlatency + amd_enforce_hrd = auto -`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 +1639,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..d7e7a419181 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -124,24 +124,27 @@ namespace config { }; enum class rc_av1_e : int { + _auto = -1, + 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 { + _auto = -1, + 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 { + _auto = -1, + 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 { @@ -168,6 +171,12 @@ namespace config { ultralowlatency = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }; + enum class enforce_hrd_e : int { + disabled = 0, + enabled, + _auto + }; + enum coder_e : int { _auto = AMF_VIDEO_ENCODER_UNDEFINED, cabac = AMF_VIDEO_ENCODER_CABAC, @@ -176,41 +185,54 @@ 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_(_auto); + _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; + } + + template + std::optional + enforce_hrd_from_view(const std::string_view &enforce_hrd, const std::optional(&original)) { +#define _CONVERT_(x) \ + if (enforce_hrd == #x##sv) return (int) T::x + _CONVERT_(_auto); + _CONVERT_(disabled); + _CONVERT_(enabled); +#undef _CONVERT_ + return original; } int @@ -219,7 +241,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 +372,21 @@ 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::_auto, // rate control (h264) + (int) amd::rc_hevc_e::_auto, // rate control (hevc) + (int) amd::rc_av1_e::_auto, // rate control (av1) + (int) amd::rc_h264_e::vbr_latency, // fallback rate control (h264) + (int) amd::rc_hevc_e::vbr_latency, // fallback rate control (hevc) + (int) amd::rc_av1_e::vbr_latency, // fallback rate control (av1) + (int) amd::enforce_hrd_e::_auto, // 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,31 +1007,36 @@ 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); + } + + std::string enforce_hrd; + string_f(vars, "amd_enforce_hrd", enforce_hrd); + if (!enforce_hrd.empty()) { + video.amd.amd_enforce_hrd = amd::enforce_hrd_from_view(enforce_hrd, video.amd.amd_enforce_hrd); } bool_f(vars, "amd_preanalysis", (bool &) video.amd.amd_preanalysis); bool_f(vars, "amd_vbaq", (bool &) video.amd.amd_vbaq); - bool_f(vars, "amd_enforce_hrd", (bool &) video.amd.amd_enforce_hrd); + int_f(vars, "amd_coder", video.amd.amd_coder, amd::coder_from_view); int_f(vars, "vt_coder", video.vt.vt_coder, vt::coder_from_view); int_f(vars, "vt_software", video.vt.vt_allow_sw, vt::allow_software_from_view); diff --git a/src/config.h b/src/config.h index 2c85096bac6..813646f09cc 100644 --- a/src/config.h +++ b/src/config.h @@ -48,18 +48,21 @@ 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_rc_h264_fallback; + std::optional amd_rc_hevc_fallback; + std::optional amd_rc_av1_fallback; + 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/platform/windows/display_vram.cpp b/src/platform/windows/display_vram.cpp index 4aa1800ba45..c942b759bc3 100644 --- a/src/platform/windows/display_vram.cpp +++ b/src/platform/windows/display_vram.cpp @@ -1552,6 +1552,35 @@ namespace platf::dxgi { return false; } + // Polaris cards cause artifacts when HRD enforcement is enabled. + std::vector hrd_blacklist_ids = { + 0x67C0, // Polaris_10 + 0x67C2, // Polaris_10 + 0x67C4, // Polaris_10 + 0x67C7, // Polaris_10 + 0x67DF, // Polaris_10 + 0x67E0, // Polaris_11 + 0x67E3, // Polaris_11 + 0x67E8, // Polaris_11 + 0x67EB, // Polaris_11 + 0x67EF, // Polaris_11 + 0x67FF, // Polaris_11 + 0x6981, // Polaris_12 + 0x6985, // Polaris_12 + 0x6987, // Polaris_12 + 0x6995, // Polaris_12 + 0x699F, // Polaris_12 + 0x6FDF // Polaris_10 + }; + + for (uint32_t id : hrd_blacklist_ids) { + if (adapter_desc.DeviceId == id) { + BOOST_LOG(warning) << "AMF HRD Enforcement: Device ID " << util::hex(id).to_string_view() << " found on blacklist."; + ::video::amd_hrd_blacklist = true; + break; + } + } + // Perform AMF version checks if we're using an AMD GPU. This check is placed in display_vram_t // to avoid hitting the display_ram_t path which uses software encoding and doesn't touch AMF. HMODULE amfrt = LoadLibraryW(AMF_DLL_NAME); diff --git a/src/video.cpp b/src/video.cpp index 6c1938c2849..ffcc059713a 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -670,9 +670,9 @@ namespace video { { "log_to_dbg"s, []() { return config::sunshine.min_log_level < 2 ? 1 : 0; } }, { "preencode"s, &config::video.amd.amd_preanalysis }, { "quality"s, &config::video.amd.amd_quality_av1 }, - { "rc"s, &config::video.amd.amd_rc_av1 }, + { "rc"s, []() { int ret = config::video.amd.amd_rc_av1.value(); return ret == -1 && amd_hrd_blacklist ? config::video.amd.amd_rc_av1_fallback.value() : ret == -1 ? 3 /* CBR */ : ret; } }, { "usage"s, &config::video.amd.amd_usage_av1 }, - { "enforce_hrd"s, &config::video.amd.amd_enforce_hrd }, + { "enforce_hrd"s, []() { int ret = config::video.amd.amd_enforce_hrd.value(); return ret < 2 ? ret : !amd_hrd_blacklist; } }, }, {}, // SDR-specific options {}, // HDR-specific options @@ -691,10 +691,10 @@ namespace video { { "qmax"s, 51 }, { "qmin"s, 0 }, { "quality"s, &config::video.amd.amd_quality_hevc }, - { "rc"s, &config::video.amd.amd_rc_hevc }, + { "rc"s, []() { int ret = config::video.amd.amd_rc_hevc.value(); return ret == -1 && amd_hrd_blacklist ? config::video.amd.amd_rc_hevc_fallback.value() : ret == -1 ? 3 /* CBR */ : ret; } }, { "usage"s, &config::video.amd.amd_usage_hevc }, { "vbaq"s, &config::video.amd.amd_vbaq }, - { "enforce_hrd"s, &config::video.amd.amd_enforce_hrd }, + { "enforce_hrd"s, []() { int ret = config::video.amd.amd_enforce_hrd.value(); return ret < 2 ? ret : !amd_hrd_blacklist; } }, }, {}, // SDR-specific options {}, // HDR-specific options @@ -711,10 +711,10 @@ namespace video { { "qmax"s, 51 }, { "qmin"s, 0 }, { "quality"s, &config::video.amd.amd_quality_h264 }, - { "rc"s, &config::video.amd.amd_rc_h264 }, + { "rc"s, []() { int ret = config::video.amd.amd_rc_h264.value(); return ret == -1 && amd_hrd_blacklist ? config::video.amd.amd_rc_h264_fallback.value() : ret == -1 ? 1 /* CBR */ : ret; } }, { "usage"s, &config::video.amd.amd_usage_h264 }, { "vbaq"s, &config::video.amd.amd_vbaq }, - { "enforce_hrd"s, &config::video.amd.amd_enforce_hrd }, + { "enforce_hrd"s, []() { int ret = config::video.amd.amd_enforce_hrd.value(); return ret < 2 ? ret : !amd_hrd_blacklist; } }, }, // SDR-specific options {}, @@ -937,6 +937,7 @@ namespace video { static encoder_t *chosen_encoder; int active_hevc_mode; int active_av1_mode; + bool amd_hrd_blacklist = false; bool last_encoder_probe_supported_ref_frames_invalidation = false; void diff --git a/src/video.h b/src/video.h index eb8eabc358d..793248f5e95 100644 --- a/src/video.h +++ b/src/video.h @@ -316,6 +316,7 @@ namespace video { extern int active_hevc_mode; extern int active_av1_mode; + extern bool amd_hrd_blacklist; extern bool last_encoder_probe_supported_ref_frames_invalidation; void diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index a48e4a41404..be728370e99 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -875,74 +875,115 @@

- -
- - -
- - -
- - -
-
+
{{ $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 +1197,12 @@

id: "amd", name: "AMD AMF Encoder", options: { - "amd_quality": "balanced", - "amd_rc": "cbr", "amd_usage": "ultralowlatency", + "amd_rc": "auto", + "amd_enforce_hrd": "auto", + "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 6fa1f3a04c4..f539c79720c 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,35 @@ "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_auto": "Autodetect -- disabled on Polaris cards, otherwise enabled", + "amd_enforce_hrd_desc": "Increases the constraints on rate control to meet HRD model requirements. This greatly reduces bitrate overflows, but is blacklisted on Polaris cards via the 'auto' setting due to encoding artifacts. If the 'auto' setting causes issues on your system, please refer to the documentation on this option regarding the HRD blacklist.", "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_auto": "Autodetect -- 'vbr_latency' on Polaris cards, otherwise 'cbr' (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 require HRD Enforcement to help constrain bitrate overflows. Defaults to 'cbr', or 'vbr_latency' if HRD is blacklisted.", + "amd_rc_group" : "AMF Rate Control Settings", + "amd_rc_vbr_latency": "vbr_latency -- latency constrained variable bitrate (recommended if HRD is disabled)", "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:", @@ -148,7 +159,7 @@ "external_ip_desc": "If no external IP address is given, Sunshine will automatically detect external IP", "fec_percentage": "FEC Percentage", "fec_percentage_desc": "Percentage of error correcting packets per data packet in each video frame. Higher values can correct for more network packet loss, but at the cost of increasing bandwidth usage.", - "ffmpeg_auto": "auto -- let ffmpeg decide (default)", + "ffmpeg_auto": "Autodetect -- let ffmpeg decide (default)", "file_apps": "Apps File", "file_apps_desc": "The file where current apps of Sunshine are stored.", "file_state": "State File",