From 9f4f2e975473e4ad3cf725196d8f9b1013b67aec Mon Sep 17 00:00:00 2001 From: "Gale, Thy-Lan" Date: Tue, 11 Jun 2024 15:30:39 -0700 Subject: [PATCH] obs-qsv11: Fix CBR Spike --- plugins/obs-qsv11/QSV_Encoder_Internal.cpp | 50 ++++++++++++++++++++-- plugins/obs-qsv11/QSV_Encoder_Internal.h | 1 + 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/plugins/obs-qsv11/QSV_Encoder_Internal.cpp b/plugins/obs-qsv11/QSV_Encoder_Internal.cpp index 695d84ef5..a90af811f 100644 --- a/plugins/obs-qsv11/QSV_Encoder_Internal.cpp +++ b/plugins/obs-qsv11/QSV_Encoder_Internal.cpp @@ -177,6 +177,26 @@ mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams, enum qsv_codec codec) return sts; } +PRAGMA_WARN_PUSH +PRAGMA_WARN_DEPRECATION +static inline bool HasOptimizedBRCSupport(const mfxPlatform &platform, + const mfxVersion &version, + mfxU16 rateControl) +{ +#if (MFX_VERSION_MAJOR >= 2 && MFX_VERSION_MINOR >= 12) || MFX_VERSION_MAJOR > 2 + if ((version.Major >= 2 && version.Minor >= 12) || version.Major > 2) + if (rateControl == MFX_RATECONTROL_CBR && + (platform.CodeName >= MFX_PLATFORM_LUNARLAKE && + platform.CodeName != MFX_PLATFORM_ALDERLAKE_N)) + return true; +#endif + UNUSED_PARAMETER(platform); + UNUSED_PARAMETER(version); + UNUSED_PARAMETER(rateControl); + return false; +} +PRAGMA_WARN_POP + mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams, enum qsv_codec codec) { @@ -233,10 +253,18 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams, switch (pParams->nRateControl) { case MFX_RATECONTROL_CBR: m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate; - m_mfxEncParams.mfx.BufferSizeInKB = - (pParams->nTargetBitRate / 8) * 2; + + if (HasOptimizedBRCSupport(platform, m_ver, + pParams->nRateControl)) { + m_mfxEncParams.mfx.BufferSizeInKB = + (pParams->nTargetBitRate / 8) * 1; + } else { + m_mfxEncParams.mfx.BufferSizeInKB = + (pParams->nTargetBitRate / 8) * 2; + } + m_mfxEncParams.mfx.InitialDelayInKB = - (pParams->nTargetBitRate / 8) * 1; + m_mfxEncParams.mfx.BufferSizeInKB / 2; break; case MFX_RATECONTROL_VBR: m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate; @@ -304,6 +332,22 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams, extendedBuffers.push_back((mfxExtBuffer *)&m_co2); + if (HasOptimizedBRCSupport(platform, m_ver, pParams->nRateControl)) { + memset(&m_co3, 0, sizeof(mfxExtCodingOption3)); + m_co3.Header.BufferId = MFX_EXTBUFF_CODING_OPTION3; + m_co3.Header.BufferSz = sizeof(m_co3); + m_co3.WinBRCSize = pParams->nFpsNum / pParams->nFpsDen; + + if (codec == QSV_CODEC_AVC || codec == QSV_CODEC_HEVC) { + m_co3.WinBRCMaxAvgKbps = + mfxU16(1.3 * pParams->nTargetBitRate); + } else if (codec == QSV_CODEC_AV1) { + m_co3.WinBRCMaxAvgKbps = + mfxU16(1.2 * pParams->nTargetBitRate); + } + extendedBuffers.push_back((mfxExtBuffer *)&m_co3); + } + if (codec == QSV_CODEC_HEVC) { if ((pParams->nWidth & 15) || (pParams->nHeight & 15)) { memset(&m_ExtHEVCParam, 0, sizeof(m_ExtHEVCParam)); diff --git a/plugins/obs-qsv11/QSV_Encoder_Internal.h b/plugins/obs-qsv11/QSV_Encoder_Internal.h index 59c078ca9..478f0b87a 100644 --- a/plugins/obs-qsv11/QSV_Encoder_Internal.h +++ b/plugins/obs-qsv11/QSV_Encoder_Internal.h @@ -116,6 +116,7 @@ private: mfxU16 m_nPPSBufferSize; mfxVideoParam m_parameter; std::vector extendedBuffers; + mfxExtCodingOption3 m_co3; mfxExtCodingOption2 m_co2; mfxExtCodingOption m_co; mfxExtHEVCParam m_ExtHEVCParam{};