@@ -662,6 +662,10 @@ VAAPIEncoder::VAAPIEncoder()
662
662
, m_width(0 )
663
663
, m_height(0 )
664
664
, m_caps()
665
+ , m_cuqp_width(0 )
666
+ , m_cuqp_height(0 )
667
+ , m_cuqp_pitch(0 )
668
+ , m_cuqp_h_aligned(0 )
665
669
{
666
670
}
667
671
@@ -1014,6 +1018,15 @@ mfxStatus VAAPIEncoder::CreateAccelerationService(MfxVideoParam const & par)
1014
1018
1015
1019
DDIHeaderPacker::Reset (par);
1016
1020
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
+ }
1017
1030
1018
1031
1019
1032
return MFX_ERR_NONE;
@@ -1116,6 +1129,68 @@ bool operator!=(const ENCODE_ENC_CTRL_CAPS& l, const ENCODE_ENC_CTRL_CAPS& r)
1116
1129
{
1117
1130
return !(l == r);
1118
1131
}
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
+ }
1119
1194
1120
1195
mfxStatus SetSkipFrame (
1121
1196
VADisplay vaDisplay,
@@ -1175,6 +1250,7 @@ mfxStatus VAAPIEncoder::Execute(Task const & task, mfxHDL surface)
1175
1250
UpdatePPS (task, m_pps, m_reconQueue);
1176
1251
UpdateSlice (task, m_sps, m_pps, m_slice);
1177
1252
1253
+ FillCUQPDataVA (task, m_videoParam, m_cuqp_buffer, m_cuqp_width, m_cuqp_height, m_cuqp_pitch);
1178
1254
mfxU8 skipFlag = ((task.m_ctrl .SkipFrame == 0 ) || (task.m_frameType & MFX_FRAMETYPE_I)) ? 0 : task.m_ctrl .SkipFrame ;
1179
1255
HevcSkipMode skipMode (task.m_SkipMode );
1180
1256
// ------------------------------------------------------------------
@@ -1233,6 +1309,18 @@ mfxStatus VAAPIEncoder::Execute(Task const & task, mfxHDL surface)
1233
1309
}
1234
1310
1235
1311
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
+ }
1236
1324
1237
1325
{
1238
1326
// AUD
0 commit comments