Skip to content

Commit

Permalink
[h264e] Enable QPOffset by default
Browse files Browse the repository at this point in the history
- In CQP mode and GopRefDist 1 case
  PRefType is set to MFX_P_REF_PYRAMID by default.
- EnableQPOffset is on by default, QPOffset is added in CQP mode.
  • Loading branch information
pgribov authored and Oleg Nabiullin committed Jul 10, 2020
1 parent 0c07631 commit 37f26bb
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 24 deletions.
13 changes: 11 additions & 2 deletions _studio/mfx_lib/encode_hw/h264/include/mfx_h264_encode_hw_utils.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2018-2019 Intel Corporation
// Copyright (c) 2018-2020 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -49,6 +49,7 @@
#define MFX_ARRAY_SIZE(ARR) (sizeof(ARR)/sizeof(ARR[0]))
const int MFX_MAX_DIRTY_RECT_COUNT = MFX_ARRAY_SIZE(mfxExtDirtyRect::Rect);
const int MFX_MAX_MOVE_RECT_COUNT = MFX_ARRAY_SIZE(mfxExtMoveRect::Rect);
const int DEFAULT_PPYR_INTERVAL = 3;


namespace MfxHwH264Encode
Expand Down Expand Up @@ -291,9 +292,17 @@ namespace MfxHwH264Encode
mfxExtCodingOptionDDI const * extDdi,
mfxU8 frameType);

mfxU8 GetPFrameLevel(
mfxU32 i,
mfxU32 num);

mfxU8 PLayer(
MfxVideoParam const & par,
mfxU32 order);

mfxU8 GetQpValue(
DdiTask const & task,
MfxVideoParam const & par,
mfxEncodeCtrl const & ctrl,
mfxU32 frameType);

PairU16 GetPicStruct(
Expand Down
68 changes: 61 additions & 7 deletions _studio/mfx_lib/encode_hw/h264/src/mfx_h264_encode_hw_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,29 +263,83 @@ namespace MfxHwH264Encode
return true;
}

mfxU8 GetPFrameLevel(mfxU32 i, mfxU32 num)
{
if (i == 0 || i >= num) return 0;
mfxU32 level = 1;
mfxU32 begin = 0;
mfxU32 end = num;
mfxU32 t = (begin + end + 1) / 2;

while (t != i)
{
level++;
if (i > t)
begin = t;
else
end = t;
t = (begin + end + 1) / 2;
}
return (mfxU8)level;
}

mfxU8 PLayer(MfxVideoParam const & par, mfxU32 order)
{
return std::min<mfxU8>(7, GetPFrameLevel(order % par.calcParam.PPyrInterval, par.calcParam.PPyrInterval));
}

mfxU8 GetQpValue(
DdiTask const & task,
MfxVideoParam const & par,
mfxEncodeCtrl const & ctrl,
mfxU32 frameType)
{
const mfxExtCodingOption2& CO2 = GetExtBufferRef(par);
const mfxExtCodingOption3& CO3 = GetExtBufferRef(par);
const mfxU8 minQP = 1;
const mfxU8 maxQP = 51;
mfxU8 QP = 0;

if (par.mfx.RateControlMethod == MFX_RATECONTROL_CQP /*||
par.mfx.RateControlMethod == MFX_RATECONTROL_VCM && (frameType & MFX_FRAMETYPE_I)*/)
{
if (ctrl.QP > 0)
if (task.m_ctrl.QP > 0)
{
if (IsOn(par.mfx.LowPower) && ctrl.QP < 10)
if (IsOn(par.mfx.LowPower) && task.m_ctrl.QP < 10)
return 10;
// get per frame qp
return std::min<mfxU8>(ctrl.QP, 51);
return std::min<mfxU8>(task.m_ctrl.QP, 51);
}
else
{
bool bUseQPOffset =
(frameType & MFX_FRAMETYPE_B && CO2.BRefType == MFX_B_REF_PYRAMID)
|| (frameType & MFX_FRAMETYPE_P && CO3.PRefType == MFX_P_REF_PYRAMID);

// get per stream qp
switch (frameType & MFX_FRAMETYPE_IPB)
{
case MFX_FRAMETYPE_I: return mfxU8(par.mfx.QPI);
case MFX_FRAMETYPE_P: return mfxU8(par.mfx.QPP);
case MFX_FRAMETYPE_B: return mfxU8(par.mfx.QPB);
case MFX_FRAMETYPE_I:
return mfxU8(par.mfx.QPI);
case MFX_FRAMETYPE_P:
QP = mfxU8(par.mfx.QPP);
if (par.calcParam.numTemporalLayer > 1)
{
QP = (mfxU8)mfx::clamp<mfxI32>(CO3.QPOffset[task.m_tid] + QP, minQP, maxQP);
}
else if (bUseQPOffset)
{
QP = (mfxU8)mfx::clamp<mfxI32>(
CO3.QPOffset[PLayer(par, task.m_encOrder - task.m_encOrderI)] + QP, minQP, maxQP);
}
return QP;
case MFX_FRAMETYPE_B:
QP = mfxU8(par.mfx.QPB);
if (bUseQPOffset)
{
QP = (mfxU8)mfx::clamp<mfxI32>(
CO3.QPOffset[mfx::clamp<mfxI32>(task.m_loc.level - 1, 0, 7)] + QP, minQP, maxQP);
}
return QP;
default: assert(!"bad frame type (GetQpValue)"); return 0xff;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2315,8 +2315,8 @@ void MfxHwH264Encode::ConfigureTask(
task.m_nalRefIdc[sfid] = task.m_reference[sfid] ? 2 : 0;
}

task.m_cqpValue[0] = GetQpValue(video, task.m_ctrl, task.m_type[0]);
task.m_cqpValue[1] = GetQpValue(video, task.m_ctrl, task.m_type[1]);
task.m_cqpValue[0] = GetQpValue(task, video, task.m_type[0]);
task.m_cqpValue[1] = GetQpValue(task, video, task.m_type[1]);

task.m_statusReportNumber[0] = 2 * task.m_encOrder;
task.m_statusReportNumber[1] = 2 * task.m_encOrder + 1;
Expand Down
6 changes: 3 additions & 3 deletions _studio/mfx_lib/fei/h264_common/fei_common.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Intel Corporation
// Copyright (c) 2019-2020 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -172,8 +172,8 @@ void MfxH264FEIcommon::ConfigureTaskFEI(
task.m_nalRefIdc[sfid] = task.m_reference[sfid] ? 2 : 0;
}

task.m_cqpValue[0] = GetQpValue(video, task.m_ctrl, task.m_type[0]);
task.m_cqpValue[1] = GetQpValue(video, task.m_ctrl, task.m_type[1]);
task.m_cqpValue[0] = GetQpValue(task, video, task.m_type[0]);
task.m_cqpValue[1] = GetQpValue(task, video, task.m_type[1]);

#if MFX_VERSION >= 1023

Expand Down
1 change: 1 addition & 0 deletions _studio/mfx_lib/shared/include/mfx_h264_enc_common_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ namespace MfxHwH264Encode
mfxU16 widthLa;
mfxU16 heightLa;
mfxU32 TCBRCTargetFrameSize;
mfxU32 PPyrInterval;
} calcParam;
};

Expand Down
71 changes: 61 additions & 10 deletions _studio/mfx_lib/shared/src/mfx_h264_enc_common_hw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3208,9 +3208,33 @@ mfxStatus MfxHwH264Encode::CheckVideoParamQueryLike(
if (!CheckTriStateOption(extOpt2->RepeatPPS)) changed = true;
if (!CheckTriStateOption(extOpt2->UseRawRef)) changed = true;

if (!CheckTriStateOption(extOpt3->EnableQPOffset)) changed = true;
if (!CheckTriStateOption(extOpt3->DirectBiasAdjustment)) changed = true;
if (!CheckTriStateOption(extOpt3->GlobalMotionBiasAdjustment)) changed = true;

if ( IsOn(extOpt3->EnableQPOffset)
&& (par.mfx.RateControlMethod != MFX_RATECONTROL_CQP
|| (par.mfx.GopRefDist > 1 && extOpt2->BRefType == MFX_B_REF_OFF)
|| (par.mfx.GopRefDist == 1 && extOpt3->PRefType == MFX_P_REF_SIMPLE)))
{
extOpt3->EnableQPOffset = MFX_CODINGOPTION_OFF;
changed = true;
}

if (IsOn(extOpt3->EnableQPOffset))
{
mfxU16 minQP = 1;
mfxU16 maxQP = 51;
mfxI16 QPX = (par.mfx.GopRefDist == 1) ? par.mfx.QPP : par.mfx.QPB;

if (QPX)
{
for (mfxI16 i = 0; i < 8; i++)
if (!CheckRange(extOpt3->QPOffset[i], minQP - QPX, maxQP - QPX))
changed = true;
}
}

if ((isENCPAK || vaType != MFX_HW_VAAPI)
&& (IsOn(extOpt3->DirectBiasAdjustment) || IsOn(extOpt3->GlobalMotionBiasAdjustment)))
{
Expand Down Expand Up @@ -5274,6 +5298,7 @@ void MfxHwH264Encode::InheritDefaultValues(
}
InheritOption(extOpt2Init.DisableVUI, extOpt2Reset.DisableVUI);
InheritOption(extOpt2Init.SkipFrame, extOpt2Reset.SkipFrame);
InheritOption(extOpt3Init.PRefType, extOpt3Reset.PRefType);

InheritOption(extOpt2Init.ExtBRC, extOpt2Reset.ExtBRC);

Expand Down Expand Up @@ -5785,6 +5810,36 @@ void MfxHwH264Encode::SetDefaults(
if (extOpt2->RepeatPPS == MFX_CODINGOPTION_UNKNOWN)
extOpt2->RepeatPPS = MFX_CODINGOPTION_ON;

mfxExtBRC const & extBRC = GetExtBufferRef(par);

if (extOpt3->PRefType == MFX_P_REF_DEFAULT)
{
if (par.mfx.GopRefDist == 1 && ((par.mfx.RateControlMethod == MFX_RATECONTROL_CQP) || (IsExtBrcSceneChangeSupported(par) && !extBRC.pthis)))
extOpt3->PRefType = MFX_P_REF_PYRAMID;
else if (par.mfx.GopRefDist == 1)
extOpt3->PRefType = MFX_P_REF_SIMPLE;
}

if (!extOpt3->EnableQPOffset)
{
mfxU16 minQP = 1;
mfxU16 maxQP = 51;
if (par.mfx.RateControlMethod == MFX_RATECONTROL_CQP
&& (extOpt2->BRefType == MFX_B_REF_PYRAMID || extOpt3->PRefType == MFX_P_REF_PYRAMID))
{
extOpt3->EnableQPOffset = MFX_CODINGOPTION_ON;
mfxI16 QPX = (par.mfx.GopRefDist == 1) ? par.mfx.QPP : par.mfx.QPB;

for (mfxI16 i = 0; i < 8; i++)
extOpt3->QPOffset[i] = mfx::clamp<mfxI16>(i + (par.mfx.GopRefDist > 1), (mfxI16)minQP - QPX, (mfxI16)maxQP - QPX);
}
else
extOpt3->EnableQPOffset = MFX_CODINGOPTION_OFF;
}

if (IsOff(extOpt3->EnableQPOffset))
Zero(extOpt3->QPOffset);

if (extOpt2->MinQPI || extOpt2->MinQPP || extOpt2->MinQPB ||
extOpt2->MaxQPI || extOpt2->MaxQPP || extOpt2->MaxQPB)
{
Expand Down Expand Up @@ -5823,13 +5878,17 @@ void MfxHwH264Encode::SetDefaults(
par.mfx.NumRefFrame = 1;
else if ((par.mfx.FrameInfo.PicStruct & MFX_PICSTRUCT_PROGRESSIVE) == 0)
par.mfx.NumRefFrame = std::min({std::max(nrfDefault, nrfMinForInterlace), nrfMaxByLevel, nrfMaxByCaps});
else if (extOpt3->PRefType == MFX_P_REF_PYRAMID)
par.mfx.NumRefFrame = std::max<mfxU16>((mfxU16)par.calcParam.PPyrInterval, extDdi->NumActiveRefP);
else
par.mfx.NumRefFrame = std::min({nrfDefault, nrfMaxByLevel, nrfMaxByCaps});

if (IsOn(par.mfx.LowPower))
{
par.mfx.NumRefFrame = std::min<mfxU16>(hwCaps.ddi_caps.MaxNum_Reference, par.mfx.NumRefFrame);
}

par.calcParam.PPyrInterval = std::min<mfxU32>(par.calcParam.PPyrInterval, par.mfx.NumRefFrame);
}

if (extOpt->IntraPredBlockSize == MFX_BLOCKSIZE_UNKNOWN)
Expand Down Expand Up @@ -5883,7 +5942,6 @@ void MfxHwH264Encode::SetDefaults(
if (extOpt3->ExtBrcAdaptiveLTR == MFX_CODINGOPTION_UNKNOWN)
{
extOpt3->ExtBrcAdaptiveLTR = MFX_CODINGOPTION_OFF;
mfxExtBRC const & extBRC = GetExtBufferRef(par);
// remove check when sample extbrc is same as implicit extbrc
// currently added for no behaviour change in sample extbrc
if (IsExtBrcSceneChangeSupported(par) && !extBRC.pthis)
Expand All @@ -5894,7 +5952,6 @@ void MfxHwH264Encode::SetDefaults(
}
}

mfxExtBRC const & extBRC = GetExtBufferRef(par);
if (extOpt2->AdaptiveI == MFX_CODINGOPTION_UNKNOWN)
{
if (IsExtBrcSceneChangeSupported(par) && !extBRC.pthis)
Expand All @@ -5910,14 +5967,6 @@ void MfxHwH264Encode::SetDefaults(
else
extOpt2->AdaptiveB = MFX_CODINGOPTION_OFF;
}

if (extOpt3->PRefType == MFX_P_REF_DEFAULT)
{
if (par.mfx.GopRefDist == 1 && IsExtBrcSceneChangeSupported(par) && !extBRC.pthis)
extOpt3->PRefType = MFX_P_REF_PYRAMID;
else if (par.mfx.GopRefDist == 1)
extOpt3->PRefType = MFX_P_REF_SIMPLE;
}
#endif //(MFX_VERSION >= 1026)

CheckVideoParamQueryLike(par, hwCaps, platform, vaType, config);
Expand Down Expand Up @@ -7568,6 +7617,8 @@ void MfxVideoParam::SyncVideoToCalculableParam()
{
mfxU32 multiplier = std::max<mfxU16>(mfx.BRCParamMultiplier, 1);

calcParam.PPyrInterval = (mfx.NumRefFrame > 0) ? std::min<mfxU32>(DEFAULT_PPYR_INTERVAL, mfx.NumRefFrame) : DEFAULT_PPYR_INTERVAL;

calcParam.bufferSizeInKB = mfx.BufferSizeInKB * multiplier;
if (IsOn(m_extOpt.VuiNalHrdParameters)
&& !IsOn(m_extOpt.VuiVclHrdParameters)
Expand Down

0 comments on commit 37f26bb

Please sign in to comment.