From fc59056b3bbc68496de80df0b9a6db7c0e37daf5 Mon Sep 17 00:00:00 2001 From: Zhijie Zhang Date: Wed, 7 Sep 2022 14:49:14 +0800 Subject: [PATCH] Revert "[Enctools] Adds new LA Models for higher compression efficiency (#3455)" This reverts commit 1dd3730375615449e460559f2eec23944ead20f4. --- _studio/enctools/aenc/include/aenc.h | 4 +- _studio/enctools/include/mfx_enctools_brc.h | 5 +- _studio/enctools/src/mfx_enctools_aenc.cpp | 3 +- _studio/enctools/src/mfx_enctools_brc.cpp | 55 +++++------------- .../av1/agnostic/base/av1ehw_base_data.h | 3 +- .../agnostic/base/av1ehw_base_enctools.cpp | 2 - .../h264/include/mfx_h264_encode_hw_utils.h | 16 ++--- .../encode_hw/h264/src/mfx_h264_encode_hw.cpp | 5 +- .../hevc/agnostic/base/hevcehw_base_data.h | 3 - .../agnostic/base/hevcehw_base_enctools.cpp | 3 +- contrib/aenc/libaenc.a | Bin 3319574 -> 3322552 bytes 11 files changed, 27 insertions(+), 72 deletions(-) diff --git a/_studio/enctools/aenc/include/aenc.h b/_studio/enctools/aenc/include/aenc.h index 53cc8f2b5d..c25d1e4680 100644 --- a/_studio/enctools/aenc/include/aenc.h +++ b/_studio/enctools/aenc/include/aenc.h @@ -63,7 +63,7 @@ extern "C" { mfxU32 Type; //FrameType, e.g. MFX_FRAMETYPE_I mfxI32 DeltaQP; mfxU32 ClassAPQ; - mfxU32 SpatialComplexity; + mfxU32 ClassCmplx; mfxU32 KeepInDPB; mfxU32 RemoveFromDPBSize; mfxU32 RemoveFromDPB[32]; @@ -79,7 +79,7 @@ extern "C" { mfxStatus MFX_CDECL AEncProcessFrame(mfxHDL pthis, mfxU32 POC, mfxU8* InFrame, mfxI32 pitch, AEncFrame* OutFrame); mfxU16 MFX_CDECL AEncGetIntraDecision(mfxHDL pthis, mfxU32 displayOrder); mfxU16 MFX_CDECL AEncGetPersistenceMap(mfxHDL pthis, mfxU32 displayOrder, mfxU8 PMap[AENC_MAP_SIZE]); - void MFX_CDECL AEncUpdateFrame(mfxHDL pthis, mfxU32 displayOrder, mfxU32 bits, mfxU32 QpY); + void MFX_CDECL AEncUpdateFrame(mfxHDL pthis, mfxU32 displayOrder, mfxU32 bits, mfxU32 QpY, mfxU32 ClassCmplx); #ifdef __cplusplus } // extern "C" diff --git a/_studio/enctools/include/mfx_enctools_brc.h b/_studio/enctools/include/mfx_enctools_brc.h index 4e16a4ec37..1fda45ccf3 100644 --- a/_studio/enctools/include/mfx_enctools_brc.h +++ b/_studio/enctools/include/mfx_enctools_brc.h @@ -41,6 +41,7 @@ namespace EncToolsBRC constexpr mfxF64 RACA_SCALE = 128.0; constexpr mfxU8 TOTAL_NUM_AV1_SEGMENTS_FOR_ENCTOOLS = 7; + /* NalHrdConformance | VuiNalHrdParameters | Result -------------------------------------------------------------- @@ -149,7 +150,6 @@ class cBRCParams mfxU16 mHasALTR; // When mHasALTR, LTR marking decision (on/off) based on content. mfxU32 codecId; bool mMBBRC; // Enable Macroblock-CU level QP control (true/false) - bool lowPower; public: cBRCParams() : @@ -205,8 +205,7 @@ class cBRCParams mLaScale(0), mHasALTR(0), codecId(0), - mMBBRC(false), - lowPower(0) + mMBBRC(false) {} mfxStatus Init(mfxEncToolsCtrl const & ctrl, bool bMBBRC, bool bFieldMode); diff --git a/_studio/enctools/src/mfx_enctools_aenc.cpp b/_studio/enctools/src/mfx_enctools_aenc.cpp index 6aeb25e57b..93aaed67ef 100644 --- a/_studio/enctools/src/mfx_enctools_aenc.cpp +++ b/_studio/enctools/src/mfx_enctools_aenc.cpp @@ -173,7 +173,7 @@ mfxStatus AEnc_EncTool::ReportEncResult(mfxU32 displayOrder, mfxEncToolsBRCEncod mfxStatus sts = FindOutFrame(displayOrder); MFX_CHECK_STS(sts); - AEncUpdateFrame(m_aenc, displayOrder, pEncRes.CodedFrameSize*8, pEncRes.QpY); + AEncUpdateFrame(m_aenc, displayOrder, pEncRes.CodedFrameSize*8, pEncRes.QpY, (*m_frameIt).ClassCmplx); return MFX_ERR_NONE; } @@ -187,7 +187,6 @@ mfxStatus AEnc_EncTool::GetSCDecision(mfxU32 displayOrder, mfxEncToolsHintPreEnc pPreEncSC->SceneChangeFlag = static_cast((*m_frameIt).SceneChanged); pPreEncSC->RepeatedFrameFlag = static_cast((*m_frameIt).RepeatedFrame); pPreEncSC->TemporalComplexity = static_cast((*m_frameIt).TemporalComplexity); - pPreEncSC->SpatialComplexity = static_cast((*m_frameIt).SpatialComplexity); return sts; } diff --git a/_studio/enctools/src/mfx_enctools_brc.cpp b/_studio/enctools/src/mfx_enctools_brc.cpp index be6ad5dad1..87eb1a311b 100644 --- a/_studio/enctools/src/mfx_enctools_brc.cpp +++ b/_studio/enctools/src/mfx_enctools_brc.cpp @@ -126,7 +126,6 @@ mfxStatus cBRCParams::Init(mfxEncToolsCtrl const & ctrl, bool bMBBRC, bool field bFieldMode= fieldMode; codecId = ctrl.CodecId; - lowPower = IsOn(ctrl.LowPower); targetbps = ctrl.TargetKbps * 1000; maxbps = ctrl.MaxKbps * 1000; @@ -1042,9 +1041,10 @@ mfxStatus BRC_EncToolBase::UpdateFrame(mfxU32 dispOrder, mfxEncToolsBRCStatus *p mfxU16 isIntra = frameStruct.frameType & (MFX_FRAMETYPE_IDR | MFX_FRAMETYPE_I); bool bIdr = (picType == MFX_FRAMETYPE_IDR); mfxF64 qstep = QP2Qstep(qpY, m_par.quantOffset); - mfxU32 ParFrameCmplx = 0; - mfxU16 ParSceneChange = (ParFrameCmplx || frameStruct.LaAvgEncodedSize) ? frameStruct.sceneChange : 0; + mfxU16 ParSceneChange = (frameStruct.frameCmplx || frameStruct.LaAvgEncodedSize) ? frameStruct.sceneChange : 0; + mfxU32 ParFrameCmplx = frameStruct.frameCmplx; + if (isIntra && !ParFrameCmplx) ParFrameCmplx = frameStruct.LaAvgEncodedSize; mfxU16 ParQpModulation = frameStruct.qpModulation; mfxU16 miniGoPSize = frameStruct.miniGopSize == 0 ? m_par.gopRefDist : frameStruct.miniGopSize; if (ParQpModulation == MFX_QP_MODULATION_NOT_DEFINED @@ -1145,8 +1145,8 @@ mfxStatus BRC_EncToolBase::UpdateFrame(mfxU32 dispOrder, mfxEncToolsBRCStatus *p pFrameSts->FrameStatus.MinFrameSize = (m_hrdSpec->GetMinFrameSizeInBits(frameStruct.encOrder,bIdr) + 7) >> 3; //printf("%d: poc %d, size %d QP %d (%d %d), HRD sts %d, maxFrameSize %d, type %d \n",frame_par->EncodedOrder, frame_par->DisplayOrder, bitsEncoded, m_ctx.Quant, m_ctx.QuantMin, m_ctx.QuantMax, brcSts, m_hrd.GetMaxFrameSize(), frame_par->FrameType); } - bool bCalcSetI = (isIntra && (ParFrameCmplx > 0 || frameStruct.LaAvgEncodedSize) && frameStruct.encOrder == m_ctx.LastIEncOrder // We could set Qp - && ((ParSceneChange > 0 || frameStruct.encOrder == 0) && m_ctx.LastIQpSet == m_ctx.LastIQpMin)); // We did set Qp and/or was SceneChange + bool bCalcSetI = (isIntra && ParFrameCmplx > 0 && frameStruct.encOrder == m_ctx.LastIEncOrder // We could set Qp + && ((ParSceneChange > 0 || frameStruct.encOrder == 0) && m_ctx.LastIQpSet == m_ctx.LastIQpMin)); // We did set Qp and/or was SceneChange if ((e2pe > BRC_SCENE_CHANGE_RATIO2 && bitsEncoded > 4 * m_par.inputBitsPerFrame) || bCalcSetI ) @@ -1263,9 +1263,9 @@ mfxStatus BRC_EncToolBase::UpdateFrame(mfxU32 dispOrder, mfxEncToolsBRCStatus *p mfxF64 lFR = std::min(m_par.gopPicSize - 1, 4); mfxF64 lowFrameSizeI = std::min(maxFrameSize, lFR *(mfxF64)m_par.inputBitsPerFrame); // Did we set the qp? - if (isIntra && (ParFrameCmplx > 0 || frameStruct.LaAvgEncodedSize) // We could set Qp + if (isIntra && ParFrameCmplx > 0 // We could set Qp && frameStruct.encOrder == m_ctx.LastIEncOrder && m_ctx.LastIQpSet == m_ctx.LastIQpMin // We did set Qp - && frameStruct.numRecode == 0 && bitsEncoded < (lowFrameSizeI / 2.0) && quant > quantMin) // We can & should recode + && frameStruct.numRecode == 0 && bitsEncoded < (lowFrameSizeI / 2.0) && quant > quantMin) // We can & should recode { // too small; do something mfxI32 quant_new = GetNewQP(bitsEncoded, (mfxU32)lowFrameSizeI, quantMin, quantMax, quant, m_par.quantOffset, 0.78, false, true); @@ -1418,7 +1418,7 @@ mfxStatus BRC_EncToolBase::UpdateFrame(mfxU32 dispOrder, mfxEncToolsBRCStatus *p m_ctx.totalDeviation += ((mfxF64)bitsEncoded - m_par.inputBitsPerFrame); - //printf("------------------ %d (%d)) Total deviation %f, old scene %d, bNeedUpdateQP %d, m_ctx.Quant %d, type %d, m_ctx.fAbLong %f m_par.inputBitsPerFrame %f\n", frameStruct.encOrder, frameStruct.dispOrder,m_ctx.totalDeviation, oldScene , bNeedUpdateQP, m_ctx.Quant,picType, m_ctx.fAbLong, m_par.inputBitsPerFrame); + //printf("------------------ %d (%d)) Total deviation %f, old scene %d, bNeedUpdateQP %d, m_ctx.Quant %d, type %d, m_ctx.fAbLong %f m_par.inputBitsPerFrame %f\n", frame_par->EncodedOrder, frame_par->DisplayOrder,m_ctx.totalDeviation, oldScene , bNeedUpdateQP, m_ctx.Quant,picType, m_ctx.fAbLong, m_par.inputBitsPerFrame); if (m_par.HRDConformance != MFX_BRC_NO_HRD) { m_hrdSpec->Update(bitsEncoded, frameStruct.encOrder, bIdr); @@ -1605,35 +1605,11 @@ mfxI32 BRC_EncToolBase::GetLaQpEst(mfxU32 LaAvgEncodedSize, mfxF64 inputBitsPerF { if (m_par.codecId == MFX_CODEC_AVC) { - if(m_par.mLaQp != 26 || !frameStruct.frameCmplx || !m_par.lowPower) { - laQp = (mfxI32)(0.679f*laQ + 0.465f); // NN V L - } else { - mfxF32 R = (mfxF32) ((1.5 * m_par.width * m_par.height) / (inputBitsPerFrame * m_par.frameRate / 1000.0)); - mfxF32 SC = (mfxF32) frameStruct.frameCmplx; - mfxF32 C = std::max(SC / (128*64), 0.03f); - mfxF32 B = (mfxF32)laScaledSize / (mfxF32) (1.5 * m_par.width * m_par.height); - mfxF32 F = (mfxF32) (std::max(std::min(m_par.frameRate, 61.0), 23.0)); - const mfxF32 Alpha=0.094160103f, Beta=0.70605035f, Gamma=0.551621897f, Delta=0.042768353f, Epsilon=0.457860107f; - mfxF32 Q = Alpha * powf(R, Beta) * powf(F, Epsilon) * powf(B, Gamma) * powf(C, Delta); - mfxF32 Qp = 6.f * (logf(Q)/logf(2.f)) + 2.f; - laQp = (mfxI32) (Qp); - } + laQp = (mfxI32)(0.679f*laQ + 0.465f); // NN V L } else { - if(m_par.mLaQp != 26 || !frameStruct.frameCmplx || !m_par.lowPower) { - laQp = (mfxI32)(0.6634f*laQ - 0.035f); // NN V L - } else { - mfxF32 R = (mfxF32) ((1.5 * m_par.width * m_par.height) / (inputBitsPerFrame * m_par.frameRate / 1000.0)); - mfxF32 SC = (mfxF32) frameStruct.frameCmplx; - mfxF32 C = std::max(SC / (128*64), 0.03f); - mfxF32 B = (mfxF32)laScaledSize / (mfxF32) (1.5 * m_par.width * m_par.height); - mfxF32 F = (mfxF32) (std::max(std::min(m_par.frameRate, 61.0), 23.0)); - const mfxF32 Alpha=0.095227005f, Beta=0.661596921f, Gamma=0.486806893f, Delta=0.078518546f, Epsilon=0.446383738f; - mfxF32 Q = Alpha * powf(R, Beta) * powf(F, Epsilon) * powf(B, Gamma) * powf(C, Delta); - mfxF32 Qp = 6.f * (logf(Q)/logf(2.f)) + 3.f; - laQp = (mfxI32) (Qp); - } + laQp = (mfxI32)(0.6634f*laQ - 0.035f); // NN V L } } else @@ -1663,7 +1639,7 @@ mfxStatus BRC_EncToolBase::ProcessFrame(mfxU32 dispOrder, mfxEncToolsBRCQuantCon mfxU16 ParSceneChange = frameStruct.sceneChange; mfxU16 ParLongTerm = frameStruct.longTerm; - mfxU32 ParFrameCmplx = 0; // Used only for LA models for now + mfxU32 ParFrameCmplx = frameStruct.frameCmplx; mfxU16 ParQpModulation = frameStruct.qpModulation; mfxI32 ParQpDeltaP = 0; mfxU16 miniGoPSize = frameStruct.miniGopSize == 0 ? m_par.gopRefDist : frameStruct.miniGopSize; @@ -2039,10 +2015,9 @@ mfxStatus BRC_EncToolBase::ProcessFrame(mfxU32 dispOrder, mfxEncToolsBRCQuantCon } frameStruct.qp = qp - m_par.quantOffset; - //printf("EncOrder %d recode %d type %d ctrl->QpY %d, qp %d PyrLayer %d QpMod %d quantOffset %d - // Cmplx %ld LaCurEncodedSize %d LaAvgEncodedSize %d Deviation %f\n", - // frameStruct.encOrder, frameStruct.numRecode, type, frameStruct.qp, qp, frameStruct.pyrLayer, ParQpModulation, m_par.quantOffset, - // ParFrameCmplx, frameStruct.LaCurEncodedSize, frameStruct.LaAvgEncodedSize, m_ctx.totalDeviation); + //printf("EncOrder %d type %d ctrl->QpY %d, qp %d PyrLayer %d QpMod %d quantOffset %d Cmplx %ld LaCurEncodedSize %d LaAvgEncodedSize %d\n", + // frameStruct.encOrder, type, frameStruct.qp, qp, frameStruct.pyrLayer, ParQpModulation, m_par.quantOffset, + // ParFrameCmplx, frameStruct.LaCurEncodedSize, frameStruct.LaAvgEncodedSize); if (isIntra) { m_ctx.LastIQpSetOrder = frameStruct.encOrder; @@ -2098,7 +2073,6 @@ mfxStatus BRC_EncToolBase::SetFrameStruct(mfxU32 dispOrder, mfxEncToolsBRCFrameP frStruct.encOrder = pFrameStruct.EncodeOrder; frStruct.longTerm = pFrameStruct.LongTerm; frStruct.sceneChange = pFrameStruct.SceneChange; - frStruct.frameCmplx = pFrameStruct.SpatialComplexity; frStruct.PersistenceMapNZ = pFrameStruct.PersistenceMapNZ; memcpy(frStruct.PersistenceMap, pFrameStruct.PersistenceMap, sizeof(frStruct.PersistenceMap)); m_FrameStruct.push_back(frStruct); @@ -2112,7 +2086,6 @@ mfxStatus BRC_EncToolBase::SetFrameStruct(mfxU32 dispOrder, mfxEncToolsBRCFrameP (*frameStruct).numRecode++; // ??? check (*frameStruct).longTerm = pFrameStruct.LongTerm; (*frameStruct).sceneChange = pFrameStruct.SceneChange; - (*frameStruct).frameCmplx = pFrameStruct.SpatialComplexity; (*frameStruct).PersistenceMapNZ = pFrameStruct.PersistenceMapNZ; memcpy((*frameStruct).PersistenceMap, pFrameStruct.PersistenceMap, sizeof((*frameStruct).PersistenceMap)); 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 613ade4340..cfaf970af6 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 @@ -771,11 +771,10 @@ namespace Base /* Scene Change parameter */ mfxU16 SceneChange = 0; #if defined(MFX_ENABLE_ENCTOOLS) - mfxU16 SpatialComplexity = 0; /* Persistence Map */ mfxU16 PersistenceMapNZ; mfxU8 PersistenceMap[MFX_ENCTOOLS_PREENC_MAP_SIZE]; -#endif +#endif }; using RepeatedFrames = std::vector; diff --git a/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_enctools.cpp b/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_enctools.cpp index d3b59ee283..6024118a49 100644 --- a/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_enctools.cpp +++ b/_studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_enctools.cpp @@ -903,7 +903,6 @@ mfxStatus AV1EncTools::BRCGetCtrl(StorageW& global, StorageW& s_task, extFrameData.FrameType = task.FrameType; extFrameData.PyramidLayer = (mfxU16) task.PyramidLevel; extFrameData.SceneChange = task.GopHints.SceneChange; - extFrameData.SpatialComplexity = task.GopHints.SpatialComplexity; extFrameData.PersistenceMapNZ = task.GopHints.PersistenceMapNZ; if (extFrameData.PersistenceMapNZ) memcpy(extFrameData.PersistenceMap, task.GopHints.PersistenceMap, sizeof(extFrameData.PersistenceMap)); @@ -1106,7 +1105,6 @@ mfxStatus AV1EncTools::QueryPreEncTask(StorageW& /*global*/, StorageW& s_task) task.GopHints.MiniGopSize = preEncodeGOP.MiniGopSize; task.GopHints.FrameType = preEncodeGOP.FrameType; task.GopHints.SceneChange = preEncodeSChg.SceneChangeFlag; - task.GopHints.SpatialComplexity = preEncodeSChg.SpatialComplexity; task.GopHints.PersistenceMapNZ = preEncodeSChg.PersistenceMapNZ; if (preEncodeSChg.PersistenceMapNZ) memcpy(task.GopHints.PersistenceMap, preEncodeSChg.PersistenceMap, sizeof(task.GopHints.PersistenceMap)); diff --git a/_studio/mfx_lib/encode_hw/h264/include/mfx_h264_encode_hw_utils.h b/_studio/mfx_lib/encode_hw/h264/include/mfx_h264_encode_hw_utils.h index c944b630e1..df3a9322c6 100644 --- a/_studio/mfx_lib/encode_hw/h264/include/mfx_h264_encode_hw_utils.h +++ b/_studio/mfx_lib/encode_hw/h264/include/mfx_h264_encode_hw_utils.h @@ -1062,11 +1062,8 @@ namespace MfxHwH264Encode #endif , m_TCBRCTargetFrameSize(0) , m_SceneChange(0) -#if defined(MFX_ENABLE_ENCTOOLS) - , m_SpatialComplexity(0) , m_PersistenceMapNZ(0) - , m_PersistenceMap{} -#endif + , m_PersistenceMap{} #if defined(MFX_ENABLE_MCTF_IN_AVC) , m_doMCTFIntraFiltering(0) #endif @@ -1365,11 +1362,8 @@ namespace MfxHwH264Encode #endif mfxU32 m_TCBRCTargetFrameSize; mfxU32 m_SceneChange; -#if defined(MFX_ENABLE_ENCTOOLS) - mfxU16 m_SpatialComplexity; mfxU16 m_PersistenceMapNZ; - mfxU8 m_PersistenceMap[128]; -#endif + mfxU8 m_PersistenceMap[128]; #if defined(MFX_ENABLE_MCTF_IN_AVC) mfxU32 m_doMCTFIntraFiltering; #endif @@ -2274,8 +2268,7 @@ class H264EncTools { MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED); MFX_CHECK(IsOn(m_EncToolConfig.AdaptiveI) || - IsOn(m_EncToolConfig.AdaptiveLTR) || - IsOn(m_EncToolConfig.BRC), MFX_ERR_NOT_INITIALIZED); + IsOn(m_EncToolConfig.AdaptiveLTR), MFX_ERR_NOT_INITIALIZED); mfxEncToolsTaskParam par = {}; par.DisplayOrder = displayOrder; @@ -2361,10 +2354,9 @@ class H264EncTools extFrameStruct.PyramidLayer = frame_par->PyramidLayer; extFrameStruct.LongTerm = frame_par->LongTerm; extFrameStruct.SceneChange = frame_par->SceneChange; - extFrameStruct.SpatialComplexity = task.m_SpatialComplexity; extFrameStruct.PersistenceMapNZ = task.m_PersistenceMapNZ; if (task.m_PersistenceMapNZ) - memcpy(extFrameStruct.PersistenceMap, task.m_PersistenceMap, sizeof(task.m_PersistenceMap)); + memcpy(extFrameStruct.PersistenceMap, task.m_PersistenceMap, sizeof(task.m_PersistenceMap)); extParams.push_back((mfxExtBuffer *)&extFrameStruct); if (frame_par->OptimalFrameSizeInBytes | frame_par->LaAvgEncodedSize) diff --git a/_studio/mfx_lib/encode_hw/h264/src/mfx_h264_encode_hw.cpp b/_studio/mfx_lib/encode_hw/h264/src/mfx_h264_encode_hw.cpp index da23b4a442..422e3c0654 100644 --- a/_studio/mfx_lib/encode_hw/h264/src/mfx_h264_encode_hw.cpp +++ b/_studio/mfx_lib/encode_hw/h264/src/mfx_h264_encode_hw.cpp @@ -3219,15 +3219,14 @@ mfxStatus ImplementationAvc::FillPreEncParams(DdiTask &task) } } - if (m_encTools.IsAdaptiveI() || m_encTools.IsAdaptiveLTR() || m_encTools.IsBRC()) { + if (m_encTools.IsAdaptiveI() || m_encTools.IsAdaptiveLTR()) { mfxEncToolsHintPreEncodeSceneChange schg = {}; sts = m_encTools.QueryPreEncSChg(task.m_frameOrder, schg); MFX_CHECK_STS(sts); task.m_SceneChange = schg.SceneChangeFlag; - task.m_SpatialComplexity = schg.SpatialComplexity; task.m_PersistenceMapNZ = schg.PersistenceMapNZ; if(task.m_PersistenceMapNZ) - memcpy(task.m_PersistenceMap, schg.PersistenceMap, sizeof(task.m_PersistenceMap)); + memcpy(task.m_PersistenceMap, schg.PersistenceMap, sizeof(task.m_PersistenceMap)); } if (m_encTools.IsAdaptiveLTR() || m_encTools.IsAdaptiveRef()) diff --git a/_studio/mfx_lib/encode_hw/hevc/agnostic/base/hevcehw_base_data.h b/_studio/mfx_lib/encode_hw/hevc/agnostic/base/hevcehw_base_data.h index d9bfb09c68..dc81586b75 100644 --- a/_studio/mfx_lib/encode_hw/hevc/agnostic/base/hevcehw_base_data.h +++ b/_studio/mfx_lib/encode_hw/hevc/agnostic/base/hevcehw_base_data.h @@ -753,12 +753,9 @@ namespace Base mfxU32 QPModulaton = 0; /* Scene Change parameter */ mfxU16 SceneChange = 0; -#if defined(MFX_ENABLE_ENCTOOLS) - mfxU16 SpatialComplexity = 0; /* Maps */ mfxU16 PersistenceMapNZ; mfxU8 PersistenceMap[128]; -#endif }; struct mfxBRCHints { diff --git a/_studio/mfx_lib/encode_hw/hevc/agnostic/base/hevcehw_base_enctools.cpp b/_studio/mfx_lib/encode_hw/hevc/agnostic/base/hevcehw_base_enctools.cpp index 86758304fa..71e2b5908b 100644 --- a/_studio/mfx_lib/encode_hw/hevc/agnostic/base/hevcehw_base_enctools.cpp +++ b/_studio/mfx_lib/encode_hw/hevc/agnostic/base/hevcehw_base_enctools.cpp @@ -830,7 +830,6 @@ mfxStatus HevcEncTools::BRCGetCtrl(StorageW& global , StorageW& s_task, extFrameData.FrameType = task.FrameType; extFrameData.PyramidLayer = (mfxU16) task.PyramidLevel; extFrameData.SceneChange = task.GopHints.SceneChange; - extFrameData.SpatialComplexity = task.GopHints.SpatialComplexity; extFrameData.PersistenceMapNZ = task.GopHints.PersistenceMapNZ; memcpy(extFrameData.PersistenceMap, task.GopHints.PersistenceMap, sizeof(extFrameData.PersistenceMap)); @@ -1010,8 +1009,8 @@ mfxStatus HevcEncTools::QueryPreEncTask(StorageW& global, StorageW& s_task) task.GopHints.MiniGopSize = preEncodeGOP.MiniGopSize; task.GopHints.FrameType = preEncodeGOP.FrameType; task.GopHints.SceneChange = preEncodeSChg.SceneChangeFlag; - task.GopHints.SpatialComplexity = preEncodeSChg.SpatialComplexity; task.GopHints.PersistenceMapNZ = preEncodeSChg.PersistenceMapNZ; + if (qpMapHint.QpMapFilled) task.bCUQPMap = true; memcpy(task.GopHints.PersistenceMap, preEncodeSChg.PersistenceMap, sizeof(task.GopHints.PersistenceMap)); diff --git a/contrib/aenc/libaenc.a b/contrib/aenc/libaenc.a index e30bc0f547825407468e3df89130c8c7441a1cc5..b6982ead800a45297d4454b52419ea4442d031c1 100644 GIT binary patch delta 31200 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 Whr^G69|@lZ?|~ona9nZvW&aOMWwGG^ delta 35326 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