diff --git a/src/config.cpp b/src/config.cpp index 6892e3029..33e0d37a7 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -490,6 +490,9 @@ namespace config { { false, // strict_rc_buffer + -1, // h264_quality (driver default; AMD vendor receives 0 below) + -1, // hevc_quality + -1, // av1_quality }, // vaapi {}, // capture @@ -1176,6 +1179,9 @@ namespace config { 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); + int_f(vars, "vaapi_h264_quality", video.vaapi.h264_quality); + int_f(vars, "vaapi_hevc_quality", video.vaapi.hevc_quality); + int_f(vars, "vaapi_av1_quality", video.vaapi.av1_quality); string_f(vars, "capture", video.capture); string_f(vars, "encoder", video.encoder); diff --git a/src/config.h b/src/config.h index a6d7c8338..1ceb45877 100644 --- a/src/config.h +++ b/src/config.h @@ -81,6 +81,9 @@ namespace config { struct { bool strict_rc_buffer; + int h264_quality; ///< VAAPI ffmpeg -quality preset (h264). -1 = driver default; on AMD, 0 = best, higher = faster. + int hevc_quality; ///< VAAPI ffmpeg -quality preset (hevc). -1 = driver default; on AMD, 0 = best, higher = faster. + int av1_quality; ///< VAAPI ffmpeg -quality preset (av1). -1 = driver default; on AMD, 0 = best, higher = faster. } vaapi; std::string capture; diff --git a/src/platform/linux/vaapi.cpp b/src/platform/linux/vaapi.cpp index adaa07075..04b3de96a 100644 --- a/src/platform/linux/vaapi.cpp +++ b/src/platform/linux/vaapi.cpp @@ -239,6 +239,26 @@ namespace va { BOOST_LOG(info) << "Using normal encoding mode"sv; } + // Apply VAAPI quality preset. ffmpeg's -quality knob is "higher = faster". + // On AMD VCN the slowest preset (0) is still well under typical frame budgets + // even at 4K, so default to best image quality for AMD when the user hasn't + // overridden it. Other vendors (Intel iHD, etc.) receive driver default. + int quality = -1; + if (ctx->codec_id == AV_CODEC_ID_HEVC) { + quality = config::video.vaapi.hevc_quality; + } else if (ctx->codec_id == AV_CODEC_ID_H264) { + quality = config::video.vaapi.h264_quality; + } else if (ctx->codec_id == AV_CODEC_ID_AV1) { + quality = config::video.vaapi.av1_quality; + } + if (quality < 0 && vendor && strstr(vendor, "AMD")) { + quality = 0; + } + if (quality >= 0) { + BOOST_LOG(info) << "Using VAAPI quality preset: "sv << quality; + av_dict_set_int(options, "quality", quality, 0); + } + VAConfigAttrib rc_attr = {VAConfigAttribRateControl}; auto status = vaGetConfigAttributes(va_display, va_profile, va_entrypoint, &rc_attr, 1); if (status != VA_STATUS_SUCCESS) {