From c4c88b02428cb5b4dc8b124b6dd30c015f8b8a08 Mon Sep 17 00:00:00 2001 From: gfxVPLsdm Date: Tue, 11 Jun 2024 07:02:05 +0800 Subject: [PATCH] Refine for commit e0b981d (#6903) --- .../av1/agnostic/base/av1ehw_base_data.h | 5 + .../av1/agnostic/base/av1ehw_base_general.cpp | 100 ++++++++++++++++-- .../linux/base/av1ehw_base_va_packer_lin.cpp | 6 ++ 3 files changed, 105 insertions(+), 6 deletions(-) diff --git a/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_data.h b/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_data.h index 28893ac887..b01c61ba64 100644 --- a/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_data.h +++ b/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_data.h @@ -840,6 +840,11 @@ namespace Base mfxI32 PrevRAP = -1; mfxU16 NumRecode = 0; mfxU8 QpY = 0; + mfxI8 YDcDeltaQ = 0; + mfxI8 UDcDeltaQ = 0; + mfxI8 UAcDeltaQ = 0; + mfxI8 VDcDeltaQ = 0; + mfxI8 VAcDeltaQ = 0; mfxU32 InsertHeaders = 0; mfxU32 StatusReportId = mfxU32(-1); DpbRefreshType RefreshFrameFlags = {}; diff --git a/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_general.cpp b/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_general.cpp index 143c0b3d64..5d05e70810 100644 --- a/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_general.cpp +++ b/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_general.cpp @@ -588,12 +588,6 @@ void General::Query1WithCaps(const FeatureBlocks& /*blocks*/, TPushQ1 Push) return CheckTU(out, m_pQWCDefaults->caps); }); - Push(BLK_CheckDeltaQ - , [this](const mfxVideoParam&, mfxVideoParam& out, StorageW&) -> mfxStatus - { - return CheckDeltaQ(out); - }); - Push(BLK_CheckFrameOBU , [this](const mfxVideoParam&, mfxVideoParam& out, StorageW& strg) -> mfxStatus { @@ -675,6 +669,12 @@ void General::Query1WithCaps(const FeatureBlocks& /*blocks*/, TPushQ1 Push) return CheckRateControl(out, *m_pQWCDefaults); }); + Push(BLK_CheckDeltaQ + , [this](const mfxVideoParam&, mfxVideoParam& out, StorageW&) -> mfxStatus + { + return CheckDeltaQ(out); + }); + Push(BLK_CheckCrops , [this](const mfxVideoParam&, mfxVideoParam& out, StorageW&) -> mfxStatus { @@ -2097,6 +2097,56 @@ inline void SetTaskQp( SetIf(task.QpY, !!task.ctrl.QP, static_cast(task.ctrl.QP)); } +inline bool CheckQpInRangeOrClip(mfxI32 qp, mfxI8& delta) +{ + + mfxI32 clipQp = static_cast(delta); + if (qp + delta > 255) + { + clipQp = 255 - qp; + } + else if (qp + delta < 0) + { + clipQp = 0 - qp; + } + else + { + return false; + } + + std::ignore = CheckRangeOrClip(clipQp, -63, 63); + + delta = static_cast(clipQp); + return true; +} + +inline void ClipTaskDeltaQp( + TaskCommonPar& task + ,const mfxVideoParam& par) +{ + if (par.mfx.RateControlMethod != MFX_RATECONTROL_CQP) + { + return; + } + const mfxExtAV1AuxData& auxPar = ExtBuffer::Get(par); + mfxU32 changed = 0; + + task.YDcDeltaQ = auxPar.QP.YDcDeltaQ; + task.UDcDeltaQ = auxPar.QP.UDcDeltaQ; + task.UAcDeltaQ = auxPar.QP.UAcDeltaQ; + task.VDcDeltaQ = auxPar.QP.VDcDeltaQ; + task.VAcDeltaQ = auxPar.QP.VAcDeltaQ; + + changed += CheckQpInRangeOrClip(task.QpY, task.YDcDeltaQ); + changed += CheckQpInRangeOrClip(task.QpY, task.UDcDeltaQ); + changed += CheckQpInRangeOrClip(task.QpY, task.UAcDeltaQ); + changed += CheckQpInRangeOrClip(task.QpY, task.VDcDeltaQ); + changed += CheckQpInRangeOrClip(task.QpY, task.VAcDeltaQ); + + std::ignore = changed; + + return; +} inline void SetTaskBRCParams( TaskCommonPar& task , const mfxVideoParam& par) @@ -2626,6 +2676,7 @@ void General::ConfigureTask( const auto& par = dflts.mvp; SetTaskQp(task, par); + ClipTaskDeltaQp(task, par); SetTaskBRCParams(task, par); SetTaskEncodeOrders(task, m_prevTask); @@ -3693,6 +3744,23 @@ mfxStatus General::CheckTU(mfxVideoParam & par, const ENCODE_CAPS_AV1& /* caps * } +inline mfxStatus FixDeltaQpRange(mfxU16& qp, mfxExtAV1AuxData* pAuxPar) +{ + MFX_CHECK(pAuxPar, MFX_ERR_NULL_PTR); + + mfxU32 changed = 0; + + changed += CheckQpInRangeOrClip(qp, pAuxPar->QP.YDcDeltaQ); + changed += CheckQpInRangeOrClip(qp, pAuxPar->QP.UDcDeltaQ); + changed += CheckQpInRangeOrClip(qp, pAuxPar->QP.UAcDeltaQ); + changed += CheckQpInRangeOrClip(qp, pAuxPar->QP.VDcDeltaQ); + changed += CheckQpInRangeOrClip(qp, pAuxPar->QP.VAcDeltaQ); + + MFX_CHECK(!changed, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM); + + return MFX_ERR_NONE; +} + mfxStatus General::CheckDeltaQ(mfxVideoParam& par) { mfxExtAV1AuxData* pAuxPar = ExtBuffer::Get(par); @@ -3710,6 +3778,20 @@ mfxStatus General::CheckDeltaQ(mfxVideoParam& par) changed += CheckMaxOrClip(pAuxPar->QP.VDcDeltaQ, 63); changed += CheckMinOrClip(pAuxPar->QP.VAcDeltaQ, -63); changed += CheckMaxOrClip(pAuxPar->QP.VAcDeltaQ, 63); + + if (par.mfx.RateControlMethod == MFX_RATECONTROL_CQP) + { + changed += FixDeltaQpRange(par.mfx.QPI, pAuxPar); + if (par.mfx.GopPicSize > 1) + { + changed += FixDeltaQpRange(par.mfx.QPP, pAuxPar); + } + if (par.mfx.GopRefDist > 1) + { + changed += FixDeltaQpRange(par.mfx.QPB, pAuxPar); + } + } + MFX_CHECK(!changed, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM); return MFX_ERR_NONE; @@ -4396,6 +4478,12 @@ mfxStatus General::GetCurrentFrameHeader( currFH.quantization_params.base_q_idx = task.QpY; + currFH.quantization_params.DeltaQYDc = task.YDcDeltaQ; + currFH.quantization_params.DeltaQUDc = task.UDcDeltaQ; + currFH.quantization_params.DeltaQUAc = task.UAcDeltaQ; + currFH.quantization_params.DeltaQVDc = task.VDcDeltaQ; + currFH.quantization_params.DeltaQVAc = task.VAcDeltaQ; + if (IsLossless(currFH)) { currFH.CodedLossless = 1; diff --git a/_studio/mfx_lib/encode_hw/av1/linux/base/av1ehw_base_va_packer_lin.cpp b/_studio/mfx_lib/encode_hw/av1/linux/base/av1ehw_base_va_packer_lin.cpp index 8c5074136d..b9d0f8c8f2 100644 --- a/_studio/mfx_lib/encode_hw/av1/linux/base/av1ehw_base_va_packer_lin.cpp +++ b/_studio/mfx_lib/encode_hw/av1/linux/base/av1ehw_base_va_packer_lin.cpp @@ -364,6 +364,12 @@ void UpdatePPS( pps.min_base_qindex = task.MinBaseQIndex; pps.max_base_qindex = task.MaxBaseQIndex; + pps.y_dc_delta_q = task.YDcDeltaQ; + pps.u_dc_delta_q = task.UDcDeltaQ; + pps.u_ac_delta_q = task.UAcDeltaQ; + pps.v_dc_delta_q = task.VDcDeltaQ; + pps.v_ac_delta_q = task.VAcDeltaQ; + pps.order_hint = static_cast(bs_fh.order_hint); //DPB and refs management