1 /*
2 * Copyright (c) 2017-2018, 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 codechal_huc_cmd_initializer.cpp
24 //! \brief Defines base class for command initializer encoder.
25 //!
26
27 #include "codec_def_encode_hevc.h"
28 #if defined (_HEVC_ENCODE_VME_SUPPORTED) || defined (_HEVC_ENCODE_VDENC_SUPPORTED)
29 #include "codechal_encode_hevc_base.h"
30 #endif
31 #include "codechal_huc_cmd_initializer.h"
32 #include "codechal_encoder_base.h"
33 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
34 #include "codechal_vdenc_vp9_base.h"
35 #endif
36
37 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD1_STARTOFFSERT 28
38 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD2_STARTOFFSERT 276
39 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CQP_CMD2_STARTOFFSET 248
40
CodechalCmdInitializer(CodechalEncoderState * encoder)41 CodechalCmdInitializer::CodechalCmdInitializer(
42 CodechalEncoderState *encoder)
43 {
44 m_encoder = encoder;
45 m_cmdCount = 0;
46 m_currentPass = 0;
47 }
48
CmdInitializerAllocateResources(CodechalHwInterface * hwInterface)49 MOS_STATUS CodechalCmdInitializer::CmdInitializerAllocateResources(
50 CodechalHwInterface *hwInterface)
51 {
52 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
53
54 CODECHAL_ENCODE_FUNCTION_ENTER;
55
56 m_hwInterface = hwInterface;
57 m_osInterface = m_hwInterface->GetOsInterface();
58 m_miInterface = m_hwInterface->GetMiInterface();
59 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
60 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
61 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
62 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
63 allocParamsForBufferLinear.Format = Format_Buffer;
64
65 //Allocate buffers for every pass.
66 for (int i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
67 {
68 for(int j = 0; j < 3; j++)
69 {
70 // Cmd Initializer DMEM
71 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
72 allocParamsForBufferLinear.pBufName = "VDEnc CmdInitializer Dmem Buffer";
73 CODECHAL_ENCODE_CHK_STATUS_RETURN(
74 m_osInterface->pfnAllocateResource(
75 m_osInterface,
76 &allocParamsForBufferLinear,
77 &m_cmdInitializerDmemBuffer[i][j]));
78
79 // Cmd Initializer Data buffer
80 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComData), CODECHAL_PAGE_SIZE);
81 allocParamsForBufferLinear.pBufName = "VDEnc CmdInitializer Data Buffer";
82 CODECHAL_ENCODE_CHK_STATUS_RETURN(
83 m_osInterface->pfnAllocateResource(
84 m_osInterface,
85 &allocParamsForBufferLinear,
86 &m_cmdInitializerDataBuffer[i][j]));
87
88 MOS_LOCK_PARAMS lockFlagsWriteOnly;
89 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
90 lockFlagsWriteOnly.WriteOnly = 1;
91
92 uint8_t *pData = (uint8_t *)m_osInterface->pfnLockResource(
93 m_osInterface,
94 &m_cmdInitializerDataBuffer[i][j],
95 &lockFlagsWriteOnly);
96 CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
97 MOS_ZeroMemory(pData, allocParamsForBufferLinear.dwBytes);
98 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDataBuffer[i][j]);
99 }
100 }
101
102 //Allocate extra buffers for dynamic scaling
103 // Cmd Initializer DMEM
104 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
105 allocParamsForBufferLinear.pBufName = "VDEnc Dynamic Sclaing CmdInitializer Dmem Buffer";
106 CODECHAL_ENCODE_CHK_STATUS_RETURN(
107 m_osInterface->pfnAllocateResource(
108 m_osInterface,
109 &allocParamsForBufferLinear,
110 &m_cmdInitializerDysScalingDmemBuffer));
111
112 // Cmd Initializer Data buffer
113 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComData), CODECHAL_PAGE_SIZE);
114 allocParamsForBufferLinear.pBufName = "VDEnc Dynamic Sclaing CmdInitializer Data Buffer";
115 CODECHAL_ENCODE_CHK_STATUS_RETURN(
116 m_osInterface->pfnAllocateResource(
117 m_osInterface,
118 &allocParamsForBufferLinear,
119 &m_cmdInitializerDysScalingDataBuffer));
120
121 MOS_LOCK_PARAMS lockFlagsWriteOnly;
122 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
123 lockFlagsWriteOnly.WriteOnly = 1;
124
125 uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource(
126 m_osInterface,
127 &m_cmdInitializerDysScalingDataBuffer,
128 &lockFlagsWriteOnly);
129 CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
130 MOS_ZeroMemory(pData, allocParamsForBufferLinear.dwBytes);
131 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer);
132
133 return eStatus;
134 }
135
CmdInitializerFreeResources()136 void CodechalCmdInitializer::CmdInitializerFreeResources()
137 {
138 for (int i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
139 {
140 for(int j = 0; j < 3; j++)
141 {
142 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerDmemBuffer[i][j]);
143 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerDataBuffer[i][j]);
144 }
145 }
146 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerDysScalingDmemBuffer);
147 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer);
148
149 }
150
151 #if defined (_HEVC_ENCODE_VME_SUPPORTED) || defined (_HEVC_ENCODE_VDENC_SUPPORTED)
CmdInitializerSetDmem(bool brcEnabled)152 MOS_STATUS CodechalCmdInitializer::CmdInitializerSetDmem(bool brcEnabled)
153 {
154 HucComDmem* hucCmdInitializerDmem;
155 MOS_LOCK_PARAMS lockFlagsWriteOnly;
156 uint16_t offset = 0;
157 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
158
159 CODECHAL_ENCODE_FUNCTION_ENTER;
160
161 m_osInterface = m_encoder->GetOsInterface();
162
163 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
164 lockFlagsWriteOnly.WriteOnly = 1;
165
166 // Setup CmdInitializer DMEM
167 hucCmdInitializerDmem = (HucComDmem *)m_osInterface->pfnLockResource(
168 m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass], &lockFlagsWriteOnly);
169
170 CODECHAL_ENCODE_CHK_NULL_RETURN(hucCmdInitializerDmem);
171
172 MOS_ZeroMemory(hucCmdInitializerDmem, sizeof(HucComDmem));
173
174 CODECHAL_ENCODE_ASSERT(m_cmdCount == 2);
175 hucCmdInitializerDmem->TotalOutputCommands = 2;
176
177 hucCmdInitializerDmem->TargetUsage = 4;
178 switch (m_encoder->m_standard)
179 {
180 case CODECHAL_HEVC:
181 hucCmdInitializerDmem->Codec = 0;
182 hucCmdInitializerDmem->TargetUsage = (uint8_t)m_encoder->m_targetUsage;
183 break;
184 case CODECHAL_VP9:
185 hucCmdInitializerDmem->Codec = 1;
186 break;
187 default:
188 hucCmdInitializerDmem->Codec = 0;
189 break;
190 }
191 hucCmdInitializerDmem->FrameType = m_encoder->m_pictureCodingType - 1;
192 hucCmdInitializerDmem->OutputCOM[0].ID = 2;
193 hucCmdInitializerDmem->OutputCOM[0].Type = 1;
194 hucCmdInitializerDmem->OutputCOM[0].StartInBytes = GetCmd1StartOffset(brcEnabled);
195
196 offset += CODECHAL_CMDINITIALIZER_MAX_CMD_SIZE;
197
198 // Command ID 1
199 hucCmdInitializerDmem->OutputCOM[1].ID = 1;
200 hucCmdInitializerDmem->OutputCOM[1].Type = 1;
201 hucCmdInitializerDmem->OutputCOM[1].StartInBytes = GetCmd2StartOffset(brcEnabled);
202
203 offset += CODECHAL_CMDINITIALIZER_MAX_CMD_SIZE;
204
205 hucCmdInitializerDmem->OutputSize = offset;
206
207 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass]);
208
209 return eStatus;
210 }
211
ConstructHevcHucCmd1ConstData(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,struct HucComData * hucConstData)212 MOS_STATUS CodechalCmdInitializer::ConstructHevcHucCmd1ConstData(
213 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,
214 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,
215 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,
216 struct HucComData * hucConstData)
217 {
218 hucConstData->InputCOM[1].ID = 1;
219 hucConstData->InputCOM[1].SizeOfData = sizeof(HucInputCmd1) / sizeof(uint8_t);
220
221 auto qpPrimeYAC = 10; //This is constant from Arch C Model
222 double qpScale = (picParams->CodingType == I_TYPE) ? 0.60 : 0.65;
223
224 HucInputCmd1 cmd1;
225 MOS_ZeroMemory(&cmd1, sizeof(HucInputCmd1));
226
227 // Shared HEVC/VP9
228 cmd1.FrameWidthInMinCbMinus1 = seqParams->wFrameWidthInMinCbMinus1;
229 cmd1.FrameHeightInMinCbMinus1 = seqParams->wFrameHeightInMinCbMinus1;
230
231 cmd1.log2_min_coding_block_size_minus3 = seqParams->log2_min_coding_block_size_minus3;
232
233 cmd1.VdencStreamInEnabled = (uint8_t)m_streamInEnabled;
234 cmd1.PakOnlyMultipassEnable = m_pakOnlyPass;
235 cmd1.num_ref_idx_l0_active_minus1 = sliceParams->num_ref_idx_l0_active_minus1;
236
237 auto qpPrimeYac = CodecHal_Clip3(0, 51, picParams->QpY + sliceParams->slice_qp_delta);
238 double lambda = sqrt(qpScale * pow(2.0, MOS_MAX(0, qpPrimeYac - 12) / 3.0));
239 cmd1.SADQPLambda = (uint16_t)(lambda * 4 + 0.5);
240 cmd1.RDQPLambda = (uint16_t)(qpScale * pow(2.0, MOS_MAX(0, picParams->QpY - 12) / 3.0) * 4 + 0.5); //U14.2
241
242 cmd1.num_ref_idx_l1_active_minus1 = sliceParams->num_ref_idx_l1_active_minus1;
243 cmd1.ROIStreamInEnabled = (uint8_t)m_roiStreamInEnabled;
244 cmd1.UseDefaultQpDeltas = (m_acqpEnabled && seqParams->QpAdjustment) || (m_brcEnabled && seqParams->MBBRC != mbBrcDisabled);
245 cmd1.TemporalMvpEnableFlag = sliceParams->slice_temporal_mvp_enable_flag;
246 cmd1.PanicEnabled = m_panicEnabled;
247
248 if (m_roiStreamInEnabled)
249 {
250 for (int8_t i = 0; i < ENCODE_VDENC_HEVC_MAX_STREAMINROI_G10; i++)
251 {
252 cmd1.ROIDeltaQp[i] = picParams->ROIDistinctDeltaQp[i];
253 }
254 }
255
256 // default
257 cmd1.FwdPocNumForRefId0inL0 = 0x01;
258 cmd1.FwdPocNumForRefId0inL1 = 0xff;
259 cmd1.FwdPocNumForRefId1inL0 = 0x02;
260 cmd1.FwdPocNumForRefId1inL1 = 0xfe;
261 cmd1.FwdPocNumForRefId2inL0 = 0x03;
262 cmd1.FwdPocNumForRefId2inL1 = 0xfd;
263 cmd1.FwdPocNumForRefId3inL0 = 0x04;
264 cmd1.FwdPocNumForRefId3inL1 = 0xfc;
265
266 if (picParams->CodingType != I_TYPE)
267 {
268 uint8_t refFrameID;
269 char diff_poc;
270
271 refFrameID = sliceParams->RefPicList[0][0].FrameIdx;
272 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
273 cmd1.FwdPocNumForRefId0inL0 = -diff_poc;
274 cmd1.FwdPocNumForRefId0inL1 = -diff_poc;
275
276 refFrameID = sliceParams->RefPicList[0][1].FrameIdx;
277 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
278 cmd1.FwdPocNumForRefId1inL0 = -diff_poc;
279 cmd1.FwdPocNumForRefId1inL1 = -diff_poc;
280
281 refFrameID = sliceParams->RefPicList[0][2].FrameIdx;
282 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
283 cmd1.FwdPocNumForRefId2inL0 = -diff_poc;
284 cmd1.FwdPocNumForRefId2inL1 = -diff_poc;
285 }
286
287 cmd1.EnableRollingIntraRefresh = picParams->bEnableRollingIntraRefresh;
288 cmd1.QpDeltaForInsertedIntra = picParams->QpDeltaForInsertedIntra;
289 cmd1.IntraInsertionSize = picParams->IntraInsertionSize;
290 cmd1.IntraInsertionLocation = picParams->IntraInsertionLocation;
291 cmd1.IntraInsertionReferenceLocation[0] = picParams->RollingIntraReferenceLocation[0];
292 cmd1.IntraInsertionReferenceLocation[1] = picParams->RollingIntraReferenceLocation[1];
293 cmd1.IntraInsertionReferenceLocation[2] = picParams->RollingIntraReferenceLocation[2];
294
295 cmd1.QpY = picParams->QpY + sliceParams->slice_qp_delta;
296 cmd1.RoundingEnabled = (uint8_t)m_roundingEnabled;
297
298 MOS_SecureMemcpy(hucConstData->InputCOM[1].data, sizeof(HucInputCmd1), &cmd1, sizeof(HucInputCmd1));
299
300 return MOS_STATUS_SUCCESS;
301 }
302
ConstructHevcHucCmd2ConstData(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,struct HucComData * hucConstData)303 MOS_STATUS CodechalCmdInitializer::ConstructHevcHucCmd2ConstData(
304 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,
305 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,
306 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,
307 struct HucComData * hucConstData)
308 {
309 hucConstData->InputCOM[0].ID = 2;
310 hucConstData->InputCOM[0].SizeOfData = 2;
311
312 auto qpPrimeYAC = 10; //This is constant from Arch C Model
313
314 double qpScale = (picParams->CodingType == I_TYPE) ? 0.60 : 0.65;
315 double lambdaInputCom = sqrt(qpScale * pow(2.0, MOS_MAX(0, qpPrimeYAC - 12) / 3.0));
316
317 // SADQPLambda
318 hucConstData->InputCOM[0].data[0] = (uint32_t)(lambdaInputCom * 4 + 0.5);
319 hucConstData->InputCOM[0].data[1] = m_roiStreamInEnabled;
320
321 return MOS_STATUS_SUCCESS;
322 }
323
GetCmd1StartOffset(bool brcEnabled)324 uint16_t CodechalCmdInitializer::GetCmd1StartOffset(bool brcEnabled)
325 {
326 return brcEnabled ? VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD1_STARTOFFSERT : 0;
327 }
328
GetCmd2StartOffset(bool brcEnabled)329 uint16_t CodechalCmdInitializer::GetCmd2StartOffset(bool brcEnabled)
330 {
331 return brcEnabled ? VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD2_STARTOFFSERT : VDBOX_HUC_CMD_INITIALIZER_HEVC_CQP_CMD2_STARTOFFSET;
332 }
333
CmdInitializerSetConstData(PMOS_INTERFACE osInterface,MhwMiInterface * miInterface,MhwVdboxVdencInterface * vdencInterface,void * sequenceParams,void * pictureParams,void * slcParams,bool pakOnlyPass,bool acqpEnabled,bool brcEnabled,bool streaminEnabled,bool roiStreamInEnabled,bool brcAdaptiveRegionBoostEnable,bool roundingEnabled,bool panicEnabled,int32_t currentPass)334 MOS_STATUS CodechalCmdInitializer::CmdInitializerSetConstData(
335 PMOS_INTERFACE osInterface,
336 MhwMiInterface *miInterface,
337 MhwVdboxVdencInterface *vdencInterface,
338 void* sequenceParams,
339 void* pictureParams,
340 void* slcParams,
341 bool pakOnlyPass,
342 bool acqpEnabled,
343 bool brcEnabled,
344 bool streaminEnabled,
345 bool roiStreamInEnabled,
346 bool brcAdaptiveRegionBoostEnable,
347 bool roundingEnabled,
348 bool panicEnabled,
349 int32_t currentPass
350 )
351 {
352 HucComData* hucConstData;
353 MOS_LOCK_PARAMS lockFlagsWriteOnly;
354 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
355
356 CODECHAL_ENCODE_FUNCTION_ENTER;
357
358 CODECHAL_ENCODE_CHK_NULL_RETURN(osInterface);
359 CODECHAL_ENCODE_CHK_NULL_RETURN(miInterface);
360 CODECHAL_ENCODE_CHK_NULL_RETURN(vdencInterface);
361 CODECHAL_ENCODE_CHK_NULL_RETURN(sequenceParams);
362 CODECHAL_ENCODE_CHK_NULL_RETURN(pictureParams);
363 CODECHAL_ENCODE_CHK_NULL_RETURN(slcParams);
364
365 m_osInterface = osInterface;
366 m_miInterface = miInterface;
367 m_vdencInterface = vdencInterface;
368 m_seqParams = sequenceParams;
369 m_picParams = pictureParams;
370 m_sliceParams = slcParams;
371
372 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS)sequenceParams;
373 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams = (PCODEC_HEVC_ENCODE_PICTURE_PARAMS)pictureParams;
374 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams = (PCODEC_HEVC_ENCODE_SLICE_PARAMS)slcParams;
375
376 m_pakOnlyPass = pakOnlyPass;
377 m_acqpEnabled = acqpEnabled;
378 m_brcEnabled = brcEnabled;
379 m_streamInEnabled = streaminEnabled;
380 m_roundingEnabled = roundingEnabled;
381 m_panicEnabled = panicEnabled;
382 m_roiStreamInEnabled = roiStreamInEnabled;
383 m_currentPass = currentPass;
384 m_brcAdaptiveRegionBoostEnabled = brcAdaptiveRegionBoostEnable;
385
386 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
387 lockFlagsWriteOnly.WriteOnly = 1;
388
389 hucConstData = (HucComData *)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][currentPass], &lockFlagsWriteOnly);
390 CODECHAL_ENCODE_CHK_NULL_RETURN(hucConstData);
391
392 MOS_ZeroMemory(hucConstData, sizeof(HucComData));
393 m_cmdCount = 0;
394
395 // Command ID 2
396 ConstructHevcHucCmd2ConstData(seqParams, picParams, sliceParams, hucConstData);
397 m_cmdCount++;
398
399 // Command ID 1
400 ConstructHevcHucCmd1ConstData(seqParams, picParams, sliceParams, hucConstData);
401 m_cmdCount++;
402
403 hucConstData->TotalCommands = m_cmdCount;
404
405 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][currentPass]);
406
407 return eStatus;
408 }
409
CmdInitializerExecute(bool brcEnabled,PMOS_RESOURCE secondlevelBB,MOS_COMMAND_BUFFER * cmdBuffer)410 MOS_STATUS CodechalCmdInitializer::CmdInitializerExecute(
411 bool brcEnabled,
412 PMOS_RESOURCE secondlevelBB,
413 MOS_COMMAND_BUFFER* cmdBuffer)
414 {
415 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
416 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
417 MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
418 MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
419 MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
420 MOS_LOCK_PARAMS lockFlagsWriteOnly;
421 MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
422 bool requestFrameTracking;
423 uint8_t codec;
424 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
425 bool renderingFlags;
426 CodechalHwInterface *hwInterface;
427 bool externCmdBuffer = (cmdBuffer != nullptr);
428
429 CODECHAL_ENCODE_FUNCTION_ENTER;
430
431 hwInterface = m_encoder->GetHwInterface();
432 m_osInterface = m_encoder->GetOsInterface();
433 m_miInterface = hwInterface->GetMiInterface();
434
435 // for scalability, the cmdbuffer is passed outside
436 // otherwise the cmdbuffer is fetched here
437 if (cmdBuffer == nullptr)
438 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, cmdBuffer, 0));
439
440 if (!m_encoder->m_singleTaskPhaseSupported || m_encoder->m_firstTaskInPhase)
441 {
442 // Send command buffer header at the beginning (OS dependent)
443 requestFrameTracking = m_encoder->m_singleTaskPhaseSupported ? m_encoder->m_firstTaskInPhase : 0;
444 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->SendPrologWithFrameTracking(cmdBuffer, requestFrameTracking));
445 }
446
447 // load kernel from WOPCM into L2 storage RAM
448 MOS_ZeroMemory(&imemParams, sizeof(imemParams));
449 imemParams.dwKernelDescriptor = m_hucCmdInitializerKernelDescriptor;
450
451 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucImemStateCmd(cmdBuffer, &imemParams));
452
453 // HUC_PIPE_MODE_SELECT
454 pipeModeSelectParams.Mode = m_encoder->m_mode;
455 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucPipeModeSelectCmd(cmdBuffer, &pipeModeSelectParams));
456
457 CODECHAL_ENCODE_CHK_STATUS_RETURN(CmdInitializerSetDmem(brcEnabled));
458
459 // set HuC DMEM param
460 MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
461 dmemParams.presHucDataSource = &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass];
462 dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
463 dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
464 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucDmemStateCmd(cmdBuffer, &dmemParams));
465
466 MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
467 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass];
468
469 virtualAddrParams.regionParams[1].presRegion = secondlevelBB;
470
471 virtualAddrParams.regionParams[1].isWritable = true;
472
473 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucVirtualAddrStateCmd(cmdBuffer, &virtualAddrParams));
474
475 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucStartCmd(cmdBuffer, true));
476
477 // wait Huc completion (use HEVC bit for now)
478 MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
479 vdPipeFlushParams.Flags.bFlushHEVC = 1;
480 vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
481 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetVdencInterface()->AddVdPipelineFlushCmd(cmdBuffer, &vdPipeFlushParams));
482
483 // Flush the engine to ensure memory written out
484 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
485 flushDwParams.bVideoPipelineCacheInvalidate = true;
486 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
487
488 if (!m_encoder->m_singleTaskPhaseSupported && (m_osInterface->bNoParsingAssistanceInKmd))
489 {
490 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
491 }
492
493 if ((!m_encoder->m_singleTaskPhaseSupported))
494 {
495 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(cmdBuffer, nullptr));
496 }
497
498 // if the cmdbuffer is passed outside, then we don't need to submit, just return
499 if (externCmdBuffer)
500 return eStatus;
501
502 m_osInterface->pfnReturnCommandBuffer(m_osInterface, cmdBuffer, 0);
503
504 if (!m_encoder->m_singleTaskPhaseSupported)
505 {
506 renderingFlags = m_encoder->m_videoContextUsesNullHw;
507
508 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetDebugInterface()->DumpCmdBuffer(
509 cmdBuffer,
510 CODECHAL_NUM_MEDIA_STATES,
511 "HucCmd")));
512
513 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, renderingFlags));
514 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpHucCmdInit(secondlevelBB)));
515 }
516
517 return eStatus;
518 }
519 #endif
520
521 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
522 //VP9 Specific functions
523
CommandInitializerSetVp9Params(CodechalVdencVp9State * state)524 MOS_STATUS CodechalCmdInitializer::CommandInitializerSetVp9Params(CodechalVdencVp9State *state)
525 {
526 HucComData * hucConstData;
527 MOS_LOCK_PARAMS lockFlagsWriteOnly;
528 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
529
530 CODECHAL_ENCODE_CHK_NULL_RETURN(state);
531 MOS_ZeroMemory(&m_vp9Params, sizeof(m_vp9Params));
532 m_vp9Params.prevFrameSegEnabled = state->m_prevFrameSegEnabled;
533 m_vp9Params.seqParams = state->m_vp9SeqParams;
534 m_vp9Params.picParams = state->m_vp9PicParams;
535 m_vp9Params.segmentationEnabled = state->m_vp9PicParams->PicFlags.fields.segmentation_enabled;
536 m_vp9Params.segmentMapProvided = state->m_segmentMapProvided;
537 m_vp9Params.prevFrameSegEnabled = state->m_prevFrameSegEnabled;
538 m_vp9Params.numRefFrames = state->m_numRefFrames;
539 m_vp9Params.me16Enabled = state->m_16xMeEnabled;
540 m_vp9Params.dysVdencMultiPassEnabled = state->m_dysVdencMultiPassEnabled;
541 m_vp9Params.vdencPakOnlyMultipassEnabled = state->m_vdencPakonlyMultipassEnabled;
542 m_vp9Params.pictureCodingType = state->m_pictureCodingType;
543 m_vp9Params.currentPass = state->GetCurrentPass();
544 m_currentPass = m_vp9Params.currentPass;
545 m_vp9Params.singleTaskPhaseSupported = state->m_singleTaskPhaseSupported;
546 m_vp9Params.lastTaskInPhase = state->m_lastTaskInPhase;
547 m_vp9Params.firstTaskInPhase = state->m_firstTaskInPhase;
548 m_vp9Params.mode = state->m_mode;
549 m_vdencInterface = state->m_vdencInterface;
550 m_vp9Params.videoContextUsesNullHw = state->m_videoContextUsesNullHw;
551 m_vp9Params.debugInterface = state->GetDebugInterface();
552 m_vp9Params.dynamicScalingEnabled = (state->m_dysRefFrameFlags != DYS_REF_NONE) ? true : false;
553 m_vp9Params.segmentParams = state->m_vp9SegmentParams;
554 m_vp9Params.bPrevFrameKey = state->m_prevFrameInfo.KeyFrame;
555 return eStatus;
556 }
557
CmdInitializerVp9Execute(PMOS_COMMAND_BUFFER cmdBuffer,PMOS_RESOURCE picStateBuffer)558 MOS_STATUS CodechalCmdInitializer::CmdInitializerVp9Execute(PMOS_COMMAND_BUFFER cmdBuffer, PMOS_RESOURCE picStateBuffer)
559 {
560 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
561 MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
562 MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
563 MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
564 MOS_LOCK_PARAMS lockFlagsWriteOnly;
565 bool requestFrameTracking;
566 uint8_t codec;
567 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
568 bool renderingFlags;
569
570 CODECHAL_ENCODE_FUNCTION_ENTER;
571 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder);
572 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
573
574 // load kernel from WOPCM into L2 storage RAM
575 MOS_ZeroMemory(&imemParams, sizeof(imemParams));
576 imemParams.dwKernelDescriptor = m_hucCmdInitializerKernelDescriptor;
577
578 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucImemStateCmd(cmdBuffer, &imemParams));
579
580 // HUC_PIPE_MODE_SELECT
581 pipeModeSelectParams.Mode = m_vp9Params.mode;
582 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucPipeModeSelectCmd(cmdBuffer, &pipeModeSelectParams));
583
584 CODECHAL_ENCODE_CHK_STATUS_RETURN(CmdInitializerVp9SetDmem());
585
586 // set HuC DMEM param
587 MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
588 if (m_vp9Params.dynamicScalingEnabled)
589 {
590 dmemParams.presHucDataSource = &m_cmdInitializerDysScalingDmemBuffer;
591 }
592 else
593 {
594 dmemParams.presHucDataSource = &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass];
595 }
596 dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
597 dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
598 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucDmemStateCmd(cmdBuffer, &dmemParams));
599
600 MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
601 if (m_vp9Params.dynamicScalingEnabled)
602 {
603 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerDysScalingDataBuffer;
604 virtualAddrParams.regionParams[1].presRegion = picStateBuffer; // Region 1 Output SLB Buffer Pass 1 (Output)
605 }
606 else
607 {
608 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass];
609 virtualAddrParams.regionParams[1].presRegion = picStateBuffer; // Region 1 Output SLB Buffer Pass 1 (Output)
610 }
611
612 virtualAddrParams.regionParams[1].isWritable = true;
613
614 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucVirtualAddrStateCmd(cmdBuffer, &virtualAddrParams));
615
616 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucStartCmd(cmdBuffer, true));
617
618 // wait Huc completion (use HEVC bit for now)
619 MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
620 MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
621 vdPipeFlushParams.Flags.bFlushHEVC = 1;
622 vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
623 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetVdencInterface()->AddVdPipelineFlushCmd(cmdBuffer, &vdPipeFlushParams));
624
625 // Flush the engine to ensure memory written out
626 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
627 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
628 flushDwParams.bVideoPipelineCacheInvalidate = true;
629 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
630
631 if (!m_vp9Params.singleTaskPhaseSupported)
632 {
633 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(cmdBuffer, nullptr));
634 }
635
636 m_osInterface->pfnReturnCommandBuffer(m_osInterface, cmdBuffer, 0);
637
638 if (!m_vp9Params.singleTaskPhaseSupported)
639 {
640 bool renderFlags = m_vp9Params.videoContextUsesNullHw;
641 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, renderFlags));
642 }
643
644 return eStatus;
645 }
646
CmdInitializerVp9SetDmem()647 MOS_STATUS CodechalCmdInitializer::CmdInitializerVp9SetDmem()
648 {
649 HucComDmem * hucCmdInitializerDmem;
650 MOS_LOCK_PARAMS lockFlagsWriteOnly;
651 uint16_t offset = 0;
652 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
653
654 CODECHAL_ENCODE_FUNCTION_ENTER;
655 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder);
656
657 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
658 lockFlagsWriteOnly.WriteOnly = 1;
659
660 HucComData *hucConstData;
661 if (m_vp9Params.dynamicScalingEnabled)
662 {
663 hucConstData = (HucComData *)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer, &lockFlagsWriteOnly);
664 }
665 else
666 {
667 hucConstData = (HucComData *)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass], &lockFlagsWriteOnly);
668 }
669 CODECHAL_ENCODE_CHK_NULL_RETURN(hucConstData);
670
671 MOS_ZeroMemory(hucConstData, sizeof(HucComData));
672
673 hucConstData->TotalCommands = 2;
674
675 // Command ID 2
676 hucConstData->InputCOM[0].ID = 2;
677 hucConstData->InputCOM[0].SizeOfData = 2;
678
679 double qpScale = (m_vp9Params.pictureCodingType == I_TYPE) ? 0.31 : 0.33;
680 uint8_t qp = m_vp9Params.picParams->LumaACQIndex;
681 double lambda = qpScale * CODECHAL_VP9_QUANT_AC[qp] / 8;
682
683 // SADQPLambda
684 hucConstData->InputCOM[0].data[0] = (uint32_t)(lambda * 4 + 0.5);
685
686 // Command ID 1
687 hucConstData->InputCOM[1].ID = 1;
688 hucConstData->InputCOM[1].SizeOfData = 0x17;
689
690 HucInputCmd1 hucInputCmd1;
691 MOS_ZeroMemory(&hucInputCmd1, sizeof(hucInputCmd1));
692 hucInputCmd1.VdencStreamInEnabled = m_vp9Params.segmentMapProvided || m_vp9Params.me16Enabled;
693 hucInputCmd1.SegMapStreamInEnabled = m_vp9Params.segmentMapProvided || m_vp9Params.me16Enabled;
694 hucInputCmd1.PakOnlyMultipassEnable = m_vp9Params.vdencPakOnlyMultipassEnabled;
695 hucInputCmd1.num_ref_idx_l0_active_minus1 = (m_vp9Params.picParams->PicFlags.fields.frame_type) ? m_vp9Params.numRefFrames - 1 : 0;
696
697 hucInputCmd1.SADQPLambda = (uint16_t)(lambda * 4 + 0.5);
698 hucInputCmd1.RDQPLambda = (uint16_t)(lambda * lambda * 4 + 0.5); //U14.2
699
700 hucInputCmd1.SrcFrameHeightMinus1 = m_vp9Params.picParams->SrcFrameHeightMinus1;
701 hucInputCmd1.SrcFrameWidthMinus1 = m_vp9Params.picParams->SrcFrameWidthMinus1;
702 hucInputCmd1.SegmentationEnabled = m_vp9Params.segmentationEnabled;
703 hucInputCmd1.PrevFrameSegEnabled = m_vp9Params.prevFrameSegEnabled;
704 hucInputCmd1.LumaACQIndex = m_vp9Params.picParams->LumaACQIndex;
705 hucInputCmd1.LumaDCQIndexDelta = m_vp9Params.picParams->LumaDCQIndexDelta;
706
707 if (m_vp9Params.segmentationEnabled)
708 {
709 for (int i = 0; i < 8; i++)
710 {
711 hucInputCmd1.SegmentQIndexDelta[i] = m_vp9Params.segmentParams->SegData[i].SegmentQIndexDelta;
712 }
713 }
714
715 MOS_SecureMemcpy(hucConstData->InputCOM[1].data, sizeof(HucInputCmd1), &hucInputCmd1, sizeof(HucInputCmd1));
716 if (m_vp9Params.dynamicScalingEnabled)
717 {
718 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer);
719 }
720 else
721 {
722 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass]);
723 }
724 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
725 lockFlagsWriteOnly.WriteOnly = 1;
726
727 // Setup CmdInitializer DMEM
728 if (m_vp9Params.dynamicScalingEnabled)
729 {
730 hucCmdInitializerDmem = (HucComDmem *)m_osInterface->pfnLockResource(
731 m_osInterface, &m_cmdInitializerDysScalingDmemBuffer, &lockFlagsWriteOnly);
732 }
733 else
734 {
735 hucCmdInitializerDmem = (HucComDmem *)m_osInterface->pfnLockResource(
736 m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass], &lockFlagsWriteOnly);
737 }
738 CODECHAL_ENCODE_CHK_NULL_RETURN(hucCmdInitializerDmem);
739
740 MOS_ZeroMemory(hucCmdInitializerDmem, sizeof(HucComDmem));
741
742 hucCmdInitializerDmem->TotalOutputCommands = 2;
743
744 hucCmdInitializerDmem->TargetUsage = 4;
745
746 hucCmdInitializerDmem->Codec = 1;
747 hucCmdInitializerDmem->TargetUsage = (uint8_t)m_vp9Params.seqParams->TargetUsage;
748 hucCmdInitializerDmem->FrameType = (uint8_t)m_vp9Params.picParams->PicFlags.fields.frame_type;
749 hucCmdInitializerDmem->OutputCOM[0].ID = 2;
750 hucCmdInitializerDmem->OutputCOM[0].Type = 1;
751 hucCmdInitializerDmem->OutputCOM[0].StartInBytes = 0;
752
753 // Command ID 1
754 hucCmdInitializerDmem->OutputCOM[1].ID = 1;
755 hucCmdInitializerDmem->OutputCOM[1].Type = 1;
756 hucCmdInitializerDmem->OutputCOM[1].StartInBytes = 544;
757
758 hucCmdInitializerDmem->OutputSize = 544 + CODECHAL_CMD2_SIZE;
759 if (m_vp9Params.dynamicScalingEnabled)
760 {
761 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDysScalingDmemBuffer);
762 }
763 else
764 {
765 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass]);
766 }
767
768 return eStatus;
769 }
770 #if USE_CODECHAL_DEBUG_TOOL
DumpHucCmdInit(PMOS_RESOURCE secondlevelBB)771 MOS_STATUS CodechalCmdInitializer::DumpHucCmdInit(PMOS_RESOURCE secondlevelBB)
772 {
773 CODECHAL_ENCODE_FUNCTION_ENTER;
774 int idx = (m_encoder == nullptr) ? 0 : m_encoder->m_currRecycledBufIdx;
775 // Dump DMEM
776 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetDebugInterface()->DumpHucDmem(
777 &m_cmdInitializerDmemBuffer[idx][m_currentPass],
778 sizeof(HucComDmem),
779 m_currentPass,
780 hucRegionDumpCmdInitializer));
781
782 // Region 0 - input data buffer
783 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetDebugInterface()->DumpHucRegion(
784 &m_cmdInitializerDataBuffer[idx][m_currentPass],
785 0,
786 sizeof(HucComData),
787 0,
788 "",
789 true,
790 m_currentPass,
791 hucRegionDumpCmdInitializer));
792
793 // Region 1 - output cmd
794 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetDebugInterface()->DumpHucRegion(
795 secondlevelBB,
796 0,
797 m_hwInterface->m_vdencReadBatchBufferSize,
798 1,
799 "",
800 false,
801 m_currentPass,
802 hucRegionDumpCmdInitializer));
803
804 return MOS_STATUS_SUCCESS;
805 }
806 #endif
807 #endif
808