Skip to content
This repository was archived by the owner on May 17, 2023. It is now read-only.

Commit 295182a

Browse files
author
Nabiullin, Oleg
committed
Add HEVCe MBQP and AVCe Fade Detection support
1 parent 6ae24f6 commit 295182a

File tree

7 files changed

+521
-4
lines changed

7 files changed

+521
-4
lines changed

_studio/hevce_hw/h265/include/mfx_h265_encode_hw_ddi.h

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ DriverEncoder* CreatePlatformH265Encoder(MFXCoreInterface* core, ENCODER_TYPE ty
6161
mfxStatus QueryHwCaps(MFXCoreInterface* core, GUID guid, ENCODE_CAPS_HEVC & caps);
6262
mfxStatus CheckHeaders(MfxVideoParam const & par, ENCODE_CAPS_HEVC const & caps);
6363

64+
mfxStatus FillCUQPDataDDI(Task& task, MfxVideoParam &par, MFXCoreInterface& core, mfxFrameInfo &CUQPFrameInfo);
6465

6566
enum
6667
{

_studio/hevce_hw/h265/include/mfx_h265_encode_vaapi.h

+5
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@ mfxStatus SetSkipFrame(
246246
mfxU32 m_height;
247247
ENCODE_CAPS_HEVC m_caps;
248248

249+
std::vector<mfxI8> m_cuqp_buffer;
250+
mfxU32 m_cuqp_width;
251+
mfxU32 m_cuqp_height;
252+
mfxU32 m_cuqp_pitch;
253+
mfxU32 m_cuqp_h_aligned;
249254
std::vector<VAEncROI> m_arrayVAEncROI;
250255

251256
static const mfxU32 MAX_CONFIG_BUFFERS_COUNT = 26 + 5;

_studio/hevce_hw/h265/src/mfx_h265_encode_hw_ddi.cpp

+67
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,73 @@ ENCODE_PACKEDHEADER_DATA* DDIHeaderPacker::PackSkippedSlice(Task const & task, m
239239

240240
return &*m_cur;
241241
}
242+
mfxStatus FillCUQPDataDDI(Task& task, MfxVideoParam &par, MFXCoreInterface& core, mfxFrameInfo &CUQPFrameInfo )
243+
{
244+
mfxStatus mfxSts = MFX_ERR_NONE;
245+
mfxCoreParam coreParams = {};
246+
247+
if (core.GetCoreParam(&coreParams))
248+
return MFX_ERR_UNSUPPORTED;
249+
250+
if (par.mfx.RateControlMethod != MFX_RATECONTROL_CQP || !IsOn(par.m_ext.CO3.EnableMBQP) || ((coreParams.Impl & 0xF00) == MFX_HW_VAAPI))
251+
return MFX_ERR_NONE;
252+
253+
mfxU32 minWidthQPData = (par.m_ext.HEVCParam.PicWidthInLumaSamples + par.LCUSize - 1) / par.LCUSize;
254+
mfxU32 minHeightQPData = (par.m_ext.HEVCParam.PicHeightInLumaSamples + par.LCUSize - 1) / par.LCUSize;
255+
mfxU32 minQPSize = minWidthQPData*minHeightQPData;
256+
mfxU32 driverQPsize = CUQPFrameInfo.Width * CUQPFrameInfo.Height;
257+
258+
if (!(driverQPsize >= minQPSize && minQPSize > 0))
259+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
260+
mfxU32 k_dr_w = 1;
261+
mfxU32 k_dr_h = 1;
262+
mfxU32 k_input = 1;
263+
264+
if (driverQPsize > minQPSize)
265+
{
266+
k_dr_w = CUQPFrameInfo.Width/minWidthQPData;
267+
k_dr_h = minHeightQPData/minHeightQPData;
268+
if (!(minWidthQPData*k_dr_w == CUQPFrameInfo.Width && minHeightQPData*k_dr_h == CUQPFrameInfo.Height))
269+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
270+
if (!(k_dr_w == 1 ||k_dr_w == 2 || k_dr_w == 4 || k_dr_w == 8))
271+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
272+
if (!(k_dr_h == 1 ||k_dr_h == 2 || k_dr_h == 4 || k_dr_h == 8))
273+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
274+
}
275+
276+
mfxExtMBQP *mbqp = ExtBuffer::Get(task.m_ctrl);
277+
mfxU32 BlockSize = 16;
278+
mfxU32 pitch_MBQP = (par.mfx.FrameInfo.Width + BlockSize - 1)/BlockSize;
279+
mfxU32 height_MBQP = (par.mfx.FrameInfo.Height + BlockSize - 1)/BlockSize;
280+
if (mbqp)
281+
{
282+
mfxU16 blockSize = 16; //mbqp->BlockSize ? mbqp->BlockSize : 16;
283+
k_input = par.LCUSize/blockSize;
284+
if (!(par.LCUSize == blockSize*k_input))
285+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
286+
if (mbqp->NumQPAlloc < ((height_MBQP*pitch_MBQP)) )
287+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
288+
if (!(k_input == 1 ||k_input == 2 || k_input == 4 || k_input == 8))
289+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
290+
}
291+
292+
{
293+
FrameLocker lock(&core, task.m_midCUQp);
294+
MFX_CHECK(lock.Y, MFX_ERR_LOCK_MEMORY);
295+
296+
if ((mbqp) && (MFX_ERR_NONE == mfxSts))
297+
for (mfxU32 i = 0; i < CUQPFrameInfo.Height; i++)
298+
for (mfxU32 j = 0; j < CUQPFrameInfo.Width; j++)
299+
lock.Y[i * lock.Pitch +j] = mbqp->QP[i*k_input/k_dr_h* pitch_MBQP + j*k_input/k_dr_w];
300+
else
301+
for (mfxU32 i = 0; i < CUQPFrameInfo.Height; i++)
302+
{
303+
memset((mfxU8 *)&lock.Y[i * lock.Pitch], (mfxU8)task.m_qpY, (size_t)CUQPFrameInfo.Width);
304+
}
305+
}
306+
return mfxSts;
307+
308+
}
242309

243310

244311
}; // namespace MfxHwH265Encode

_studio/hevce_hw/h265/src/mfx_h265_encode_hw_par.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1323,8 +1323,10 @@ mfxStatus CheckVideoParam(MfxVideoParam& par, ENCODE_CAPS_HEVC const & caps, boo
13231323
{
13241324
if (par.mfx.RateControlMethod != MFX_RATECONTROL_CQP && !par.isSWBRC())
13251325
changed += CheckOption(CO3.EnableMBQP, (mfxU16)MFX_CODINGOPTION_UNKNOWN, (mfxU16)MFX_CODINGOPTION_ON);
1326-
else
1327-
changed += CheckOption(CO3.EnableMBQP, (mfxU16)MFX_CODINGOPTION_UNKNOWN, (mfxU16)MFX_CODINGOPTION_OFF);
1326+
if (par.isSWBRC())
1327+
changed += CheckOption(CO3.EnableMBQP, (mfxU16)MFX_CODINGOPTION_UNKNOWN, (mfxU16)MFX_CODINGOPTION_OFF);
1328+
if (caps.MbQpDataSupport == 0 && par.mfx.RateControlMethod == MFX_RATECONTROL_CQP)
1329+
changed += CheckOption(CO3.EnableMBQP, (mfxU16)MFX_CODINGOPTION_UNKNOWN, (mfxU16)MFX_CODINGOPTION_OFF);
13281330

13291331

13301332
}

_studio/hevce_hw/h265/src/mfx_h265_encode_vaapi.cpp

+88
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,10 @@ VAAPIEncoder::VAAPIEncoder()
662662
, m_width(0)
663663
, m_height(0)
664664
, m_caps()
665+
, m_cuqp_width(0)
666+
, m_cuqp_height(0)
667+
, m_cuqp_pitch(0)
668+
, m_cuqp_h_aligned(0)
665669
{
666670
}
667671

@@ -1014,6 +1018,15 @@ mfxStatus VAAPIEncoder::CreateAccelerationService(MfxVideoParam const & par)
10141018

10151019
DDIHeaderPacker::Reset(par);
10161020

1021+
if (par.mfx.RateControlMethod == MFX_RATECONTROL_CQP && IsOn(par.m_ext.CO3.EnableMBQP))
1022+
{
1023+
//16x32 only: driver limitation
1024+
m_cuqp_width = (par.m_ext.HEVCParam.PicWidthInLumaSamples + par.LCUSize - 1) / par.LCUSize*2;
1025+
m_cuqp_height = (par.m_ext.HEVCParam.PicHeightInLumaSamples + par.LCUSize - 1) / par.LCUSize;
1026+
m_cuqp_pitch = (((((((par.m_ext.HEVCParam.PicWidthInLumaSamples/4 + 15)/16)*4*16) + 31)/32)*2 + 63)/64)*64;
1027+
m_cuqp_h_aligned = (((((((par.m_ext.HEVCParam.PicHeightInLumaSamples/4 + 15)/16)*4*16) + 31)/32) + 3)/4)*4;
1028+
m_cuqp_buffer.resize(m_cuqp_pitch * m_cuqp_h_aligned);
1029+
}
10171030

10181031

10191032
return MFX_ERR_NONE;
@@ -1116,6 +1129,68 @@ bool operator!=(const ENCODE_ENC_CTRL_CAPS& l, const ENCODE_ENC_CTRL_CAPS& r)
11161129
{
11171130
return !(l == r);
11181131
}
1132+
mfxStatus FillCUQPDataVA(Task const & task, MfxVideoParam &par, std::vector<mfxI8> &m_cuqp_buffer, mfxU32 Width, mfxU32 Height, mfxU32 Pitch)
1133+
{
1134+
mfxStatus mfxSts = MFX_ERR_NONE;
1135+
if (par.mfx.RateControlMethod != MFX_RATECONTROL_CQP || !IsOn(par.m_ext.CO3.EnableMBQP) )
1136+
return MFX_ERR_NONE;
1137+
1138+
Zero(m_cuqp_buffer);
1139+
1140+
mfxU32 minWidthQPData = (par.m_ext.HEVCParam.PicWidthInLumaSamples + par.LCUSize - 1) / par.LCUSize;
1141+
mfxU32 minHeightQPData = (par.m_ext.HEVCParam.PicHeightInLumaSamples + par.LCUSize - 1) / par.LCUSize;
1142+
mfxU32 minQPSize = minWidthQPData*minHeightQPData;
1143+
mfxU32 driverQPsize = Width * Height;
1144+
1145+
if (!(driverQPsize >= minQPSize && minQPSize > 0))
1146+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
1147+
mfxU32 k_dr_w = 1;
1148+
mfxU32 k_dr_h = 1;
1149+
mfxU32 k_input = 1;
1150+
1151+
if (driverQPsize > minQPSize)
1152+
{
1153+
k_dr_w = Width/minWidthQPData;
1154+
k_dr_h = Height/minHeightQPData;
1155+
1156+
if (!(minWidthQPData*k_dr_w == Width && minHeightQPData*k_dr_h == Height))
1157+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
1158+
if (!(k_dr_w == 1 || k_dr_w == 2 || k_dr_w == 4 || k_dr_w == 8))
1159+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
1160+
if (!(k_dr_h == 1 || k_dr_h == 2 || k_dr_h == 4 || k_dr_h == 8))
1161+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
1162+
}
1163+
1164+
mfxExtMBQP *mbqp = ExtBuffer::Get(task.m_ctrl);
1165+
mfxU32 BlockSize = 16;
1166+
mfxU32 pitch_MBQP = (par.mfx.FrameInfo.Width + BlockSize - 1)/BlockSize;
1167+
mfxU32 height_MBQP = (par.mfx.FrameInfo.Height + BlockSize - 1)/BlockSize;
1168+
if (mbqp)
1169+
{
1170+
mfxU16 blockSize = 16;//mbqp->BlockSize ? mbqp->BlockSize : 16;
1171+
k_input = par.LCUSize/blockSize;
1172+
if (!(par.LCUSize == blockSize*k_input))
1173+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
1174+
if (mbqp->NumQPAlloc < ((height_MBQP*pitch_MBQP)) )
1175+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
1176+
if (!(k_input == 1 ||k_input == 2 || k_input == 4 || k_input == 8))
1177+
mfxSts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
1178+
}
1179+
1180+
if ((mbqp) && (MFX_ERR_NONE == mfxSts))
1181+
for (mfxU32 i = 0; i < Height; i++)
1182+
for (mfxU32 j = 0; j < Width; j++)
1183+
{
1184+
//m_cuqp_buffer[i * Pitch +j] = mbqp->QP[i*k_input/k_dr_h * Width + j*k_input/k_dr_w];
1185+
m_cuqp_buffer[i * Pitch +j] = mbqp->QP[i*k_input/k_dr_h * pitch_MBQP + j*k_input/k_dr_w];
1186+
}
1187+
else
1188+
for (mfxU32 i = 0; i < Height; i++)
1189+
for (mfxU32 j = 0; j < Width; j++)
1190+
m_cuqp_buffer[i * Pitch +j] = (mfxU8)task.m_qpY;
1191+
1192+
return mfxSts;
1193+
}
11191194

11201195
mfxStatus SetSkipFrame(
11211196
VADisplay vaDisplay,
@@ -1175,6 +1250,7 @@ mfxStatus VAAPIEncoder::Execute(Task const & task, mfxHDL surface)
11751250
UpdatePPS(task, m_pps, m_reconQueue);
11761251
UpdateSlice(task, m_sps, m_pps, m_slice);
11771252

1253+
FillCUQPDataVA(task, m_videoParam, m_cuqp_buffer, m_cuqp_width, m_cuqp_height, m_cuqp_pitch);
11781254
mfxU8 skipFlag = ((task.m_ctrl.SkipFrame == 0) || (task.m_frameType & MFX_FRAMETYPE_I)) ? 0 : task.m_ctrl.SkipFrame;
11791255
HevcSkipMode skipMode(task.m_SkipMode);
11801256
//------------------------------------------------------------------
@@ -1233,6 +1309,18 @@ mfxStatus VAAPIEncoder::Execute(Task const & task, mfxHDL surface)
12331309
}
12341310

12351311

1312+
if (m_cuqp_buffer.size() > 0)
1313+
{
1314+
vaSts = vaCreateBuffer(m_vaDisplay,
1315+
m_vaContextEncode,
1316+
(VABufferType)VAEncQpBufferType,
1317+
m_cuqp_pitch ,
1318+
m_cuqp_h_aligned,
1319+
&m_cuqp_buffer[0],
1320+
&VABufferNew(VABID_QpBuffer, 0));
1321+
1322+
MFX_CHECK_WITH_ASSERT(VA_STATUS_SUCCESS == vaSts, MFX_ERR_DEVICE_FAILED);
1323+
}
12361324

12371325
{
12381326
// AUD

0 commit comments

Comments
 (0)