1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file media_ddi_encode_fei_avc.cpp
24 //! \brief Implements class for DDI media avc fei encode
25 //!
26
27 #include "media_libva.h"
28 #include "media_libva_encoder.h"
29 #include "media_libva_util.h"
30 #include "hwinfo_linux.h"
31 #include "media_ddi_encode_base.h"
32 #include "media_ddi_encode_fei_avc.h"
33 #include "media_ddi_encode_const.h"
34 #include "media_ddi_factory.h"
35 static const uint8_t feiMaxPassesNum = 4;
36
37 extern template class MediaDdiFactoryNoArg<DdiEncodeBase>;
38
39 static bool isEncodeAvcFeiRegistered =
40 MediaDdiFactoryNoArg<DdiEncodeBase>::RegisterCodec<DdiEncodeAvcFei>(ENCODE_ID_AVCFEI);
41
~DdiEncodeAvcFei()42 DdiEncodeAvcFei::~DdiEncodeAvcFei()
43 {
44 if (nullptr == m_encodeCtx)
45 {
46 return;
47 }
48 MOS_FreeMemory(m_encodeCtx->pFeiPicParams);
49 m_encodeCtx->pFeiPicParams = nullptr;
50
51 MOS_FreeMemory(m_encodeCtx->pPreEncParams);
52 m_encodeCtx->pPreEncParams = nullptr;
53
54 MOS_FreeMemory(iqMatrixParams);
55 iqMatrixParams = nullptr;
56
57 MOS_FreeMemory(iqWeightScaleLists);
58 iqWeightScaleLists = nullptr;
59
60 }
61
ContextInitialize(CodechalSetting * codecHalSettings)62 VAStatus DdiEncodeAvcFei::ContextInitialize(CodechalSetting * codecHalSettings)
63 {
64 VAStatus status = DdiEncodeAvc::ContextInitialize(codecHalSettings);
65 if (VA_STATUS_SUCCESS != status)
66 {
67 return status;
68 }
69
70 codecHalSettings->codecFunction = m_encodeCtx->codecFunction;
71
72 m_encodeCtx->pFeiPicParams = (void *)MOS_AllocAndZeroMemory(CODEC_AVC_MAX_PPS_NUM * sizeof(CodecEncodeAvcFeiPicParams));
73 DDI_CHK_NULL(m_encodeCtx->pFeiPicParams, "nullptr m_encodeCtx->pFeiPicParams", VA_STATUS_ERROR_ALLOCATION_FAILED);
74
75 m_encodeCtx->pPreEncParams = (void *)MOS_AllocAndZeroMemory(CODEC_AVC_MAX_PPS_NUM * sizeof(FeiPreEncParams));
76 DDI_CHK_NULL(m_encodeCtx->pPreEncParams, "nullptr m_encodeCtx->pPreEncParams", VA_STATUS_ERROR_ALLOCATION_FAILED);
77
78 iqMatrixParams = (PCODEC_AVC_IQ_MATRIX_PARAMS)MOS_AllocAndZeroMemory(sizeof(CODEC_AVC_IQ_MATRIX_PARAMS));
79 DDI_CHK_NULL(iqMatrixParams, "nullptr iqMatrixParams", VA_STATUS_ERROR_ALLOCATION_FAILED);
80
81 iqWeightScaleLists = (PCODEC_AVC_ENCODE_IQ_WEIGTHSCALE_LISTS)MOS_AllocAndZeroMemory(sizeof(CODEC_AVC_ENCODE_IQ_WEIGTHSCALE_LISTS));
82 DDI_CHK_NULL(iqWeightScaleLists, "nullptr iqWeightScaleLists", VA_STATUS_ERROR_ALLOCATION_FAILED);
83
84 return VA_STATUS_SUCCESS;
85 }
86
EncodeInCodecHal(uint32_t numSlices)87 VAStatus DdiEncodeAvcFei::EncodeInCodecHal(uint32_t numSlices)
88 {
89 uint8_t ppsIdx, spsIdx;
90 PCODEC_AVC_ENCODE_PIC_PARAMS picParams;
91
92 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
93 DDI_CHK_NULL(m_encodeCtx->pCodecHal, "nullptr m_encodeCtx->pCodecHal", VA_STATUS_ERROR_INVALID_CONTEXT);
94 DDI_CHK_NULL(m_encodeCtx->pMediaCtx, "nullptr m_encodeCtx->pMediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
95 CodecEncodeAvcFeiPicParams *feiPicParams = (CodecEncodeAvcFeiPicParams *)(m_encodeCtx->pFeiPicParams);
96 FeiPreEncParams *preEncParams = (FeiPreEncParams*)(m_encodeCtx->pPreEncParams);
97
98 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_encodeCtx->RTtbl);
99
100 MOS_STATUS status;
101
102 EncoderParams *encodeParams = &m_encodeCtx->EncodeParams;
103 MOS_ZeroMemory(encodeParams, sizeof(EncoderParams));
104
105 if ((feiPicParams != nullptr) && CodecHalIsFeiEncode(m_encodeCtx->codecFunction))
106 {
107 encodeParams->ExecCodecFunction = m_encodeCtx->codecFunction;
108 }
109 else if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC)
110 {
111 encodeParams->ExecCodecFunction = m_encodeCtx->codecFunction;
112 }
113 else
114 {
115 encodeParams->ExecCodecFunction = CODECHAL_FUNCTION_ENC_PAK;
116 }
117
118 // Raw Surface
119 PMOS_SURFACE rawSurface = &encodeParams->rawSurface;
120 rawSurface->Format = Format_NV12;
121 rawSurface->dwOffset = 0;
122
123 DdiMedia_MediaSurfaceToMosResource(rtTbl->pCurrentRT, &(rawSurface->OsResource));
124
125 if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC)
126 {
127 if (rtTbl->pRT[preEncParams->CurrOriginalPicture.FrameIdx] != rtTbl->pCurrentRT)
128 {
129 DDI_ASSERTMESSAGE("PREENC CurrOriginalPicture.FrameIdx != pCurrentRT");
130 }
131 rawSurface->dwWidth = rawSurface->OsResource.iWidth;
132 rawSurface->dwHeight = rawSurface->OsResource.iHeight;
133 rawSurface->dwPitch = rawSurface->OsResource.iPitch;
134 rawSurface->TileType = rawSurface->OsResource.TileType;
135 rawSurface->TileModeGMM = rawSurface->OsResource.TileModeGMM;
136 rawSurface->bGMMTileEnabled = rawSurface->OsResource.bGMMTileEnabled;
137 preEncParams->psCurrOriginalSurface = rawSurface;
138 encodeParams->pPreEncParams = m_encodeCtx->pPreEncParams;
139 DDI_CHK_RET(ClearRefList(&m_encodeCtx->RTtbl, false), "ClearRefList failed!");
140 }
141 else
142 {
143 // Recon Surface
144 PMOS_SURFACE reconSurface = &encodeParams->reconSurface;
145 reconSurface->Format = Format_NV12;
146 reconSurface->dwOffset = 0;
147
148 DdiMedia_MediaSurfaceToMosResource(rtTbl->pCurrentReconTarget, &(reconSurface->OsResource));
149
150 // Bitstream surface
151 PMOS_RESOURCE bitstreamSurface = &encodeParams->resBitstreamBuffer;
152 *bitstreamSurface = m_encodeCtx->resBitstreamBuffer; // in render picture
153 bitstreamSurface->Format = Format_Buffer;
154
155 encodeParams->psRawSurface = &encodeParams->rawSurface;
156 encodeParams->psReconSurface = &encodeParams->reconSurface;
157 encodeParams->presBitstreamBuffer = &encodeParams->resBitstreamBuffer;
158
159 PMOS_SURFACE mbQpSurface = &encodeParams->mbQpSurface;
160 if (m_encodeCtx->bMBQpEnable)
161 {
162 mbQpSurface->Format = Format_Buffer_2D;
163 mbQpSurface->dwOffset = 0;
164 mbQpSurface->OsResource = m_encodeCtx->resMBQpBuffer;
165 encodeParams->psMbQpDataSurface = &encodeParams->mbQpSurface;
166 encodeParams->bMbQpDataEnabled = true;
167 }
168
169 PMOS_SURFACE disableSkipMapSurface = &encodeParams->disableSkipMapSurface;
170 encodeParams->bMbDisableSkipMapEnabled = m_encodeCtx->bMbDisableSkipMapEnabled;
171 if (encodeParams->bMbDisableSkipMapEnabled)
172 {
173 disableSkipMapSurface->Format = Format_Buffer;
174 disableSkipMapSurface->dwOffset = 0;
175 disableSkipMapSurface->OsResource = m_encodeCtx->resPerMBSkipMapBuffer;
176 encodeParams->psMbDisableSkipMapSurface = &encodeParams->disableSkipMapSurface;
177 }
178
179 // correct some params
180 if (CODECHAL_ENCODE_MODE_AVC == m_encodeCtx->wModeType)
181 {
182 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
183 CODECHAL_ENCODE_AVC_VUI_PARAMS *vuiParam;
184
185 vuiParam = (CODECHAL_ENCODE_AVC_VUI_PARAMS *)m_encodeCtx->pVuiParams;
186 seqParams = (PCODEC_AVC_ENCODE_SEQUENCE_PARAMS)(m_encodeCtx->pSeqParams);
187
188 if (VA_RC_CQP == m_encodeCtx->uiRCMethod)
189 {
190 vuiParam->bit_rate_value_minus1[0] = 0;
191 vuiParam->cpb_size_value_minus1[0] = 0;
192 seqParams->TargetBitRate = 0;
193 seqParams->MaxBitRate = 0;
194 seqParams->MinBitRate = 0;
195 seqParams->InitVBVBufferFullnessInBit = 0;
196 seqParams->VBVBufferSizeInBit = 0;
197 }
198
199 encodeParams->uiSlcStructCaps = CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE;
200 }
201
202 ppsIdx = ((PCODEC_AVC_ENCODE_SLICE_PARAMS)(m_encodeCtx->pSliceParams))->pic_parameter_set_id;
203 picParams = (PCODEC_AVC_ENCODE_PIC_PARAMS)m_encodeCtx->pPicParams + ppsIdx;
204 spsIdx = picParams->seq_parameter_set_id;
205 encodeParams->pSeqParams = (PCODEC_AVC_ENCODE_SEQUENCE_PARAMS)m_encodeCtx->pSeqParams + spsIdx;
206 encodeParams->pPicParams = picParams;
207 encodeParams->pVuiParams = m_encodeCtx->pVuiParams;
208 encodeParams->pSliceParams = m_encodeCtx->pSliceParams;
209 encodeParams->pAVCQCParams = m_qcParams;
210 encodeParams->pAVCRoundingParams = m_roundingParams;
211
212 // Sequence data
213 encodeParams->bNewSeq = m_encodeCtx->bNewSeq;
214 // VUI
215 encodeParams->bNewVuiData = m_encodeCtx->bNewVuiData;
216
217 // Slice level data
218 encodeParams->dwNumSlices = numSlices;
219
220 // IQmatrix params
221 encodeParams->bNewQmatrixData = m_encodeCtx->bNewQmatrixData;
222 encodeParams->bPicQuant = m_encodeCtx->bPicQuant;
223 encodeParams->ppNALUnitParams = m_encodeCtx->ppNALUnitParams;
224 encodeParams->pSeiData = m_encodeCtx->pSEIFromApp;
225 encodeParams->pSeiParamBuffer = m_encodeCtx->pSEIFromApp->pSEIBuffer;
226 encodeParams->dwSEIDataOffset = 0;
227
228 status = MOS_SecureMemcpy(&iqMatrixParams->ScalingList4x4,
229 6 * 16 * sizeof(uint8_t),
230 &m_scalingLists4x4,
231 6 * 16 * sizeof(uint8_t));
232 if (MOS_STATUS_SUCCESS != status)
233 {
234 DDI_ASSERTMESSAGE("DDI:Failed to copy scaling list 4x4!");
235 return VA_STATUS_ERROR_INVALID_PARAMETER;
236 }
237
238 status = MOS_SecureMemcpy(&iqMatrixParams->ScalingList8x8,
239 2 * 64 * sizeof(uint8_t),
240 &m_scalingLists8x8,
241 2 * 64 * sizeof(uint8_t));
242 if (MOS_STATUS_SUCCESS != status)
243 {
244 DDI_ASSERTMESSAGE("DDI:Failed to copy scaling list 8x8!");
245 return VA_STATUS_ERROR_INVALID_PARAMETER;
246 }
247
248 encodeParams->pIQMatrixBuffer = iqMatrixParams;
249
250 status = MOS_SecureMemcpy(&iqWeightScaleLists->WeightScale4x4,
251 (CODEC_AVC_WEIGHT_SCALE_4x4 * sizeof(uint32_t)),
252 &m_weightScale4x4,
253 (CODEC_AVC_WEIGHT_SCALE_4x4 * sizeof(uint32_t)));
254 if (MOS_STATUS_SUCCESS != status)
255 {
256 DDI_ASSERTMESSAGE("DDI:Failed to copy weight scale list 4x4!");
257 return VA_STATUS_ERROR_INVALID_PARAMETER;
258 }
259
260 status = MOS_SecureMemcpy(&iqWeightScaleLists->WeightScale8x8,
261 (CODEC_AVC_WEIGHT_SCALE_8x8 * sizeof(uint32_t)),
262 &m_weightScale8x8,
263 (CODEC_AVC_WEIGHT_SCALE_8x8 * sizeof(uint32_t)));
264 if (MOS_STATUS_SUCCESS != status)
265 {
266 DDI_ASSERTMESSAGE("DDI:Failed to copy weight scale list 8x8!");
267 return VA_STATUS_ERROR_INVALID_PARAMETER;
268 }
269
270 encodeParams->pIQWeightScaleLists = iqWeightScaleLists;
271
272 // whether driver need to pack slice header
273 if (true == m_encodeCtx->bHavePackedSliceHdr)
274 {
275 encodeParams->bAcceleratorHeaderPackingCaps = false;
276 }
277 else
278 {
279 encodeParams->bAcceleratorHeaderPackingCaps = true;
280 }
281
282 encodeParams->pBSBuffer = m_encodeCtx->pbsBuffer;
283 encodeParams->pSlcHeaderData = (void *)m_encodeCtx->pSliceHeaderData;
284 encodeParams->pFeiPicParams = (CodecEncodeAvcFeiPicParams *)(m_encodeCtx->pFeiPicParams);
285 //clear registered recon/ref surface flags
286 DDI_CHK_RET(ClearRefList(&m_encodeCtx->RTtbl, true), "ClearRefList failed!");
287 }
288
289 CodechalEncoderState *encoder = dynamic_cast<CodechalEncoderState *>(m_encodeCtx->pCodecHal);
290 DDI_CHK_NULL(encoder, "nullptr Codechal encode", VA_STATUS_ERROR_INVALID_PARAMETER);
291
292 if (!encoder->m_mfeEnabled)
293 {
294 status = m_encodeCtx->pCodecHal->Execute(encodeParams);
295 if (MOS_STATUS_SUCCESS != status)
296 {
297 DDI_ASSERTMESSAGE("DDI:Failed in Codechal!");
298 return VA_STATUS_ERROR_ENCODING_ERROR;
299 }
300 }
301
302 return VA_STATUS_SUCCESS;
303 }
304
ResetAtFrameLevel()305 VAStatus DdiEncodeAvcFei::ResetAtFrameLevel()
306 {
307 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
308 DDI_CHK_NULL(m_encodeCtx->pFeiPicParams, "nullptr m_encodeCtx->pFeiPicParams", VA_STATUS_ERROR_INVALID_PARAMETER);
309 DDI_CHK_NULL(m_encodeCtx->pPreEncParams, "nullptr m_encodeCtx->pPreEncParams", VA_STATUS_ERROR_INVALID_PARAMETER);
310
311 // Assume there is only one SPS parameter
312 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_AVC_ENCODE_SEQUENCE_PARAMS)(m_encodeCtx->pSeqParams);
313 seqParams->bInitBRC = 0x0;
314 seqParams->bResetBRC = 0x0;
315 CodecEncodeAvcFeiPicParams *feiPicParams = (CodecEncodeAvcFeiPicParams *)(m_encodeCtx->pFeiPicParams);
316 FeiPreEncParams *preEncParams = (FeiPreEncParams*)(m_encodeCtx->pPreEncParams);
317
318 m_encodeCtx->dwNumSlices = 0x0;
319 m_encodeCtx->indexNALUnit = 0x0;
320 m_encodeCtx->uiSliceHeaderCnt = 0x0;
321
322 // reset bsbuffer every frame
323 m_encodeCtx->pbsBuffer->pCurrent = m_encodeCtx->pbsBuffer->pBase;
324 m_encodeCtx->pbsBuffer->SliceOffset = 0x0;
325 m_encodeCtx->pbsBuffer->BitOffset = 0x0;
326 m_encodeCtx->pbsBuffer->BitSize = 0x0;
327
328 // clear the packed header information
329 if (nullptr != m_encodeCtx->ppNALUnitParams)
330 {
331 MOS_ZeroMemory(m_encodeCtx->ppNALUnitParams[0], sizeof(CODECHAL_NAL_UNIT_PARAMS) * CODECHAL_ENCODE_AVC_MAX_NAL_TYPE);
332 }
333
334 m_encodeCtx->bHavePackedSliceHdr = false;
335 m_encodeCtx->bLastPackedHdrIsSlice = false;
336 m_encodeCtx->bMbDisableSkipMapEnabled = false;
337 m_encodeCtx->bMBQpEnable = false;
338
339 if (nullptr != m_roundingParams)
340 {
341 MOS_ZeroMemory(m_roundingParams, sizeof(CODECHAL_ENCODE_AVC_ROUNDING_PARAMS));
342 }
343
344 if (CodecHalIsFeiEncode(m_encodeCtx->codecFunction) && m_encodeCtx->codecFunction != CODECHAL_FUNCTION_FEI_PRE_ENC)
345 {
346 m_encodeCtx->codecFunction = CODECHAL_FUNCTION_FEI_ENC_PAK;
347 feiPicParams->NumMVPredictorsL0 = 0; // number of MV Predictors L0 provided, max is 4
348 feiPicParams->NumMVPredictorsL1 = 0; // number of MV Predictors L1 provided, max is 2
349 feiPicParams->SearchPath = 0; // search path, default is 0, 0 and 2 mean full search, 1 means diamond search
350 feiPicParams->LenSP = 57; // max number of SUs per reference which is evaluated by the predetermined SUs, range is [1, 63]
351 feiPicParams->SubMBPartMask = 0x77; // the bit-mask for disabling sub-partition, bit 0 16x16, bit 1 16x8, bit 2 8x16 ... default value is 1110111b
352 feiPicParams->IntraPartMask = 0; // luma intra partition mask bits, bit 0 16x16, bit 1 8x8, bit 2 4x4
353 feiPicParams->MultiPredL0 = false; // true neighbor MV will be used as predictori for L0, false will not.
354 feiPicParams->MultiPredL1 = false; // true neighbor MV will be used as predictori for L0, false will not.
355 feiPicParams->SubPelMode = 3; // half/quater pixels mode, 00b integer mode search, 01b half mode search, 11b quater mode search
356 feiPicParams->InterSAD = 2;
357 feiPicParams->IntraSAD = 2;
358 feiPicParams->DistortionType = 0; // output distortion type, 0 raw distortion without cost, 1 distortion with cost
359 feiPicParams->RepartitionCheckEnable = false; // true, enables the additional calls on Fraction & Bidirectional Refinement
360 feiPicParams->AdaptiveSearch = true; // whether adaptive searching is enabled for IME
361 feiPicParams->MVPredictorEnable = false; // if enable MV Predictor input
362 feiPicParams->bMBQp = false; // if enable MB per QP input
363 feiPicParams->bPerMBInput = false; // if enable per MB control/special input
364 feiPicParams->bMBSizeCtrl = false; // if enable MB size control when enabled per MB special input
365 feiPicParams->RefWidth = 48;
366 feiPicParams->RefHeight = 40;
367 feiPicParams->SearchWindow = 0;
368
369 feiPicParams->DistortionEnable = false;
370 feiPicParams->MbCodeMvEnable = false;
371 }
372
373 if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC)
374 {
375 preEncParams->dwNumPastReferences = 1; // Number of past reference frame
376 preEncParams->dwNumFutureReferences = 0; // Number of future reference frame
377 MOS_ZeroMemory(&(preEncParams->CurrOriginalPicture), sizeof(CODEC_PICTURE));
378 MOS_ZeroMemory(&(preEncParams->PastRefPicture), sizeof(CODEC_PICTURE));
379 MOS_ZeroMemory(&(preEncParams->FutureRefPicture), sizeof(CODEC_PICTURE));
380
381 preEncParams->dwFrameQp = 25; // Frame level QP
382 preEncParams->dwLenSP = 57; // max number of SUs per reference which is evaluated by the predetermined SUs, range is [1, 63]
383 preEncParams->dwSearchPath = 0; // search path, default is 0, 0 and 2 mean full search, 1 means diamond search
384 preEncParams->dwSubMBPartMask = 0x77; // the bit-mask for disabling sub-partition, bit 0 16x16, bit 1 16x8, bit 2 8x16 ... default value is 1110111b
385 preEncParams->dwIntraPartMask = 0;
386 preEncParams->dwSubPelMode = 3; // half/quater pixels mode, 00b integer mode search, 01b half mode search, 11b quater mode search
387 preEncParams->dwInterSAD = 2;
388 preEncParams->dwIntraSAD = 2;
389 preEncParams->bAdaptiveSearch = 1; // whether adaptive searching is enabled for IME
390 preEncParams->dwMVPredictorCtrl = 0; // MV predictor control, 0, disable, 1, enabled for past reference, 2, enabled for future reference, 3 enabled for both
391 preEncParams->bMBQp = false; // if enable MB per QP input
392 preEncParams->bFTEnable = false; // if use provided QP (frame level QP and per MB QP) and obtained MV to judge the number of non zero coefficients
393 preEncParams->dwRefWidth = 48;
394 preEncParams->dwRefHeight = 40;
395 preEncParams->dwSearchWindow = 0; // defines predefined search windows, 0, disable
396 // 1, Tiny 4 SUs 24x24 windows
397 // 2, small 9 SUs 28x28 windows
398 // 3, diamond 16 SUs 48x40 windows
399 // 4, large diamon 32SUs 48x40 windows
400 // 5, exhaustive 48SUs 48x40 windows
401 preEncParams->bDisableMVOutput = false; // if disable MV output buffer
402 preEncParams->bDisableStatisticsOutput = false; // if disable Statisticts output buffer
403 preEncParams->bEnable8x8Statistics = false; // if enable, generate block8x8 average and variance output
404 }
405
406 return VA_STATUS_SUCCESS;
407 }
408
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)409 VAStatus DdiEncodeAvcFei::RenderPicture(
410 VADriverContextP ctx,
411 VAContextID context,
412 VABufferID *buffers,
413 int32_t numBuffers)
414 {
415 DDI_FUNCTION_ENTER();
416
417 DDI_CHK_NULL(ctx, "nullptr context in vpgEncodeRenderPicture!", VA_STATUS_ERROR_INVALID_CONTEXT);
418 PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
419 DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
420
421 // assume the VAContextID is encoder ID
422 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
423
424 uint32_t numSlices = 0;
425 VAStatus vaStatus = VA_STATUS_SUCCESS;
426
427 DDI_MEDIA_BUFFER *buf;
428 void *data;
429 uint32_t dataSize;
430 for (int32_t i = 0; i < numBuffers; i++)
431 {
432 buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffers[i]);
433 DDI_CHK_NULL(buf, "Invalid buffer.", VA_STATUS_ERROR_INVALID_BUFFER);
434 if (buf->uiType == VAEncMacroblockDisableSkipMapBufferType)
435 {
436 DdiMedia_MediaBufferToMosResource(buf, &(m_encodeCtx->resPerMBSkipMapBuffer));
437 m_encodeCtx->bMbDisableSkipMapEnabled = true;
438 continue;
439 }
440 dataSize = buf->iSize;
441 // can use internal function instead of DdiMedia_MapBuffer here?
442 DdiMedia_MapBuffer(ctx, buffers[i], &data);
443
444 DDI_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_BUFFER);
445
446 switch (buf->uiType)
447 {
448 case VAIQMatrixBufferType:
449 case VAQMatrixBufferType:
450 DDI_CHK_STATUS(Qmatrix(data), VA_STATUS_ERROR_INVALID_BUFFER);
451 break;
452
453 case VAEncSequenceParameterBufferType:
454 DDI_CHK_STATUS(ParseSeqParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
455 m_encodeCtx->bNewSeq = true;
456 break;
457
458 case VAEncPictureParameterBufferType:
459 DDI_CHK_STATUS(ParsePicParams(mediaCtx, data), VA_STATUS_ERROR_INVALID_BUFFER);
460
461 // it should use pFeiPicParams->function, but it may be still not set here yet
462 if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC)
463 break;
464
465 DDI_CHK_STATUS(
466 AddToStatusReportQueue((void *)m_encodeCtx->resBitstreamBuffer.bo),
467 VA_STATUS_ERROR_INVALID_BUFFER);
468 break;
469
470 case VAEncSliceParameterBufferType:
471 numSlices = buf->uiNumElements;
472 DDI_CHK_STATUS(ParseSlcParams(mediaCtx, data, numSlices), VA_STATUS_ERROR_INVALID_BUFFER);
473 break;
474
475 case VAEncPackedHeaderParameterBufferType:
476 DDI_CHK_STATUS(ParsePackedHeaderParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
477 break;
478
479 case VAEncPackedHeaderDataBufferType:
480 vaStatus = ParsePackedHeaderData(data);
481 break;
482
483 case VAEncMiscParameterBufferType:
484 DDI_CHK_STATUS(ParseMiscParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
485 break;
486
487 case VAEncQPBufferType:
488 DdiMedia_MediaBufferToMosResource(buf, &m_encodeCtx->resMBQpBuffer);
489 m_encodeCtx->bMBQpEnable = true;
490 break;
491
492 case VAStatsStatisticsParameterBufferType:
493 DDI_CHK_STATUS(ParseStatsParams(mediaCtx, data), VA_STATUS_ERROR_INVALID_BUFFER);
494 break;
495
496 case VAEncFEIMBControlBufferType:
497 case VAEncFEIMVPredictorBufferType:
498 case VAEncFEIMVBufferType:
499 case VAEncFEIMBCodeBufferType:
500 case VAEncFEIDistortionBufferType:
501 case VAStatsMVPredictorBufferType:
502 case VAStatsStatisticsBufferType:
503 case VAStatsStatisticsBottomFieldBufferType:
504 case VAStatsMVBufferType:
505 {
506 // handled in VAEncMiscParameterBufferType/VAEncMiscParameterTypeFEIFrameControlIntel case by vaBufferID
507 break;
508 }
509 default:
510 DDI_ASSERTMESSAGE("not supported buffer type in vpgEncodeRenderPicture.");
511 // vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
512 break;
513 }
514 DdiMedia_UnmapBuffer(ctx, buffers[i]);
515 }
516
517 DDI_FUNCTION_EXIT(vaStatus);
518 return vaStatus;
519 }
520
ParseMiscParamFeiPic(void * data)521 VAStatus DdiEncodeAvcFei::ParseMiscParamFeiPic(void *data)
522 {
523 DDI_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
524 CodecEncodeAvcFeiPicParams *feiPicParams = (CodecEncodeAvcFeiPicParams *)(m_encodeCtx->pFeiPicParams);
525 DDI_CHK_NULL(feiPicParams, "nullptr feiPicParams", VA_STATUS_ERROR_INVALID_PARAMETER);
526 VAEncMiscParameterFEIFrameControlH264 *vaEncMiscParamFeiPic = (VAEncMiscParameterFEIFrameControlH264*)data;
527
528 m_encodeCtx->codecFunction = CODECHAL_FUNCTION_INVALID;
529 if (vaEncMiscParamFeiPic->function & VA_FEI_FUNCTION_ENC_PAK)
530 m_encodeCtx->codecFunction = CODECHAL_FUNCTION_FEI_ENC_PAK;
531 if (vaEncMiscParamFeiPic->function == VA_FEI_FUNCTION_ENC)
532 m_encodeCtx->codecFunction = CODECHAL_FUNCTION_FEI_ENC;
533 if (vaEncMiscParamFeiPic->function == VA_FEI_FUNCTION_PAK)
534 m_encodeCtx->codecFunction = CODECHAL_FUNCTION_FEI_PAK;
535
536 feiPicParams->NumMVPredictorsL0 = vaEncMiscParamFeiPic->num_mv_predictors_l0;
537 feiPicParams->NumMVPredictorsL1 = vaEncMiscParamFeiPic->num_mv_predictors_l1;
538 feiPicParams->SearchPath = vaEncMiscParamFeiPic->search_path;
539 feiPicParams->LenSP = vaEncMiscParamFeiPic->len_sp;
540 feiPicParams->SubMBPartMask = vaEncMiscParamFeiPic->sub_mb_part_mask;
541 feiPicParams->IntraPartMask = vaEncMiscParamFeiPic->intra_part_mask;
542 feiPicParams->MultiPredL0 = vaEncMiscParamFeiPic->multi_pred_l0;
543 feiPicParams->MultiPredL1 = vaEncMiscParamFeiPic->multi_pred_l1;
544 feiPicParams->SubPelMode = vaEncMiscParamFeiPic->sub_pel_mode;
545 feiPicParams->InterSAD = vaEncMiscParamFeiPic->inter_sad;
546 feiPicParams->IntraSAD = vaEncMiscParamFeiPic->intra_sad;
547 feiPicParams->DistortionType = vaEncMiscParamFeiPic->distortion_type;
548 feiPicParams->RepartitionCheckEnable = vaEncMiscParamFeiPic->repartition_check_enable;
549 feiPicParams->AdaptiveSearch = vaEncMiscParamFeiPic->adaptive_search;
550 feiPicParams->MVPredictorEnable = vaEncMiscParamFeiPic->mv_predictor_enable;
551 feiPicParams->bMBQp = vaEncMiscParamFeiPic->mb_qp;
552 feiPicParams->bPerMBInput = vaEncMiscParamFeiPic->mb_input;
553 feiPicParams->bMBSizeCtrl = vaEncMiscParamFeiPic->mb_size_ctrl;
554 feiPicParams->RefWidth = vaEncMiscParamFeiPic->ref_width;
555 feiPicParams->RefHeight = vaEncMiscParamFeiPic->ref_height;
556 feiPicParams->SearchWindow = vaEncMiscParamFeiPic->search_window;
557
558 DDI_MEDIA_BUFFER *mediaBuffer;
559 VAStatus status = VA_STATUS_SUCCESS;
560 if (feiPicParams->bPerMBInput)
561 {
562 mediaBuffer = DdiMedia_GetBufferFromVABufferID(m_encodeCtx->pMediaCtx, vaEncMiscParamFeiPic->mb_ctrl);
563 DDI_CHK_NULL(mediaBuffer, "nullptr mediaBuffer", VA_STATUS_ERROR_INVALID_PARAMETER);
564 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(feiPicParams->resMBCtrl));
565 }
566 if (feiPicParams->MVPredictorEnable == 1)
567 {
568 mediaBuffer = DdiMedia_GetBufferFromVABufferID(m_encodeCtx->pMediaCtx, vaEncMiscParamFeiPic->mv_predictor);
569 DDI_CHK_NULL(mediaBuffer, "nullptr mediaBuffer", VA_STATUS_ERROR_INVALID_PARAMETER);
570 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(feiPicParams->resMVPredictor));
571 }
572 else if ((feiPicParams->NumMVPredictorsL0 != 0) || (feiPicParams->NumMVPredictorsL1 != 0))
573 {
574 DDI_ASSERTMESSAGE("feiPicParams->NumMVPredictorsL0 and NumMVPredictorsL1 should be set to 0 when feiPicParams->MVPredictorEnable is false!");
575 status = VA_STATUS_ERROR_INVALID_PARAMETER;
576 }
577 if (feiPicParams->bMBQp)
578 {
579 mediaBuffer = DdiMedia_GetBufferFromVABufferID(m_encodeCtx->pMediaCtx, vaEncMiscParamFeiPic->qp);
580 DDI_CHK_NULL(mediaBuffer, "nullptr mediaBuffer", VA_STATUS_ERROR_INVALID_PARAMETER);
581 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(feiPicParams->resMBQp));
582 }
583
584 feiPicParams->MbCodeMvEnable = false;
585 if (vaEncMiscParamFeiPic->mv_data != VA_INVALID_ID)
586 {
587 feiPicParams->MbCodeMvEnable = true;
588 mediaBuffer = DdiMedia_GetBufferFromVABufferID(m_encodeCtx->pMediaCtx, vaEncMiscParamFeiPic->mv_data);
589 DDI_CHK_NULL(mediaBuffer, "nullptr mediaBuffer", VA_STATUS_ERROR_INVALID_PARAMETER);
590 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(feiPicParams->resMVData));
591 if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC)
592 {
593 RemoveFromEncStatusReportQueue(mediaBuffer, FEI_ENC_BUFFER_TYPE_MVDATA);
594 if (VA_STATUS_SUCCESS != AddToEncStatusReportQueue((void *)(feiPicParams->resMVData.bo), FEI_ENC_BUFFER_TYPE_MVDATA))
595 {
596 DDI_ASSERTMESSAGE("feiPicParams->resMVData is invalid for FEI ENC only");
597 status = VA_STATUS_ERROR_INVALID_PARAMETER;
598 }
599 }
600 }
601 if (vaEncMiscParamFeiPic->mb_code_data != VA_INVALID_ID)
602 {
603 if (feiPicParams->MbCodeMvEnable == false)
604 {
605 DDI_ASSERTMESSAGE("MV data and MB Code should be enabled or disabled together!");
606 status = MOS_STATUS_INVALID_PARAMETER;
607 }
608 mediaBuffer = DdiMedia_GetBufferFromVABufferID(m_encodeCtx->pMediaCtx, vaEncMiscParamFeiPic->mb_code_data);
609 DDI_CHK_NULL(mediaBuffer, "nullptr mediaBuffer", VA_STATUS_ERROR_INVALID_PARAMETER);
610 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(feiPicParams->resMBCode));
611 if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC)
612 {
613 RemoveFromEncStatusReportQueue(mediaBuffer, FEI_ENC_BUFFER_TYPE_MBCODE);
614 if (MOS_STATUS_SUCCESS != AddToEncStatusReportQueue((void *)(feiPicParams->resMBCode.bo), FEI_ENC_BUFFER_TYPE_MBCODE))
615 {
616 DDI_ASSERTMESSAGE("feiPicParams->resMBCode is invalid for FEI ENC only");
617 status = VA_STATUS_ERROR_INVALID_PARAMETER;
618 }
619 }
620 }
621 if (vaEncMiscParamFeiPic->distortion != VA_INVALID_ID)
622 {
623 feiPicParams->DistortionEnable = true;
624 mediaBuffer = DdiMedia_GetBufferFromVABufferID(m_encodeCtx->pMediaCtx, vaEncMiscParamFeiPic->distortion);
625 DDI_CHK_NULL(mediaBuffer, "nullptr mediaBuffer", VA_STATUS_ERROR_INVALID_PARAMETER);
626 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(feiPicParams->resDistortion));
627 if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC)
628 {
629 RemoveFromEncStatusReportQueue(mediaBuffer, FEI_ENC_BUFFER_TYPE_DISTORTION);
630 if (MOS_STATUS_SUCCESS != AddToEncStatusReportQueue((void *)(feiPicParams->resDistortion.bo), FEI_ENC_BUFFER_TYPE_DISTORTION))
631 {
632 DDI_ASSERTMESSAGE("feiPicParams->resDistortion is invalid for FEI ENC only");
633 status = VA_STATUS_ERROR_INVALID_PARAMETER;
634 }
635 }
636 }
637 if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC)
638 {
639 AddToEncStatusReportQueueUpdatePos();
640 }
641
642 //add for mutlple pass pak
643 feiPicParams->dwMaxFrameSize = vaEncMiscParamFeiPic->max_frame_size;
644 if (feiPicParams->dwMaxFrameSize)
645 {
646 feiPicParams->dwNumPasses = vaEncMiscParamFeiPic->num_passes;
647 if ((feiPicParams->dwNumPasses == 0) || (feiPicParams->dwNumPasses > feiMaxPassesNum))
648 {
649 return VA_STATUS_ERROR_INVALID_PARAMETER;
650 }
651 if (feiPicParams->pDeltaQp != nullptr)
652 {
653 MOS_FreeMemory(feiPicParams->pDeltaQp);
654 }
655 feiPicParams->pDeltaQp = (uint8_t *)MOS_AllocAndZeroMemory(sizeof(uint8_t) * feiPicParams->dwNumPasses);
656 if (!feiPicParams->pDeltaQp)
657 {
658 return VA_STATUS_ERROR_INVALID_PARAMETER;
659 }
660
661 if (MOS_STATUS_SUCCESS != MOS_SecureMemcpy(feiPicParams->pDeltaQp, feiPicParams->dwNumPasses, vaEncMiscParamFeiPic->delta_qp, feiPicParams->dwNumPasses))
662 {
663 status = VA_STATUS_ERROR_INVALID_PARAMETER;
664 }
665 }
666
667 return status;
668 }
669
AddToEncStatusReportQueue(void * encBuf,DDI_ENCODE_FEI_ENC_BUFFER_TYPE typeIdx)670 VAStatus DdiEncodeAvcFei::AddToEncStatusReportQueue(
671 void *encBuf,
672 DDI_ENCODE_FEI_ENC_BUFFER_TYPE typeIdx)
673 {
674 DDI_CHK_NULL(encBuf, "nullptr encBuf", VA_STATUS_ERROR_INVALID_PARAMETER);
675
676 CodecEncodeAvcFeiPicParams *feiPicParams = (CodecEncodeAvcFeiPicParams *)(m_encodeCtx->pFeiPicParams);
677 DDI_CHK_NULL(feiPicParams, "nullptr feiPicParams", VA_STATUS_ERROR_INVALID_PARAMETER);
678
679 if (m_encodeCtx->codecFunction != CODECHAL_FUNCTION_FEI_ENC)
680 {
681 DDI_ASSERTMESSAGE("ENC output buffers status checking is not allowed for non-FEI_ENC case! .");
682 return VA_STATUS_ERROR_INVALID_PARAMETER;
683 }
684 if ((typeIdx < 0) || (typeIdx >= FEI_ENC_BUFFER_TYPE_MAX))
685 {
686 DDI_ASSERTMESSAGE("ENC output buffers status checking, gets invalid buffer type index! .");
687 return VA_STATUS_ERROR_INVALID_PARAMETER;
688 }
689
690 int32_t idx = m_encodeCtx->statusReportBuf.ulHeadPosition;
691 m_encodeCtx->statusReportBuf.encInfos[idx].pEncBuf[typeIdx] = encBuf;
692 m_encodeCtx->statusReportBuf.encInfos[idx].uiStatus = 0;
693 m_encodeCtx->statusReportBuf.encInfos[idx].uiBuffers++;
694
695 return VA_STATUS_SUCCESS;
696 }
697
AddToEncStatusReportQueueUpdatePos()698 VAStatus DdiEncodeAvcFei::AddToEncStatusReportQueueUpdatePos()
699 {
700 CodecEncodeAvcFeiPicParams *feiPicParams = (CodecEncodeAvcFeiPicParams *)(m_encodeCtx->pFeiPicParams);
701 DDI_CHK_NULL(feiPicParams, "nullptr feiPicParams", VA_STATUS_ERROR_INVALID_PARAMETER);
702
703 if (m_encodeCtx->codecFunction != CODECHAL_FUNCTION_FEI_ENC)
704 {
705 DDI_ASSERTMESSAGE("ENC output buffers status checking is not allowed for non-FEI_ENC case! .");
706 return VA_STATUS_ERROR_INVALID_PARAMETER;
707 }
708
709 int32_t i = m_encodeCtx->statusReportBuf.ulHeadPosition;
710 if ((m_encodeCtx->statusReportBuf.encInfos[i].uiBuffers == (feiPicParams->MbCodeMvEnable * 2 + feiPicParams->DistortionEnable)) &&
711 m_encodeCtx->statusReportBuf.encInfos[i].uiBuffers != 0)
712 {
713 m_encodeCtx->statusReportBuf.ulHeadPosition = (m_encodeCtx->statusReportBuf.ulHeadPosition + 1) % DDI_ENCODE_MAX_STATUS_REPORT_BUFFER;
714 }
715
716 return VA_STATUS_SUCCESS;
717 }
718
AddToPreEncStatusReportQueue(void * preEncBuf,DDI_ENCODE_PRE_ENC_BUFFER_TYPE typeIdx)719 VAStatus DdiEncodeAvcFei::AddToPreEncStatusReportQueue(
720 void *preEncBuf,
721 DDI_ENCODE_PRE_ENC_BUFFER_TYPE typeIdx)
722 {
723 DDI_CHK_NULL(preEncBuf, "nullptr preEncBuf", VA_STATUS_ERROR_INVALID_PARAMETER);
724
725 if (m_encodeCtx->codecFunction != CODECHAL_FUNCTION_FEI_PRE_ENC)
726 {
727 DDI_ASSERTMESSAGE("PRE ENC output buffers status checking is not allowed for non-PRE_ENC case! .");
728 return VA_STATUS_ERROR_INVALID_PARAMETER;
729 }
730 if ((typeIdx < 0) || (typeIdx >= PRE_ENC_BUFFER_TYPE_MAX))
731 {
732 DDI_ASSERTMESSAGE("PRE ENC output buffers status checking, gets invalid buffer type index! .");
733 return VA_STATUS_ERROR_INVALID_PARAMETER;
734 }
735
736 int32_t i = m_encodeCtx->statusReportBuf.ulHeadPosition;
737 m_encodeCtx->statusReportBuf.preencInfos[i].pPreEncBuf[typeIdx] = preEncBuf;
738 m_encodeCtx->statusReportBuf.preencInfos[i].uiStatus = 0;
739 m_encodeCtx->statusReportBuf.preencInfos[i].uiBuffers++;
740
741 return VA_STATUS_SUCCESS;
742 }
743
AddToPreEncStatusReportQueueUpdatePos()744 VAStatus DdiEncodeAvcFei::AddToPreEncStatusReportQueueUpdatePos()
745 {
746 FeiPreEncParams *preEncParams = (FeiPreEncParams*)(m_encodeCtx->pPreEncParams);
747 DDI_CHK_NULL(preEncParams, "nullptr preEncParams", VA_STATUS_ERROR_INVALID_PARAMETER);
748
749 if (m_encodeCtx->codecFunction != CODECHAL_FUNCTION_FEI_PRE_ENC)
750 {
751 DDI_ASSERTMESSAGE("PRE ENC output buffers status checking is not allowed for non-PRE_ENC case! .");
752 return VA_STATUS_ERROR_INVALID_PARAMETER;
753 }
754
755 uint32_t numBuffers = (!preEncParams->bInterlaced) ? (2 - preEncParams->bDisableMVOutput - preEncParams->bDisableStatisticsOutput)
756 : (3 - preEncParams->bDisableMVOutput - 2 * preEncParams->bDisableStatisticsOutput);
757 int32_t i = m_encodeCtx->statusReportBuf.ulHeadPosition;
758 if ((m_encodeCtx->statusReportBuf.preencInfos[i].uiBuffers == numBuffers) &&
759 m_encodeCtx->statusReportBuf.preencInfos[i].uiBuffers != 0)
760 {
761 m_encodeCtx->statusReportBuf.ulHeadPosition = (m_encodeCtx->statusReportBuf.ulHeadPosition + 1) % DDI_ENCODE_MAX_STATUS_REPORT_BUFFER;
762 }
763
764 return VA_STATUS_SUCCESS;
765 }
766
ParseMiscParams(void * ptr)767 VAStatus DdiEncodeAvcFei::ParseMiscParams(void *ptr)
768 {
769 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
770 DDI_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
771
772 VAEncMiscParameterBuffer *miscParamBuf = (VAEncMiscParameterBuffer *)ptr;
773 DDI_CHK_NULL(miscParamBuf->data, "nullptr miscParamBuf->data", VA_STATUS_ERROR_INVALID_PARAMETER);
774
775 VAStatus status = MOS_STATUS_SUCCESS;
776 switch ((int32_t)(miscParamBuf->type))
777 {
778 case VAEncMiscParameterTypeHRD:
779 status = ParseMiscParamHRD((void *)miscParamBuf->data);
780 break;
781
782 case VAEncMiscParameterTypeFrameRate:
783 status = ParseMiscParamFR((void *)miscParamBuf->data);
784 break;
785
786 case VAEncMiscParameterTypeRateControl:
787 status = ParseMiscParamRC((void *)miscParamBuf->data);
788 break;
789
790 case VAEncMiscParameterTypeEncQuality:
791 status = ParseMiscParamEncQuality((void *)miscParamBuf->data);
792 break;
793
794 case VAEncMiscParameterTypeQuantization:
795 status = ParseMiscParamQuantization((void *)miscParamBuf->data);
796 break;
797
798 case VAEncMiscParameterTypeRIR:
799 status = ParseMiscParameterRIR((void *)miscParamBuf->data);
800 break;
801
802 case VAEncMiscParameterTypeSkipFrame:
803 status = ParseMiscParamSkipFrame((void *)miscParamBuf->data);
804 break;
805
806 case VAEncMiscParameterTypeMaxFrameSize:
807 status = ParseMiscParamMaxFrameSize((void *)miscParamBuf->data);
808 break;
809
810 case VAEncMiscParameterTypeQualityLevel:
811 status = ParseMiscParamQualityLevel((void *)miscParamBuf->data);
812 break;
813
814 case VAEncMiscParameterTypeMaxSliceSize:
815 status = ParseMiscParamMaxSliceSize((void *)miscParamBuf->data);
816 break;
817
818 case VAEncMiscParameterTypeROI:
819 status = ParseMiscParamROI((void *)miscParamBuf->data);
820 break;
821
822 case VAEncMiscParameterTypeFEIFrameControl:
823 status = ParseMiscParamFeiPic((void *)miscParamBuf->data);
824 break;
825
826 case VAEncMiscParameterTypeDirtyRect:
827 status = ParseMiscParamDirtyROI((void *)miscParamBuf->data);
828 break;
829
830 case VAEncMiscParameterTypeCustomRoundingControl:
831 status = ParseMiscParamRounding((void *)miscParamBuf->data);
832 break;
833
834 case VAEncMiscParameterTypeSubMbPartPel:
835 status = ParseMiscParamSubMbPartPel((void *)miscParamBuf->data);
836 break;
837
838 default:
839 DDI_ASSERTMESSAGE("unsupported misc parameter type.");
840 status = VA_STATUS_ERROR_INVALID_PARAMETER;
841 break;
842 }
843
844 return status;
845 }
846
ParseStatsParams(PDDI_MEDIA_CONTEXT mediaCtx,void * ptr)847 VAStatus DdiEncodeAvcFei::ParseStatsParams(PDDI_MEDIA_CONTEXT mediaCtx, void *ptr)
848 {
849 if ((nullptr == ptr) || (nullptr == m_encodeCtx))
850 {
851 DDI_ASSERTMESSAGE("invalidate input parameters");
852 return VA_STATUS_ERROR_INVALID_PARAMETER;
853 }
854
855 VAStatsStatisticsParameterH264 *statsParams = (VAStatsStatisticsParameterH264 *)ptr;
856 FeiPreEncParams *preEncParams = (FeiPreEncParams*)(m_encodeCtx->pPreEncParams);
857 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_encodeCtx->RTtbl);
858
859 preEncParams->dwNumPastReferences = statsParams->stats_params.num_past_references;
860 preEncParams->dwNumFutureReferences = statsParams->stats_params.num_future_references;
861 preEncParams->dwFrameQp = statsParams->frame_qp;
862 preEncParams->dwLenSP = statsParams->len_sp;
863 preEncParams->dwSearchPath = statsParams->search_path;
864 preEncParams->dwSubMBPartMask = statsParams->sub_mb_part_mask;
865 preEncParams->dwIntraPartMask = statsParams->intra_part_mask;
866 preEncParams->dwSubPelMode = statsParams->sub_pel_mode;
867 preEncParams->dwInterSAD = statsParams->inter_sad;
868 preEncParams->dwIntraSAD = statsParams->intra_sad;
869 preEncParams->bAdaptiveSearch = statsParams->adaptive_search;
870 preEncParams->dwMVPredictorCtrl = statsParams->mv_predictor_ctrl;
871 preEncParams->bMBQp = statsParams->mb_qp;
872 preEncParams->bFTEnable = statsParams->ft_enable;
873 preEncParams->dwRefWidth = statsParams->ref_width;
874 preEncParams->dwRefHeight = statsParams->ref_height;
875 preEncParams->dwSearchWindow = statsParams->search_window;
876 preEncParams->bDisableMVOutput = statsParams->disable_mv_output;
877 preEncParams->bDisableStatisticsOutput = statsParams->disable_statistics_output;
878 preEncParams->bEnable8x8Statistics = statsParams->enable_8x8_statistics;
879 preEncParams->bInputUpdated = false;
880 preEncParams->bCurPicUpdated = false;
881 preEncParams->bPastRefUpdated = false;
882 preEncParams->bFutureRefUpdated = false;
883 preEncParams->bPastRefStatsNeeded = false;
884 preEncParams->bFutureRefStatsNeeded = false;
885
886 if (statsParams->stats_params.input.picture_id == VA_INVALID_ID)
887 {
888 DDI_ASSERTMESSAGE("invalidate input parameters, current picture id is invalidate");
889 return VA_STATUS_ERROR_INVALID_PARAMETER;
890 }
891
892 if ((statsParams->stats_params.input.flags & VA_PICTURE_STATS_CONTENT_UPDATED) != 0)
893 {
894 preEncParams->bCurPicUpdated = true;
895 }
896
897 CODEC_PICTURE_FLAG picFlags = ((statsParams->stats_params.input.flags & 0xF) == VA_PICTURE_STATS_PROGRESSIVE) ? PICTURE_FRAME : (((statsParams->stats_params.input.flags & 0xF) == VA_PICTURE_STATS_TOP_FIELD) ? PICTURE_TOP_FIELD : (((statsParams->stats_params.input.flags & 0xF) == VA_PICTURE_STATS_BOTTOM_FIELD) ? PICTURE_BOTTOM_FIELD : PICTURE_INVALID));
898 preEncParams->bInterlaced = (picFlags == PICTURE_TOP_FIELD || picFlags == PICTURE_BOTTOM_FIELD);
899
900 DDI_MEDIA_SURFACE *currentSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, statsParams->stats_params.input.picture_id);
901 if (nullptr == currentSurface)
902 {
903 DDI_ASSERTMESSAGE("invalidate current ref surface");
904 return VA_STATUS_ERROR_INVALID_PARAMETER;
905 }
906
907 DDI_CHK_RET(RegisterRTSurfaces(&m_encodeCtx->RTtbl, currentSurface), "RegisterRTSurfaces failed!");
908 preEncParams->CurrOriginalPicture.FrameIdx = (uint8_t)GetRenderTargetID(rtTbl, currentSurface);
909 preEncParams->CurrOriginalPicture.PicFlags = picFlags;
910 DDI_MEDIA_BUFFER *mediaBuffer;
911 if ((preEncParams->dwNumPastReferences == 1) && (statsParams->stats_params.past_references[0].picture_id != VA_INVALID_ID))
912 {
913 if ((statsParams->stats_params.past_references->flags & VA_PICTURE_STATS_CONTENT_UPDATED) != 0)
914 {
915 preEncParams->bPastRefUpdated = true;
916 }
917 DDI_MEDIA_SURFACE *pastRefSurface = (DDI_MEDIA_SURFACE *)DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, statsParams->stats_params.past_references->picture_id);
918 if (nullptr == pastRefSurface)
919 {
920 DDI_ASSERTMESSAGE("invalidate Future ref surface");
921 return VA_STATUS_ERROR_INVALID_PARAMETER;
922 }
923 DDI_CHK_RET(RegisterRTSurfaces(&m_encodeCtx->RTtbl, pastRefSurface), "RegisterRTSurfaces failed!");
924 preEncParams->PastRefPicture.FrameIdx = (uint8_t)GetRenderTargetID(rtTbl, pastRefSurface);
925 picFlags = ((statsParams->stats_params.past_references->flags & 0xF) == VA_PICTURE_STATS_PROGRESSIVE) ? PICTURE_FRAME : (((statsParams->stats_params.past_references->flags & 0xF) == VA_PICTURE_STATS_TOP_FIELD) ? PICTURE_TOP_FIELD : (((statsParams->stats_params.past_references->flags & 0xF) == VA_PICTURE_STATS_BOTTOM_FIELD) ? PICTURE_BOTTOM_FIELD : PICTURE_INVALID));
926 preEncParams->PastRefPicture.PicFlags = picFlags;
927
928 DdiMedia_MediaSurfaceToMosResource(pastRefSurface, &(preEncParams->sPastRefSurface.OsResource));
929 preEncParams->sPastRefSurface.dwWidth = preEncParams->sPastRefSurface.OsResource.iWidth;
930 preEncParams->sPastRefSurface.dwHeight = preEncParams->sPastRefSurface.OsResource.iHeight;
931 preEncParams->sPastRefSurface.dwPitch = preEncParams->sPastRefSurface.OsResource.iPitch;
932 preEncParams->sPastRefSurface.TileType = preEncParams->sPastRefSurface.OsResource.TileType;
933 preEncParams->sPastRefSurface.TileModeGMM = preEncParams->sPastRefSurface.OsResource.TileModeGMM;
934 preEncParams->sPastRefSurface.bGMMTileEnabled = preEncParams->sPastRefSurface.OsResource.bGMMTileEnabled;
935 preEncParams->bPastRefStatsNeeded = false;
936
937 if (statsParams->stats_params.past_ref_stat_buf)
938 {
939 if (!preEncParams->bDisableStatisticsOutput)
940 {
941 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, *(statsParams->stats_params.past_ref_stat_buf));
942 if (nullptr == mediaBuffer)
943 {
944 DDI_ASSERTMESSAGE("invalidate statistics output media buffer for Past ref");
945 return VA_STATUS_ERROR_INVALID_PARAMETER;
946 }
947 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->sPastRefStatsBuffer));
948 if (picFlags == PICTURE_TOP_FIELD || picFlags == PICTURE_BOTTOM_FIELD)
949 {
950 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, *(statsParams->stats_params.past_ref_stat_buf + 1));
951 if (nullptr == mediaBuffer)
952 {
953 DDI_ASSERTMESSAGE("invalidate statistics output media buffer for Past bottom field ref");
954 return VA_STATUS_ERROR_INVALID_PARAMETER;
955 }
956 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->sPastRefStatsBotFieldBuffer));
957 }
958 preEncParams->bPastRefStatsNeeded = true;
959 }
960 else
961 preEncParams->bPastRefStatsNeeded = false;
962 }
963 }
964 else
965 {
966 preEncParams->PastRefPicture.FrameIdx = (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX;
967 preEncParams->PastRefPicture.PicFlags = PICTURE_INVALID;
968 }
969
970 if ((preEncParams->dwNumFutureReferences == 1) && (statsParams->stats_params.future_references[0].picture_id != VA_INVALID_ID))
971 {
972 if ((statsParams->stats_params.future_references->flags & VA_PICTURE_STATS_CONTENT_UPDATED) != 0)
973 {
974 preEncParams->bFutureRefUpdated = true;
975 }
976 DDI_MEDIA_SURFACE *futureRefSurface = (DDI_MEDIA_SURFACE *)DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, statsParams->stats_params.future_references->picture_id);
977 if (nullptr == futureRefSurface)
978 {
979 DDI_ASSERTMESSAGE("invalidate Future ref surface");
980 return VA_STATUS_ERROR_INVALID_PARAMETER;
981 }
982 DDI_CHK_RET(RegisterRTSurfaces(&m_encodeCtx->RTtbl, futureRefSurface), "RegisterRTSurfaces failed!");
983 preEncParams->FutureRefPicture.FrameIdx = (uint8_t)GetRenderTargetID(rtTbl, futureRefSurface);
984 picFlags = ((statsParams->stats_params.future_references->flags & 0xF) == VA_PICTURE_STATS_PROGRESSIVE) ? PICTURE_FRAME : (((statsParams->stats_params.future_references->flags & 0xF) == VA_PICTURE_STATS_TOP_FIELD) ? PICTURE_TOP_FIELD : (((statsParams->stats_params.future_references->flags & 0xF) == VA_PICTURE_STATS_BOTTOM_FIELD) ? PICTURE_BOTTOM_FIELD : PICTURE_INVALID));
985 preEncParams->FutureRefPicture.PicFlags = picFlags;
986
987 DdiMedia_MediaSurfaceToMosResource(futureRefSurface, &(preEncParams->sFutureRefSurface.OsResource));
988 preEncParams->sFutureRefSurface.dwWidth = preEncParams->sFutureRefSurface.OsResource.iWidth;
989 preEncParams->sFutureRefSurface.dwHeight = preEncParams->sFutureRefSurface.OsResource.iHeight;
990 preEncParams->sFutureRefSurface.dwPitch = preEncParams->sFutureRefSurface.OsResource.iPitch;
991 preEncParams->sFutureRefSurface.TileType = preEncParams->sFutureRefSurface.OsResource.TileType;
992 preEncParams->bFutureRefStatsNeeded = false;
993 if (!preEncParams->bDisableStatisticsOutput)
994 {
995 if (statsParams->stats_params.future_ref_stat_buf)
996 {
997 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, *(statsParams->stats_params.future_ref_stat_buf));
998 if (nullptr == mediaBuffer)
999 {
1000 DDI_ASSERTMESSAGE("invalidate statistics output media buffer for Future ref");
1001 return VA_STATUS_ERROR_INVALID_PARAMETER;
1002 }
1003 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->sFutureRefStatsBuffer));
1004 if (picFlags == PICTURE_TOP_FIELD || picFlags == PICTURE_BOTTOM_FIELD)
1005 {
1006 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, *(statsParams->stats_params.future_ref_stat_buf + 1));
1007 if (nullptr == mediaBuffer)
1008 {
1009 DDI_ASSERTMESSAGE("invalidate statistics output media buffer for Future ref");
1010 return VA_STATUS_ERROR_INVALID_PARAMETER;
1011 }
1012 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->sFutureRefStatsBotFieldBuffer));
1013 }
1014 preEncParams->bFutureRefStatsNeeded = true;
1015 }
1016 else
1017 preEncParams->bFutureRefStatsNeeded = false;
1018 }
1019 }
1020 else
1021 {
1022 preEncParams->FutureRefPicture.FrameIdx = (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX;
1023 preEncParams->FutureRefPicture.PicFlags = PICTURE_INVALID;
1024 }
1025
1026 if (preEncParams->dwMVPredictorCtrl)
1027 {
1028 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, statsParams->stats_params.mv_predictor);
1029 if (nullptr == mediaBuffer)
1030 {
1031 DDI_ASSERTMESSAGE("invalidate mv_predictor media buffer");
1032 return VA_STATUS_ERROR_INVALID_PARAMETER;
1033 }
1034 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->resMvPredBuffer));
1035 }
1036 if (preEncParams->bMBQp)
1037 {
1038 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, statsParams->stats_params.qp);
1039 if (nullptr == mediaBuffer)
1040 {
1041 DDI_ASSERTMESSAGE("invalidate qp media buffer");
1042 return VA_STATUS_ERROR_INVALID_PARAMETER;
1043 }
1044 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->resMbQpBuffer));
1045 }
1046
1047 uint32_t i = 0;
1048 if (!preEncParams->bDisableMVOutput)
1049 {
1050 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, statsParams->stats_params.outputs[i++]);
1051 if (nullptr == mediaBuffer)
1052 {
1053 DDI_ASSERTMESSAGE("invalidate mv output media buffer");
1054 return VA_STATUS_ERROR_INVALID_PARAMETER;
1055 }
1056 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->resMvBuffer));
1057 RemoveFromPreEncStatusReportQueue(mediaBuffer, PRE_ENC_BUFFER_TYPE_MVDATA);
1058 if (VA_STATUS_SUCCESS != AddToPreEncStatusReportQueue((void *)(preEncParams->resMvBuffer.bo), PRE_ENC_BUFFER_TYPE_MVDATA))
1059 {
1060 DDI_ASSERTMESSAGE("preEncParams->resMvBuffer is invalid for PREENC only");
1061 return VA_STATUS_ERROR_INVALID_PARAMETER;
1062 }
1063 }
1064
1065 if (!preEncParams->bDisableStatisticsOutput)
1066 {
1067 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, statsParams->stats_params.outputs[i++]);
1068 if (nullptr == mediaBuffer)
1069 {
1070 DDI_ASSERTMESSAGE("invalidate statistics output media buffer");
1071 return VA_STATUS_ERROR_INVALID_PARAMETER;
1072 }
1073 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->resStatsBuffer));
1074 RemoveFromPreEncStatusReportQueue(mediaBuffer, PRE_ENC_BUFFER_TYPE_STATS);
1075 if (VA_STATUS_SUCCESS != AddToPreEncStatusReportQueue((void *)(preEncParams->resStatsBuffer.bo), PRE_ENC_BUFFER_TYPE_STATS))
1076 {
1077 DDI_ASSERTMESSAGE("preEncParams->resStatsBuffer is invalid for PREENC only");
1078 return VA_STATUS_ERROR_INVALID_PARAMETER;
1079 }
1080
1081 if (preEncParams->bInterlaced)
1082 {
1083 mediaBuffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, statsParams->stats_params.outputs[i++]);
1084 if (nullptr == mediaBuffer)
1085 {
1086 DDI_ASSERTMESSAGE("invalidate statistics output media bottom field buffer, must provide bottom field statistics buffer for both top and bottom field PreENC");
1087 return VA_STATUS_ERROR_INVALID_PARAMETER;
1088 }
1089 DdiMedia_MediaBufferToMosResource(mediaBuffer, &(preEncParams->resStatsBotFieldBuffer));
1090 RemoveFromPreEncStatusReportQueue(mediaBuffer, PRE_ENC_BUFFER_TYPE_STATS_BOT);
1091 if (VA_STATUS_SUCCESS != AddToPreEncStatusReportQueue((void *)(preEncParams->resStatsBotFieldBuffer.bo), PRE_ENC_BUFFER_TYPE_STATS_BOT))
1092 {
1093 DDI_ASSERTMESSAGE("preEncParams->resStatsBotFieldBuffer is invalid for PREENC only");
1094 return VA_STATUS_ERROR_INVALID_PARAMETER;
1095 }
1096 }
1097 }
1098
1099 AddToPreEncStatusReportQueueUpdatePos();
1100
1101 return VA_STATUS_SUCCESS;
1102 }
1103