From ffd0bbb1ab4fc80fd01758ffd79b3cf100d02c9c Mon Sep 17 00:00:00 2001 From: brittneysclark Date: Sat, 21 Sep 2019 04:53:21 -0700 Subject: [PATCH] obs-qsv11: Enable option for Custom Quantization Matrix Add the option to enable custom quantization matrix for game streaming on ICL for better subject quality. Feature is only supported with AVC high profile, so added function to detect when QSV profile is modified and hide or show CQM UI option accordingly. Also, increase SPS/PPS buffer sizes since matrix is stored in SPS/PPS. --- plugins/obs-qsv11/QSV_Encoder.h | 1 + plugins/obs-qsv11/QSV_Encoder_Internal.cpp | 20 +++++++++++++++----- plugins/obs-qsv11/QSV_Encoder_Internal.h | 5 +++-- plugins/obs-qsv11/obs-qsv11.c | 18 ++++++++++++++++++ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/plugins/obs-qsv11/QSV_Encoder.h b/plugins/obs-qsv11/QSV_Encoder.h index 865a954fc..0fa4dfb7f 100644 --- a/plugins/obs-qsv11/QSV_Encoder.h +++ b/plugins/obs-qsv11/QSV_Encoder.h @@ -101,6 +101,7 @@ typedef struct { mfxU16 nbFrames; mfxU16 nICQQuality; bool bMBBRC; + bool bCQM; } qsv_param_t; enum qsv_cpu_platform { diff --git a/plugins/obs-qsv11/QSV_Encoder_Internal.cpp b/plugins/obs-qsv11/QSV_Encoder_Internal.cpp index 8e808db52..5631afb17 100644 --- a/plugins/obs-qsv11/QSV_Encoder_Internal.cpp +++ b/plugins/obs-qsv11/QSV_Encoder_Internal.cpp @@ -74,8 +74,8 @@ mfxU16 QSV_Encoder_Internal::g_numEncodersOpen = 0; QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL &impl, mfxVersion &version) : m_pmfxSurfaces(NULL), m_pmfxENC(NULL), - m_nSPSBufferSize(100), - m_nPPSBufferSize(100), + m_nSPSBufferSize(1024), + m_nPPSBufferSize(1024), m_nTaskPool(0), m_pTaskPool(NULL), m_nTaskIdx(0), @@ -253,7 +253,7 @@ bool QSV_Encoder_Internal::InitParams(qsv_param_t *pParams) (mfxU16)(pParams->nKeyIntSec * pParams->nFpsNum / (float)pParams->nFpsDen); - static mfxExtBuffer *extendedBuffers[2]; + static mfxExtBuffer *extendedBuffers[3]; int iBuffers = 0; if (m_ver.Major == 1 && m_ver.Minor >= 8) { @@ -270,6 +270,16 @@ bool QSV_Encoder_Internal::InitParams(qsv_param_t *pParams) extendedBuffers[iBuffers++] = (mfxExtBuffer *)&m_co2; } + if (pParams->bCQM) { + if (m_ver.Major == 1 && m_ver.Minor >= 16) { + memset(&m_co3, 0, sizeof(mfxExtCodingOption3)); + m_co3.Header.BufferId = MFX_EXTBUFF_CODING_OPTION3; + m_co3.Header.BufferSz = sizeof(m_co3); + m_co3.ScenarioInfo = 7; // MFX_SCENARIO_GAME_STREAMING + extendedBuffers[iBuffers++] = (mfxExtBuffer *)&m_co3; + } + } + if (iBuffers > 0) { m_mfxEncParams.ExtParam = extendedBuffers; m_mfxEncParams.NumExtParam = (mfxU16)iBuffers; @@ -365,8 +375,8 @@ mfxStatus QSV_Encoder_Internal::GetVideoParam() opt.SPSBuffer = m_SPSBuffer; opt.PPSBuffer = m_PPSBuffer; - opt.SPSBufSize = 100; // m_nSPSBufferSize; - opt.PPSBufSize = 100; // m_nPPSBufferSize; + opt.SPSBufSize = 1024; // m_nSPSBufferSize; + opt.PPSBufSize = 1024; // m_nPPSBufferSize; mfxStatus sts = m_pmfxENC->GetVideoParam(&m_parameter); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); diff --git a/plugins/obs-qsv11/QSV_Encoder_Internal.h b/plugins/obs-qsv11/QSV_Encoder_Internal.h index b454d4089..7f4a7c98d 100644 --- a/plugins/obs-qsv11/QSV_Encoder_Internal.h +++ b/plugins/obs-qsv11/QSV_Encoder_Internal.h @@ -94,11 +94,12 @@ private: mfxFrameSurface1 **m_pmfxSurfaces; mfxU16 m_nSurfNum; MFXVideoENCODE *m_pmfxENC; - mfxU8 m_SPSBuffer[100]; - mfxU8 m_PPSBuffer[100]; + mfxU8 m_SPSBuffer[1024]; + mfxU8 m_PPSBuffer[1024]; mfxU16 m_nSPSBufferSize; mfxU16 m_nPPSBufferSize; mfxVideoParam m_parameter; + mfxExtCodingOption3 m_co3; mfxExtCodingOption2 m_co2; mfxExtCodingOption m_co; mfxU16 m_nTaskPool; diff --git a/plugins/obs-qsv11/obs-qsv11.c b/plugins/obs-qsv11/obs-qsv11.c index c89c21dc4..dba561609 100644 --- a/plugins/obs-qsv11/obs-qsv11.c +++ b/plugins/obs-qsv11/obs-qsv11.c @@ -240,6 +240,18 @@ static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p, return true; } +static bool profile_modified(obs_properties_t *ppts, obs_property_t *p, + obs_data_t *settings) +{ + const char *profile = obs_data_get_string(settings, "profile"); + enum qsv_cpu_platform plat = qsv_get_cpu_platform(); + bool bVisible = ((astrcmpi(profile, "high") == 0) && + (plat >= QSV_CPU_PLATFORM_ICL)); + p = obs_properties_get(ppts, "CQM"); + obs_property_set_visible(p, bVisible); + return true; +} + static inline void add_rate_controls(obs_property_t *list, const struct qsv_rate_control_info *rc) { @@ -268,6 +280,8 @@ static obs_properties_t *obs_qsv_props(void *unused) OBS_COMBO_FORMAT_STRING); add_strings(list, qsv_profile_names); + obs_property_set_modified_callback(list, profile_modified); + obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 1, 20, 1); obs_properties_add_int(props, "async_depth", TEXT_ASYNC_DEPTH, 1, 7, 1); @@ -300,6 +314,8 @@ static obs_properties_t *obs_qsv_props(void *unused) if (is_skl_or_greater_platform()) obs_properties_add_bool(props, "mbbrc", TEXT_MBBRC); + obs_properties_add_bool(props, "CQM", "Customized quantization matrix"); + return props; } @@ -437,6 +453,8 @@ static void update_params(struct obs_qsv *obsqsv, obs_data_t *settings) "\theight: %d", voi->fps_num, voi->fps_den, width, height); + obsqsv->params.bCQM = (bool)obs_data_get_bool(settings, "CQM"); + info("debug info:"); }