1 /*
2  * Copyright (c) 2020-2022, 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     encode_preenc_packet.cpp
24 //! \brief    Defines the interface for preenc packet
25 //!
26 
27 #include "encode_preenc_packet.h"
28 #include "encode_status_report_defs.h"
29 #include "media_perf_profiler.h"
30 #include "encode_utils.h"
31 #include "encode_status_report_defs.h"
32 #include "mos_solo_generic.h"
33 #include "encode_status_report_defs.h"
34 #include "codec_hw_next.h"
35 
36 using namespace mhw::vdbox;
37 
38 namespace encode
39 {
Init()40     MOS_STATUS EncodePreEncPacket::Init()
41     {
42         ENCODE_FUNC_CALL();
43         ENCODE_CHK_NULL_RETURN(m_statusReport);
44 
45         ENCODE_CHK_STATUS_RETURN(CmdPacket::Init());
46         m_basicFeature = dynamic_cast<PreEncBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::preEncFeature));
47         ENCODE_CHK_NULL_RETURN(m_basicFeature);
48         ENCODE_CHK_STATUS_RETURN(m_basicFeature->GetEncodeMode(m_encodeMode));
49 
50 #ifdef _MMC_SUPPORTED
51         m_mmcState = m_pipeline->GetMmcState();
52         ENCODE_CHK_NULL_RETURN(m_mmcState);
53         m_basicFeature->m_mmcState = m_mmcState;
54 #endif
55 
56         m_allocator = m_pipeline->GetEncodeAllocator();
57         ENCODE_CHK_STATUS_RETURN(AllocateResources());
58 
59         if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC)
60         {
61             ENCODE_CHK_STATUS_RETURN(m_statusReport->RegistObserver(this));
62         }
63 
64         CalculatePictureStateCommandSize();
65 
66         uint32_t vdencPictureStatesSize = 0, vdencPicturePatchListSize = 0;
67         GetVdencStateCommandsDataSize(vdencPictureStatesSize, vdencPicturePatchListSize);
68         m_defaultPictureStatesSize += vdencPictureStatesSize;
69         m_defaultPicturePatchListSize += vdencPicturePatchListSize;
70 
71         GetHxxPrimitiveCommandSize();
72 
73         m_usePatchList = m_osInterface->bUsesPatchList;
74 
75         return MOS_STATUS_SUCCESS;
76     }
77 
Prepare()78     MOS_STATUS EncodePreEncPacket::Prepare()
79     {
80         ENCODE_FUNC_CALL();
81 
82         m_pictureStatesSize    = m_defaultPictureStatesSize;
83         m_picturePatchListSize = m_defaultPicturePatchListSize;
84         m_sliceStatesSize      = m_defaultSliceStatesSize;
85         m_slicePatchListSize   = m_defaultSlicePatchListSize;
86 
87         MediaPipeline *pipeline = dynamic_cast<MediaPipeline *>(m_pipeline);
88         ENCODE_CHK_NULL_RETURN(pipeline);
89 
90         m_hevcIqMatrixParams = &(m_basicFeature->m_hevcIqMatrixParams);
91         m_nalUnitParams      = m_basicFeature->m_nalUnitParams;
92 
93         return MOS_STATUS_SUCCESS;
94     }
95 
Destroy()96     MOS_STATUS EncodePreEncPacket::Destroy()
97     {
98         if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC)
99         {
100             m_statusReport->UnregistObserver(this);
101         }
102         return MOS_STATUS_SUCCESS;
103     }
104 
AllocateResources()105     MOS_STATUS EncodePreEncPacket::AllocateResources()
106     {
107         ENCODE_FUNC_CALL();
108         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
109         ENCODE_CHK_NULL_RETURN(m_allocator);
110         MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
111         MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
112         allocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
113         allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
114         allocParamsForBufferLinear.Format   = Format_Buffer;
115 
116         allocParamsForBufferLinear.dwBytes  = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameWidth, m_basicFeature->m_maxLCUSize) * CODECHAL_CACHELINE_SIZE * 2 * 2;
117         allocParamsForBufferLinear.pBufName = "vdencIntraRowStoreScratch";
118         allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
119         m_vdencIntraRowStoreScratch         = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
120 
121         MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
122         allocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
123         allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
124         allocParamsForBufferLinear.Format   = Format_Buffer;
125 
126         // VDENC tile row store buffer
127         allocParamsForBufferLinear.dwBytes  = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameWidth, 32) * CODECHAL_CACHELINE_SIZE * 2;
128         allocParamsForBufferLinear.pBufName = "VDENC Tile Row Store Buffer";
129         allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
130         m_vdencTileRowStoreBuffer           = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
131 
132         hcp::HcpBufferSizePar hcpBufSizePar;
133         MOS_ZeroMemory(&hcpBufSizePar, sizeof(hcpBufSizePar));
134 
135         hcpBufSizePar.ucMaxBitDepth  = m_basicFeature->m_bitDepth;
136         hcpBufSizePar.ucChromaFormat = m_basicFeature->m_chromaFormat;
137         // We should move the buffer allocation to picture level if the size is dependent on LCU size
138         hcpBufSizePar.dwCtbLog2SizeY = 6;  //assume Max LCU size
139         hcpBufSizePar.dwPicWidth     = MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, m_basicFeature->m_maxLCUSize);
140         hcpBufSizePar.dwPicHeight    = MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, m_basicFeature->m_maxLCUSize);
141 
142         auto AllocateHcpBuffer = [&](PMOS_RESOURCE &res, const hcp::HCP_INTERNAL_BUFFER_TYPE bufferType, const char *bufferName) {
143             uint32_t bufSize         = 0;
144             hcpBufSizePar.bufferType = bufferType;
145             eStatus                  = m_hcpItf->GetHcpBufSize(hcpBufSizePar, bufSize);
146             if (eStatus != MOS_STATUS_SUCCESS)
147             {
148                 ENCODE_ASSERTMESSAGE("Failed to get hcp buffer size.");
149                 return eStatus;
150             }
151             allocParamsForBufferLinear.dwBytes  = bufSize;
152             allocParamsForBufferLinear.pBufName = bufferName;
153             allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
154             res                                 = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
155             return MOS_STATUS_SUCCESS;
156         };
157 
158         // Metadata Line buffer
159         ENCODE_CHK_STATUS_RETURN(AllocateHcpBuffer(m_resMetadataLineBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::META_LINE, "MetadataLineBuffer"));
160         // Metadata Tile Line buffer
161         ENCODE_CHK_STATUS_RETURN(AllocateHcpBuffer(m_resMetadataTileLineBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::META_TILE_LINE, "MetadataTileLineBuffer"));
162         // Metadata Tile Column buffer
163         ENCODE_CHK_STATUS_RETURN(AllocateHcpBuffer(m_resMetadataTileColumnBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::META_TILE_COL, "MetadataTileColumnBuffer"));
164 
165         return eStatus;
166     }
167 
SetPerfTag(uint16_t type,uint16_t mode,uint16_t picCodingType)168     void EncodePreEncPacket::SetPerfTag(uint16_t type, uint16_t mode, uint16_t picCodingType)
169     {
170         ENCODE_FUNC_CALL();
171 
172         PerfTagSetting perfTag    = {};
173         perfTag.Value             = 0;
174         perfTag.Mode              = mode & CODECHAL_ENCODE_MODE_BIT_MASK;
175         perfTag.CallType          = type;
176         perfTag.PictureCodingType = picCodingType > 3 ? 0 : picCodingType;
177         m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
178         m_osInterface->pfnIncPerfBufferID(m_osInterface);
179     }
180 
SendPrologCmds(MOS_COMMAND_BUFFER & cmdBuffer)181     MOS_STATUS EncodePreEncPacket::SendPrologCmds(
182             MOS_COMMAND_BUFFER &cmdBuffer)
183     {
184         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
185 
186         ENCODE_FUNC_CALL();
187 
188 #ifdef _MMC_SUPPORTED
189         ENCODE_CHK_NULL_RETURN(m_mmcState);
190         ENCODE_CHK_STATUS_RETURN(m_mmcState->SendPrologCmd(&cmdBuffer, false));
191 #endif
192 
193         MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
194         MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
195         genericPrologParams.pOsInterface  = m_osInterface;
196         genericPrologParams.pvMiInterface = nullptr;
197         genericPrologParams.bMmcEnabled   = m_mmcState ? m_mmcState->IsMmcEnabled() : false;
198         ENCODE_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
199 
200         return eStatus;
201     }
202 
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)203     MOS_STATUS EncodePreEncPacket::AddForceWakeup(MOS_COMMAND_BUFFER &cmdBuffer)
204     {
205         ENCODE_FUNC_CALL();
206 
207         auto &forceWakeupParams                     = m_miItf->MHW_GETPAR_F(MI_FORCE_WAKEUP)();
208         forceWakeupParams                           = {};
209         forceWakeupParams.bMFXPowerWellControl      = true;
210         forceWakeupParams.bMFXPowerWellControlMask  = true;
211         forceWakeupParams.bHEVCPowerWellControl     = true;
212         forceWakeupParams.bHEVCPowerWellControlMask = true;
213 
214         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FORCE_WAKEUP)(&cmdBuffer));
215 
216         return MOS_STATUS_SUCCESS;
217     }
218 
MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT,EncodePreEncPacket)219     MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT, EncodePreEncPacket)
220     {
221         ENCODE_FUNC_CALL();
222 
223         params.codecStandardSelect = CODECHAL_HEVC - CODECHAL_HCP_BASE;
224         params.bStreamOutEnabled   = false;
225         params.bVdencEnabled       = true;
226         params.codecSelect         = 1;
227 
228         params.multiEngineMode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_FE_LEGACY;
229         params.pipeWorkMode    = MHW_VDBOX_HCP_PIPE_WORK_MODE_LEGACY;
230 
231         params.bTileBasedReplayMode = 0;
232 
233         return MOS_STATUS_SUCCESS;
234     }
235 
AddHcpSurfaceStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const236     MOS_STATUS EncodePreEncPacket::AddHcpSurfaceStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const
237     {
238         ENCODE_FUNC_CALL();
239         ENCODE_CHK_NULL_RETURN(cmdBuffer);
240 
241         m_curHcpSurfStateId = CODECHAL_HCP_SRC_SURFACE_ID;
242         SETPAR_AND_ADDCMD(HCP_SURFACE_STATE, m_hcpItf, cmdBuffer);
243 
244         m_curHcpSurfStateId = CODECHAL_HCP_DECODED_SURFACE_ID;
245         SETPAR_AND_ADDCMD(HCP_SURFACE_STATE, m_hcpItf, cmdBuffer);
246 
247         m_curHcpSurfStateId = CODECHAL_HCP_REF_SURFACE_ID;
248         SETPAR_AND_ADDCMD(HCP_SURFACE_STATE, m_hcpItf, cmdBuffer);
249 
250         return MOS_STATUS_SUCCESS;
251     }
252 
MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE,EncodePreEncPacket)253     MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE, EncodePreEncPacket)
254     {
255         ENCODE_FUNC_CALL();
256 
257         params.Mode                 = m_basicFeature->m_mode;
258         params.psPreDeblockSurface  = &m_basicFeature->m_reconSurface;
259         params.psPostDeblockSurface = &m_basicFeature->m_reconSurface;
260         params.psRawSurface         = m_basicFeature->m_preEncRawSurface;
261 
262         params.presMetadataLineBuffer       = m_resMetadataLineBuffer;
263         params.presMetadataTileLineBuffer   = m_resMetadataTileLineBuffer;
264         params.presMetadataTileColumnBuffer = m_resMetadataTileColumnBuffer;
265 
266         params.bRawIs10Bit = m_basicFeature->m_is10Bit;
267 
268         return MOS_STATUS_SUCCESS;
269     }
270 
MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE,EncodePreEncPacket)271     MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE, EncodePreEncPacket)
272     {
273         ENCODE_FUNC_CALL();
274 
275         params.presMvObjectBuffer      = m_basicFeature->m_resMbCodeBuffer;
276         params.dwMvObjectOffset        = 0;
277         params.dwMvObjectSize          = m_basicFeature->m_mbCodeSize;
278         params.presPakBaseObjectBuffer = &m_basicFeature->m_resBitstreamBuffer;
279         params.dwPakBaseObjectSize     = m_basicFeature->m_bitstreamSize;
280 
281         return MOS_STATUS_SUCCESS;
282     }
283 
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)284     MOS_STATUS EncodePreEncPacket::StartStatusReport(
285             uint32_t            srType,
286             MOS_COMMAND_BUFFER *cmdBuffer)
287     {
288         ENCODE_FUNC_CALL();
289         ENCODE_CHK_NULL_RETURN(cmdBuffer);
290 
291         if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC)
292         {
293             ENCODE_CHK_STATUS_RETURN(MediaPacket::StartStatusReportNext(srType, cmdBuffer));
294         }
295 
296         MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
297         ENCODE_CHK_NULL_RETURN(perfProfiler);
298         ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectStartCmd(
299                     (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer));
300 
301         return MOS_STATUS_SUCCESS;
302     }
303 
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)304     MOS_STATUS EncodePreEncPacket::EndStatusReport(
305             uint32_t            srType,
306             MOS_COMMAND_BUFFER *cmdBuffer)
307     {
308         ENCODE_FUNC_CALL();
309         ENCODE_CHK_NULL_RETURN(cmdBuffer);
310 
311         if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC)
312         {
313             ENCODE_CHK_STATUS_RETURN(MediaPacket::EndStatusReportNext(srType, cmdBuffer));
314         }
315 
316         MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
317         ENCODE_CHK_NULL_RETURN(perfProfiler);
318         ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectEndCmd(
319                     (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer));
320 
321         return MOS_STATUS_SUCCESS;
322     }
323 
ReadHcpStatus(MHW_VDBOX_NODE_IND vdboxIndex,MediaStatusReport * statusReport,MOS_COMMAND_BUFFER & cmdBuffer)324     MOS_STATUS EncodePreEncPacket::ReadHcpStatus(
325             MHW_VDBOX_NODE_IND  vdboxIndex,
326             MediaStatusReport * statusReport,
327             MOS_COMMAND_BUFFER &cmdBuffer)
328     {
329         ENCODE_FUNC_CALL();
330 
331         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
332 
333         CODEC_HW_FUNCTION_ENTER;
334 
335         ENCODE_CHK_NULL_RETURN(statusReport);
336         ENCODE_CHK_NULL_RETURN(m_hwInterface);
337 
338         MOS_RESOURCE *osResource = nullptr;
339         uint32_t      offset     = 0;
340 
341         EncodeStatusReadParams params;
342         MOS_ZeroMemory(&params, sizeof(params));
343 
344         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportMfxBitstreamByteCountPerFrame, osResource, offset));
345         params.resBitstreamByteCountPerFrame    = osResource;
346         params.bitstreamByteCountPerFrameOffset = offset;
347 
348         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportMfxBitstreamSyntaxElementOnlyBitCount, osResource, offset));
349         params.resBitstreamSyntaxElementOnlyBitCount    = osResource;
350         params.bitstreamSyntaxElementOnlyBitCountOffset = offset;
351 
352         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportQPStatusCount, osResource, offset));
353         params.resQpStatusCount    = osResource;
354         params.qpStatusCountOffset = offset;
355 
356         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportImageStatusMask, osResource, offset));
357         params.resImageStatusMask    = osResource;
358         params.imageStatusMaskOffset = offset;
359 
360         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportImageStatusCtrl, osResource, offset));
361         params.resImageStatusCtrl    = osResource;
362         params.imageStatusCtrlOffset = offset;
363 
364         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportNumSlices, osResource, offset));
365         params.resNumSlices    = osResource;
366         params.numSlicesOffset = offset;
367 
368         ENCODE_CHK_STATUS_RETURN(m_hwInterface->ReadHcpStatus(vdboxIndex, params, &cmdBuffer));
369 
370         ENCODE_CHK_STATUS_RETURN(m_hwInterface->ReadImageStatusForHcp(vdboxIndex, params, &cmdBuffer));
371         return eStatus;
372     }
373 
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)374     MOS_STATUS EncodePreEncPacket::Completed(void *mfxStatus, void *rcsStatus, void *statusReport)
375     {
376         ENCODE_FUNC_CALL();
377 
378         ENCODE_CHK_NULL_RETURN(statusReport);
379         ENCODE_CHK_NULL_RETURN(m_basicFeature);
380 
381         EncodeStatusReportData *statusReportData = (EncodeStatusReportData *)statusReport;
382 #if USE_CODECHAL_DEBUG_TOOL
383         auto preencFeature = dynamic_cast<PreEncBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::preEncFeature));
384         ENCODE_CHK_NULL_RETURN(preencFeature);
385         preencFeature->EncodePreencBasicFuntion1();
386 #endif
387 
388         m_basicFeature->Reset((CODEC_REF_LIST *)statusReportData->currRefList);
389         return MOS_STATUS_SUCCESS;
390     }
391 
GetVdencStateCommandsDataSize(uint32_t & vdencPictureStatesSize,uint32_t & vdencPicturePatchListSize)392     MOS_STATUS EncodePreEncPacket::GetVdencStateCommandsDataSize(uint32_t &vdencPictureStatesSize, uint32_t &vdencPicturePatchListSize)
393     {
394         vdencPictureStatesSize =
395             m_vdencItf->MHW_GETSIZE_F(VDENC_PIPE_MODE_SELECT)() +
396             m_vdencItf->MHW_GETSIZE_F(VDENC_SRC_SURFACE_STATE)() +
397             m_vdencItf->MHW_GETSIZE_F(VDENC_REF_SURFACE_STATE)() +
398             m_vdencItf->MHW_GETSIZE_F(VDENC_DS_REF_SURFACE_STATE)() +
399             m_vdencItf->MHW_GETSIZE_F(VDENC_PIPE_BUF_ADDR_STATE)() +
400             m_vdencItf->MHW_GETSIZE_F(VDENC_WEIGHTSOFFSETS_STATE)() +
401             m_vdencItf->MHW_GETSIZE_F(VDENC_WALKER_STATE)() +
402             m_vdencItf->MHW_GETSIZE_F(VD_PIPELINE_FLUSH)() +
403             m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_IMM)()*8 +
404             m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() +
405             m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)() +
406             m_hcpItf->MHW_GETSIZE_F(HEVC_VP9_RDOQ_STATE)() +
407             m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)();
408 
409         vdencPicturePatchListSize = PATCH_LIST_COMMAND(mhw::vdbox::vdenc::Itf::VDENC_PIPE_BUF_ADDR_STATE_CMD);
410 
411         return MOS_STATUS_SUCCESS;
412     }
413 
GetHxxPrimitiveCommandSize()414     MOS_STATUS EncodePreEncPacket::GetHxxPrimitiveCommandSize()
415     {
416         uint32_t hcpCommandsSize  = 0;
417         uint32_t hcpPatchListSize = 0;
418         hcpCommandsSize =
419             m_hcpItf->MHW_GETSIZE_F(HCP_REF_IDX_STATE)() * 2 +
420             m_hcpItf->MHW_GETSIZE_F(HCP_WEIGHTOFFSET_STATE)() * 2 +
421             m_hcpItf->MHW_GETSIZE_F(HCP_SLICE_STATE)() +
422             m_hcpItf->MHW_GETSIZE_F(HCP_PAK_INSERT_OBJECT)() +
423             m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)() * 2 +
424             m_hcpItf->MHW_GETSIZE_F(HCP_TILE_CODING)();  // one slice cannot be with more than one tile
425 
426         hcpPatchListSize =
427             mhw::vdbox::hcp::Itf::HCP_REF_IDX_STATE_CMD_NUMBER_OF_ADDRESSES * 2 +
428             mhw::vdbox::hcp::Itf::HCP_WEIGHTOFFSET_STATE_CMD_NUMBER_OF_ADDRESSES * 2 +
429             mhw::vdbox::hcp::Itf::HCP_SLICE_STATE_CMD_NUMBER_OF_ADDRESSES +
430             mhw::vdbox::hcp::Itf::HCP_PAK_INSERT_OBJECT_CMD_NUMBER_OF_ADDRESSES +
431             mhw::vdbox::hcp::Itf::MI_BATCH_BUFFER_START_CMD_NUMBER_OF_ADDRESSES * 2 +  // One is for the PAK command and another one is for the BB when BRC and single task mode are on
432             mhw::vdbox::hcp::Itf::HCP_TILE_CODING_COMMAND_NUMBER_OF_ADDRESSES;         // HCP_TILE_CODING_STATE command
433 
434         uint32_t cpCmdsize = 0;
435         uint32_t cpPatchListSize = 0;
436         if (m_hwInterface->GetCpInterface())
437         {
438             m_hwInterface->GetCpInterface()->GetCpSliceLevelCmdSize(cpCmdsize, cpPatchListSize);
439         }
440 
441         m_defaultSliceStatesSize = hcpCommandsSize + (uint32_t)cpCmdsize;
442         m_defaultSlicePatchListSize = hcpPatchListSize + (uint32_t)cpPatchListSize;
443         return MOS_STATUS_SUCCESS;
444     }
445 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)446     MOS_STATUS EncodePreEncPacket::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
447     {
448         m_pictureStatesSize    = m_defaultPictureStatesSize;
449         m_picturePatchListSize = m_defaultPicturePatchListSize;
450         m_sliceStatesSize      = m_defaultSliceStatesSize;
451         m_slicePatchListSize   = m_defaultSlicePatchListSize;
452 
453         commandBufferSize      = CalculateCommandBufferSize();
454         requestedPatchListSize = CalculatePatchListSize();
455         return MOS_STATUS_SUCCESS;
456     }
457 
CalculateCommandBufferSize()458     uint32_t EncodePreEncPacket::CalculateCommandBufferSize()
459     {
460         ENCODE_FUNC_CALL();
461         uint32_t commandBufferSize = 0;
462 
463         commandBufferSize = m_pictureStatesSize + m_sliceStatesSize;
464 
465         if (m_pipeline->IsSingleTaskPhaseSupported())
466         {
467             commandBufferSize *= m_pipeline->GetPassNum();
468         }
469 
470         // 4K align since allocation is in chunks of 4K bytes.
471         commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE);
472 
473         return commandBufferSize;
474     }
475 
CalculatePatchListSize()476     uint32_t EncodePreEncPacket::CalculatePatchListSize()
477     {
478         ENCODE_FUNC_CALL();
479         uint32_t requestedPatchListSize = 0;
480         if (m_usePatchList)
481         {
482             requestedPatchListSize = m_picturePatchListSize + m_slicePatchListSize;
483 
484             if (m_pipeline->IsSingleTaskPhaseSupported())
485             {
486                 requestedPatchListSize *= m_pipeline->GetPassNum();
487             }
488 
489             // Multi pipes are sharing one patchlist
490             requestedPatchListSize *= m_pipeline->GetPipeNum();
491         }
492         return requestedPatchListSize;
493     }
494 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,EncodePreEncPacket)495     MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, EncodePreEncPacket)
496     {
497         //params.tlbPrefetch = true;
498 
499         // can be enabled by reg key (disabled by default)
500         params.pakObjCmdStreamOut = false;
501 
502         if (!MEDIA_IS_WA(m_osInterface->pfnGetWaTable(m_osInterface), WaEnableOnlyASteppingFeatures))
503         {
504             params.VdencPipeModeSelectPar0 = 1;
505         }
506 
507         params.rgbEncodingMode = false;
508 
509         return MOS_STATUS_SUCCESS;
510     }
511 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,EncodePreEncPacket)512     MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, EncodePreEncPacket)
513     {
514         params.intraRowStoreScratchBuffer       = m_vdencIntraRowStoreScratch;
515         params.tileRowStoreBuffer               = m_vdencTileRowStoreBuffer;
516 
517         return MOS_STATUS_SUCCESS;
518     }
519 
MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH,EncodePreEncPacket)520     MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH, EncodePreEncPacket)
521     {
522         switch (m_flushCmd)
523         {
524             case waitHevc:
525                 params.waitDoneHEVC           = true;
526                 params.flushHEVC              = true;
527                 params.waitDoneVDCmdMsgParser = true;
528                 break;
529             case waitVdenc:
530                 params.waitDoneMFX            = true;
531                 params.waitDoneVDENC          = true;
532                 params.flushVDENC             = true;
533                 params.waitDoneVDCmdMsgParser = true;
534                 break;
535             case waitHevcVdenc:
536                 params.waitDoneMFX            = true;
537                 params.waitDoneVDENC          = true;
538                 params.flushVDENC             = true;
539                 params.flushHEVC              = true;
540                 params.waitDoneVDCmdMsgParser = true;
541                 break;
542         }
543 
544         return MOS_STATUS_SUCCESS;
545     }
546 
547 #if USE_CODECHAL_DEBUG_TOOL
DumpResources(EncodeStatusMfx * encodeStatusMfx,EncodeStatusReportData * statusReportData)548     MOS_STATUS EncodePreEncPacket::DumpResources(
549             EncodeStatusMfx *       encodeStatusMfx,
550             EncodeStatusReportData *statusReportData)
551     {
552         ENCODE_FUNC_CALL();
553         ENCODE_CHK_NULL_RETURN(encodeStatusMfx);
554         ENCODE_CHK_NULL_RETURN(statusReportData);
555         ENCODE_CHK_NULL_RETURN(m_pipeline);
556         ENCODE_CHK_NULL_RETURN(m_statusReport);
557         ENCODE_CHK_NULL_RETURN(m_basicFeature);
558         ENCODE_CHK_NULL_RETURN(m_basicFeature->m_trackedBuf);
559 
560         CodechalDebugInterface *debugInterface = m_pipeline->GetStatusReportDebugInterface();
561         ENCODE_CHK_NULL_RETURN(debugInterface);
562 
563         CODEC_REF_LIST currRefList = *((CODEC_REF_LIST *)statusReportData->currRefList);
564         currRefList.RefPic         = statusReportData->currOriginalPic;
565 
566         debugInterface->m_currPic            = statusReportData->currOriginalPic;
567         debugInterface->m_bufferDumpFrameNum = m_statusReport->GetReportedCount();
568         debugInterface->m_frameType          = encodeStatusMfx->pictureCodingType;
569 
570         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
571                     &currRefList.resBitstreamBuffer,
572                     CodechalDbgAttr::attrBitstream,
573                     "_PAK",
574                     statusReportData->bitstreamSize,
575                     0,
576                     CODECHAL_NUM_MEDIA_STATES));
577 
578         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpData(
579                     statusReportData,
580                     sizeof(EncodeStatusReportData),
581                     CodechalDbgAttr::attrStatusReport,
582                     "EncodeStatusReport_Buffer"));
583 
584         MOS_SURFACE *ds4xSurface = m_basicFeature->m_trackedBuf->GetSurface(
585                 BufferType::ds4xSurface, currRefList.ucScalingIdx);
586 
587         if (ds4xSurface != nullptr)
588         {
589             ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
590                         ds4xSurface,
591                         CodechalDbgAttr::attrReconstructedSurface,
592                         "4xScaledSurf"))
593         }
594 
595         MOS_SURFACE *ds8xSurface = m_basicFeature->m_trackedBuf->GetSurface(
596                 BufferType::ds8xSurface, currRefList.ucScalingIdx);
597 
598         if (ds8xSurface != nullptr)
599         {
600             ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
601                         ds8xSurface,
602                         CodechalDbgAttr::attrReconstructedSurface,
603                         "8xScaledSurf"))
604         }
605 
606         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
607                     &currRefList.sRefReconBuffer,
608                     CodechalDbgAttr::attrReconstructedSurface,
609                     "ReconSurf"))
610 
611         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
612                     &currRefList.sRefRawBuffer,
613                     CodechalDbgAttr::attrEncodeRawInputSurface,
614                     "SrcSurf"))
615 
616         return MOS_STATUS_SUCCESS;
617     }
618 
619 #endif
620 
SubmitPictureLevel(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)621     MOS_STATUS EncodePreEncPacket::SubmitPictureLevel(
622             MOS_COMMAND_BUFFER *commandBuffer,
623             uint8_t             packetPhase)
624     {
625         ENCODE_FUNC_CALL();
626 
627         MOS_COMMAND_BUFFER &cmdBuffer = *commandBuffer;
628         ENCODE_CHK_STATUS_RETURN(Mos_Solo_PreProcessEncode(m_osInterface, &m_basicFeature->m_resBitstreamBuffer, &m_basicFeature->m_reconSurface));
629 
630         MOS_SYNC_PARAMS syncParams;
631         syncParams                  = g_cInitSyncParams;
632         syncParams.GpuContext       = m_osInterface->pfnGetGpuContext(m_osInterface);
633         syncParams.presSyncResource = &m_basicFeature->m_preEncRawSurface->OsResource;
634         syncParams.bReadOnly        = true;
635         ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
636         m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
637 
638         ENCODE_CHK_STATUS_RETURN(PatchPictureLevelCommands(packetPhase, cmdBuffer));
639 
640         return MOS_STATUS_SUCCESS;
641     }
642 
Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)643     MOS_STATUS EncodePreEncPacket::Submit(
644             MOS_COMMAND_BUFFER *commandBuffer,
645             uint8_t             packetPhase)
646     {
647         ENCODE_FUNC_CALL();
648 
649         ENCODE_CHK_STATUS_RETURN(PrepareRawSurface());
650 
651         ENCODE_CHK_STATUS_RETURN(SubmitPictureLevel(commandBuffer, packetPhase));
652 
653         MOS_COMMAND_BUFFER &cmdBuffer = *commandBuffer;
654 
655         ENCODE_CHK_STATUS_RETURN(PatchSliceLevelCommands(cmdBuffer, packetPhase));
656 
657         ENCODE_CHK_STATUS_RETURN(Mos_Solo_PostProcessEncode(m_osInterface, &m_basicFeature->m_resBitstreamBuffer, &m_basicFeature->m_reconSurface));
658 
659         m_enablePreEncStatusReport = true;
660 
661         return MOS_STATUS_SUCCESS;
662     }
663 
PrepareRawSurface()664     MOS_STATUS EncodePreEncPacket::PrepareRawSurface()
665     {
666         ENCODE_FUNC_CALL();
667 
668         if (m_basicFeature->m_rawDsSurface != nullptr)
669         {
670             ENCODE_CHK_STATUS_RETURN(RawSurfaceDownScaling(&m_basicFeature->m_rawSurface, m_basicFeature->m_rawDsSurface));
671             m_basicFeature->m_preEncRawSurface = m_basicFeature->m_rawDsSurface;
672         }
673         else
674         {
675             m_basicFeature->m_preEncRawSurface = &m_basicFeature->m_rawSurface;
676         }
677 
678         return MOS_STATUS_SUCCESS;
679     }
680 
RawSurfaceDownScaling(const PMOS_SURFACE inSurf,PMOS_SURFACE outSurf)681     MOS_STATUS EncodePreEncPacket::RawSurfaceDownScaling(const PMOS_SURFACE inSurf, PMOS_SURFACE outSurf)
682     {
683         ENCODE_FUNC_CALL();
684 
685         if (outSurf == nullptr)
686         {
687             return MOS_STATUS_SUCCESS;
688         }
689 
690         VEBOX_SFC_PARAMS params = {};
691 
692         params.input.surface      = inSurf;
693         params.input.colorSpace   = CSpace_Any;
694         params.input.chromaSiting = 0;
695         params.input.rcSrc        = {0, 0, (long)inSurf->dwWidth, (long)inSurf->dwHeight};
696         params.input.rotation     = ROTATION_IDENTITY;
697 
698         params.output.surface      = outSurf;
699         params.output.colorSpace   = CSpace_Any;
700         params.output.chromaSiting = 0;
701         params.output.rcDst        = {0, 0, (long)outSurf->dwWidth, (long)outSurf->dwHeight};
702 
703         ENCODE_CHK_STATUS_RETURN(m_sfcItf->Render(params));
704 
705         m_pipeline->ContextSwitchBack();
706 
707         return MOS_STATUS_SUCCESS;
708     }
709 
PatchPictureLevelCommands(const uint8_t & packetPhase,MOS_COMMAND_BUFFER & cmdBuffer)710     MOS_STATUS EncodePreEncPacket::PatchPictureLevelCommands(const uint8_t &packetPhase, MOS_COMMAND_BUFFER &cmdBuffer)
711     {
712         ENCODE_FUNC_CALL();
713 
714         ENCODE_CHK_STATUS_RETURN(m_miItf->SetWatchdogTimerThreshold(m_basicFeature->m_frameWidth, m_basicFeature->m_frameHeight, true));
715 
716         SetPerfTag(CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE, (uint16_t)m_basicFeature->m_mode, m_basicFeature->GetPictureCodingType());
717 
718         bool firstTaskInPhase = packetPhase & firstPacket;
719         if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase)
720         {
721             ENCODE_CHK_STATUS_RETURN(AddForceWakeup(cmdBuffer));
722 
723             // Send command buffer header at the beginning (OS dependent)
724             ENCODE_CHK_STATUS_RETURN(SendPrologCmds(cmdBuffer));
725         }
726 
727         ENCODE_CHK_STATUS_RETURN(StartStatusReport(statusReportMfx, &cmdBuffer));
728 
729         ENCODE_CHK_STATUS_RETURN(AddPictureHcpCommands(cmdBuffer));
730 
731         ENCODE_CHK_STATUS_RETURN(AddPictureVdencCommands(cmdBuffer));
732 
733         ENCODE_CHK_STATUS_RETURN(AddPicStateWithNoTile(cmdBuffer));
734 
735         return MOS_STATUS_SUCCESS;
736     }
737 
PatchSliceLevelCommands(MOS_COMMAND_BUFFER & cmdBuffer,uint8_t packetPhase)738     MOS_STATUS EncodePreEncPacket::PatchSliceLevelCommands(MOS_COMMAND_BUFFER &cmdBuffer, uint8_t packetPhase)
739     {
740         ENCODE_FUNC_CALL();
741 
742         ENCODE_CHK_STATUS_RETURN(SendHwSliceEncodeCommand(cmdBuffer));
743 
744         m_flushCmd = waitVdenc;
745         SETPAR_AND_ADDCMD(VD_PIPELINE_FLUSH, m_vdencItf, &cmdBuffer);
746 
747         ENCODE_CHK_STATUS_RETURN(EnsureAllCommandsExecuted(cmdBuffer));
748 
749         m_flushCmd = waitHevc;
750         SETPAR_AND_ADDCMD(VD_PIPELINE_FLUSH, m_vdencItf, &cmdBuffer);
751 
752         ENCODE_CHK_STATUS_RETURN(EnsureAllCommandsExecuted(cmdBuffer));
753 
754         if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC)
755         {
756             ENCODE_CHK_STATUS_RETURN(ReadHcpStatus(MHW_VDBOX_NODE_1, m_statusReport, cmdBuffer));
757         }
758 
759         ENCODE_CHK_STATUS_RETURN(EndStatusReport(statusReportMfx, &cmdBuffer));
760 
761         if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC)
762         {
763             ENCODE_CHK_STATUS_RETURN(MediaPacket::UpdateStatusReportNext(statusReportGlobalCount, &cmdBuffer));
764         }
765 
766         return MOS_STATUS_SUCCESS;
767     }
768 
AddPicStateWithNoTile(MOS_COMMAND_BUFFER & cmdBuffer)769     MOS_STATUS EncodePreEncPacket::AddPicStateWithNoTile(
770             MOS_COMMAND_BUFFER &cmdBuffer)
771     {
772         ENCODE_FUNC_CALL();
773 
774         SETPAR_AND_ADDCMD(VDENC_CMD1, m_vdencItf, &cmdBuffer);
775 
776         SETPAR_AND_ADDCMD(HCP_PIC_STATE, m_hcpItf, &cmdBuffer);
777 
778         SETPAR_AND_ADDCMD(VDENC_CMD2, m_vdencItf, &cmdBuffer);
779 
780         // Send HEVC_VP9_RDOQ_STATE command
781         SETPAR_AND_ADDCMD(HEVC_VP9_RDOQ_STATE, m_hcpItf, &cmdBuffer);
782 
783         return MOS_STATUS_SUCCESS;
784     }
785 
EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER & cmdBuffer)786     MOS_STATUS EncodePreEncPacket::EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER &cmdBuffer)
787     {
788         ENCODE_FUNC_CALL();
789 
790         // Send MI_FLUSH command
791         auto &flushDwParams                         = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
792         flushDwParams                               = {};
793         flushDwParams.bVideoPipelineCacheInvalidate = true;
794         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer));
795 
796         return MOS_STATUS_SUCCESS;
797     }
798 
AddPictureVdencCommands(MOS_COMMAND_BUFFER & cmdBuffer)799     MOS_STATUS EncodePreEncPacket::AddPictureVdencCommands(MOS_COMMAND_BUFFER &cmdBuffer)
800     {
801         ENCODE_FUNC_CALL();
802 
803         SETPAR_AND_ADDCMD(VDENC_PIPE_MODE_SELECT, m_vdencItf, &cmdBuffer);
804         SETPAR_AND_ADDCMD(VDENC_SRC_SURFACE_STATE, m_vdencItf, &cmdBuffer);
805         SETPAR_AND_ADDCMD(VDENC_REF_SURFACE_STATE, m_vdencItf, &cmdBuffer);
806         SETPAR_AND_ADDCMD(VDENC_DS_REF_SURFACE_STATE, m_vdencItf, &cmdBuffer);
807         SETPAR_AND_ADDCMD(VDENC_PIPE_BUF_ADDR_STATE, m_vdencItf, &cmdBuffer);
808 
809         return MOS_STATUS_SUCCESS;
810     }
811 
AddPictureHcpCommands(MOS_COMMAND_BUFFER & cmdBuffer)812     MOS_STATUS EncodePreEncPacket::AddPictureHcpCommands(
813             MOS_COMMAND_BUFFER &cmdBuffer)
814     {
815         ENCODE_FUNC_CALL();
816 
817         ENCODE_CHK_STATUS_RETURN(AddHcpPipeModeSelect(cmdBuffer));
818 
819         ENCODE_CHK_STATUS_RETURN(AddHcpSurfaceStateCmds(&cmdBuffer));
820 
821         SETPAR_AND_ADDCMD(HCP_PIPE_BUF_ADDR_STATE, m_hcpItf, &cmdBuffer);
822 
823         SETPAR_AND_ADDCMD(HCP_IND_OBJ_BASE_ADDR_STATE, m_hcpItf, &cmdBuffer);
824 
825         ENCODE_CHK_STATUS_RETURN(AddHcpFqmStateCmds(&cmdBuffer));
826         ENCODE_CHK_STATUS_RETURN(AddHcpQMStateCmds(&cmdBuffer));
827 
828         return MOS_STATUS_SUCCESS;
829     }
830 
AddHcpPipeModeSelect(MOS_COMMAND_BUFFER & cmdBuffer)831     MOS_STATUS EncodePreEncPacket::AddHcpPipeModeSelect(
832             MOS_COMMAND_BUFFER &cmdBuffer)
833     {
834         ENCODE_FUNC_CALL();
835 
836         SETPAR_AND_ADDCMD(VDENC_CONTROL_STATE, m_vdencItf, &cmdBuffer);
837 
838         auto &vdControlStateParams          = m_miItf->MHW_GETPAR_F(VD_CONTROL_STATE)();
839         vdControlStateParams                = {};
840         vdControlStateParams.initialization = true;
841         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(VD_CONTROL_STATE)(&cmdBuffer));
842 
843         // for Gen11+, we need to add MFX wait for both KIN and VRT before and after HCP Pipemode select...
844         auto &mfxWaitParams               = m_miItf->MHW_GETPAR_F(MFX_WAIT)();
845         mfxWaitParams                     = {};
846         mfxWaitParams.iStallVdboxPipeline = true;
847         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer));
848 
849         SETPAR_AND_ADDCMD(HCP_PIPE_MODE_SELECT, m_hcpItf, &cmdBuffer);
850 
851         mfxWaitParams                     = {};
852         mfxWaitParams.iStallVdboxPipeline = true;
853         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer));
854 
855         return MOS_STATUS_SUCCESS;
856     }
857 
CalculatePictureStateCommandSize()858     MOS_STATUS EncodePreEncPacket::CalculatePictureStateCommandSize()
859     {
860         ENCODE_FUNC_CALL();
861 
862         uint32_t hcpCommandsSize  = 0;
863         uint32_t hcpPatchListSize = 0;
864         uint32_t cpCmdsize        = 0;
865         uint32_t cpPatchListSize  = 0;
866         uint32_t hucCommandsSize = 0;
867         uint32_t hucPatchListSize = 0;
868 
869         MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
870 
871         hcpCommandsSize =
872             m_vdencItf->MHW_GETSIZE_F(VD_PIPELINE_FLUSH)() +
873             m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() +
874             m_hcpItf->MHW_GETSIZE_F(HCP_PIPE_MODE_SELECT)() +
875             m_hcpItf->MHW_GETSIZE_F(HCP_SURFACE_STATE)() +
876             m_hcpItf->MHW_GETSIZE_F(HCP_PIPE_BUF_ADDR_STATE)() +
877             m_hcpItf->MHW_GETSIZE_F(HCP_IND_OBJ_BASE_ADDR_STATE)() +
878             m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_REG)() * 8;
879 
880         hcpPatchListSize =
881             PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::VD_PIPELINE_FLUSH_CMD) +
882             PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_FLUSH_DW_CMD) +
883             PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_PIPE_MODE_SELECT_CMD) +
884             PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_SURFACE_STATE_CMD) +
885             PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_PIPE_BUF_ADDR_STATE_CMD) +
886             PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_IND_OBJ_BASE_ADDR_STATE_CMD);
887 
888         // HCP_QM_STATE_CMD may be issued up to 20 times: 3x Colour Component plus 2x intra/inter plus 4x SizeID minus 4 for the 32x32 chroma components.
889         // HCP_FQP_STATE_CMD may be issued up to 8 times: 4 scaling list per intra and inter.
890         hcpCommandsSize +=
891             2 * m_miItf->MHW_GETSIZE_F(VD_CONTROL_STATE)() +
892             m_hcpItf->MHW_GETSIZE_F(HCP_SURFACE_STATE)() +  // encoder needs two surface state commands. One is for raw and another one is for recon surfaces.
893             20 * m_hcpItf->MHW_GETSIZE_F(HCP_QM_STATE)() +
894             8 * m_hcpItf->MHW_GETSIZE_F(HCP_FQM_STATE)() +
895             m_hcpItf->MHW_GETSIZE_F(HCP_PIC_STATE)() +
896             m_hcpItf->MHW_GETSIZE_F(HEVC_VP9_RDOQ_STATE)() +        // RDOQ
897             2 * m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() +       // Slice level commands
898             2 * m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() +             // need for Status report, Mfc Status and
899             10 * m_miItf->MHW_GETSIZE_F(MI_STORE_REGISTER_MEM)() +  // 8 for BRCStatistics and 2 for RC6 WAs
900             m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_MEM)() +        // 1 for RC6 WA
901             2 * m_hcpItf->MHW_GETSIZE_F(HCP_PAK_INSERT_OBJECT)() +  // Two PAK insert object commands are for headers before the slice header and the header for the end of stream
902             4 * m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() +       // two (BRC+reference frame) for clean-up HW semaphore memory and another two for signal it
903             17 * m_miItf->MHW_GETSIZE_F(MI_SEMAPHORE_WAIT)() +      // Use HW wait command for each reference and one wait for current semaphore object
904             m_miItf->MHW_GETSIZE_F(MI_SEMAPHORE_WAIT)() +           // Use HW wait command for each BRC pass
905             +m_miItf->MHW_GETSIZE_F(MI_SEMAPHORE_WAIT)()            // Use HW wait command for each VDBOX
906             + 2 * m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)()       // One is for reset and another one for set per VDBOX
907             + 8 * m_miItf->MHW_GETSIZE_F(MI_COPY_MEM_MEM)()         // Need to copy SSE statistics/ Slice Size overflow into memory
908             ;
909 
910         hcpPatchListSize +=
911             20 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_QM_STATE_CMD) +
912             8 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_FQM_STATE_CMD) +
913             PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_PIC_STATE_CMD) +
914             PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_BATCH_BUFFER_START_CMD) +       // When BRC is on, HCP_PIC_STATE_CMD command is in the BB
915             2 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD) +       // Slice level commands
916             2 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_FLUSH_DW_CMD) +             // need for Status report, Mfc Status and
917             11 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_STORE_REGISTER_MEM_CMD) +  // 8 for BRCStatistics and 3 for RC6 WAs
918             22 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD)        // Use HW wait commands plus its memory clean-up and signal (4+ 16 + 1 + 1)
919             + 8 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_BATCH_BUFFER_START_CMD)   // At maximal, there are 8 batch buffers for 8 VDBOXes for VE. Each box has one BB.
920             + PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_FLUSH_DW_CMD)                 // Need one flush before copy command
921             + PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MFX_WAIT_CMD)                    // Need one wait after copy command
922             + 3 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD)       // one wait commands and two for reset and set semaphore memory
923             + 8 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_COPY_MEM_MEM_CMD)         // Need to copy SSE statistics/ Slice Size overflow into memory
924             ;
925 
926         auto cpInterface = m_hwInterface->GetCpInterface();
927         cpInterface->GetCpStateLevelCmdSize(cpCmdsize, cpPatchListSize);
928 
929         ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize(
930                 m_basicFeature->m_mode, (uint32_t *)&hucCommandsSize, (uint32_t *)&hucPatchListSize, &stateCmdSizeParams));
931 
932         m_defaultPictureStatesSize    = hcpCommandsSize + hucCommandsSize + (uint32_t)cpCmdsize;
933         m_defaultPicturePatchListSize = hcpPatchListSize + hucPatchListSize + (uint32_t)cpPatchListSize;
934 
935         return MOS_STATUS_SUCCESS;
936     }
937 
SendHwSliceEncodeCommand(MOS_COMMAND_BUFFER & cmdBuffer)938     MOS_STATUS EncodePreEncPacket::SendHwSliceEncodeCommand(
939             MOS_COMMAND_BUFFER &cmdBuffer)
940     {
941         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
942 
943         ENCODE_FUNC_CALL();
944 
945         // VDENC does not use batch buffer for slice state
946         // add HCP_REF_IDX command
947         ENCODE_CHK_STATUS_RETURN(AddHcpRefIdxStateCmds(&cmdBuffer));
948 
949         // add HEVC Slice state commands
950         SETPAR_AND_ADDCMD(HCP_SLICE_STATE, m_hcpItf, &cmdBuffer);
951 
952         // add HCP_PAK_INSERT_OBJECTS command
953         ENCODE_CHK_STATUS_RETURN(AddHcpPakInsertObjectCmds(&cmdBuffer));
954 
955         // Send VDENC_WEIGHT_OFFSETS_STATE command
956         SETPAR_AND_ADDCMD(VDENC_WEIGHTSOFFSETS_STATE, m_vdencItf, &cmdBuffer);
957 
958         SETPAR_AND_ADDCMD(VDENC_HEVC_VP9_TILE_SLICE_STATE, m_vdencItf, &cmdBuffer);
959 
960         // Send VDENC_WALKER_STATE command
961         SETPAR_AND_ADDCMD(VDENC_WALKER_STATE, m_vdencItf, &cmdBuffer);
962 
963         return eStatus;
964     }
965 
MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,EncodePreEncPacket)966     MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, EncodePreEncPacket)
967     {
968 
969         params.numPipe = VDENC_PIPE_SINGLE_PIPE;
970 
971         return MOS_STATUS_SUCCESS;
972     }
973 
MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE,EncodePreEncPacket)974     MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE, EncodePreEncPacket)
975     {
976         params.surfaceStateId = m_curHcpSurfStateId;
977 
978         return MOS_STATUS_SUCCESS;
979     }
980 
MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE,EncodePreEncPacket)981     MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE, EncodePreEncPacket)
982     {
983         ENCODE_FUNC_CALL();
984 
985         params.intrareffetchdisable = false;
986 
987         return MOS_STATUS_SUCCESS;
988     }
989 
AddHcpFqmStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const990     MOS_STATUS EncodePreEncPacket::AddHcpFqmStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const
991     {
992         ENCODE_FUNC_CALL();
993         ENCODE_CHK_NULL_RETURN(cmdBuffer);
994 
995         MHW_MI_CHK_NULL(m_hevcIqMatrixParams);
996 
997         auto &params = m_hcpItf->MHW_GETPAR_F(HCP_FQM_STATE)();
998         params       = {};
999 
1000         auto      iqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams;
1001         uint16_t *fqMatrix = (uint16_t *)params.quantizermatrix;
1002 
1003         /* 4x4 */
1004         for (uint8_t i = 0; i < 32; i++)
1005         {
1006             params.quantizermatrix[i] = 0;
1007         }
1008         for (uint8_t intraInter = 0; intraInter <= 1; intraInter++)
1009         {
1010             params.intraInter     = intraInter;
1011             params.sizeid         = 0;
1012             params.colorComponent = 0;
1013 
1014             for (uint8_t i = 0; i < 16; i++)
1015             {
1016                 fqMatrix[i] =
1017                     GetReciprocalScalingValue(iqMatrix->List4x4[3 * intraInter][i]);
1018             }
1019 
1020             m_hcpItf->MHW_ADDCMD_F(HCP_FQM_STATE)(cmdBuffer);
1021         }
1022 
1023         /* 8x8, 16x16 and 32x32 */
1024         for (uint8_t i = 0; i < 32; i++)
1025         {
1026             params.quantizermatrix[i] = 0;
1027         }
1028         for (uint8_t intraInter = 0; intraInter <= 1; intraInter++)
1029         {
1030             params.intraInter     = intraInter;
1031             params.sizeid         = 1;
1032             params.colorComponent = 0;
1033 
1034             for (uint8_t i = 0; i < 64; i++)
1035             {
1036                 fqMatrix[i] =
1037                     GetReciprocalScalingValue(iqMatrix->List8x8[3 * intraInter][i]);
1038             }
1039 
1040             m_hcpItf->MHW_ADDCMD_F(HCP_FQM_STATE)(cmdBuffer);
1041         }
1042 
1043         /* 16x16 DC */
1044         for (uint8_t i = 0; i < 32; i++)
1045         {
1046             params.quantizermatrix[i] = 0;
1047         }
1048         for (uint8_t intraInter = 0; intraInter <= 1; intraInter++)
1049         {
1050             params.intraInter     = intraInter;
1051             params.sizeid         = 2;
1052             params.colorComponent = 0;
1053             params.fqmDcValue1Dc  = GetReciprocalScalingValue(iqMatrix->ListDC16x16[3 * intraInter]);
1054 
1055             for (uint8_t i = 0; i < 64; i++)
1056             {
1057                 fqMatrix[i] =
1058                     GetReciprocalScalingValue(iqMatrix->List16x16[3 * intraInter][i]);
1059             }
1060 
1061             m_hcpItf->MHW_ADDCMD_F(HCP_FQM_STATE)(cmdBuffer);
1062         }
1063 
1064         /* 32x32 DC */
1065         for (uint8_t i = 0; i < 32; i++)
1066         {
1067             params.quantizermatrix[i] = 0;
1068         }
1069         for (uint8_t intraInter = 0; intraInter <= 1; intraInter++)
1070         {
1071             params.intraInter     = intraInter;
1072             params.sizeid         = 3;
1073             params.colorComponent = 0;
1074             params.fqmDcValue1Dc  = GetReciprocalScalingValue(iqMatrix->ListDC32x32[intraInter]);
1075 
1076             for (uint8_t i = 0; i < 64; i++)
1077             {
1078                 fqMatrix[i] =
1079                     GetReciprocalScalingValue(iqMatrix->List32x32[intraInter][i]);
1080             }
1081 
1082             m_hcpItf->MHW_ADDCMD_F(HCP_FQM_STATE)(cmdBuffer);
1083         }
1084 
1085         return MOS_STATUS_SUCCESS;
1086     }
1087 
AddHcpQMStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const1088     MOS_STATUS EncodePreEncPacket::AddHcpQMStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const
1089     {
1090         ENCODE_FUNC_CALL();
1091         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1092 
1093         MHW_MI_CHK_NULL(m_hevcIqMatrixParams);
1094 
1095         auto &params = m_hcpItf->MHW_GETPAR_F(HCP_QM_STATE)();
1096         params       = {};
1097 
1098         auto     iqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams;
1099         uint8_t *qMatrix  = (uint8_t *)params.quantizermatrix;
1100 
1101         for (uint8_t sizeId = 0; sizeId < 4; sizeId++)  // 4x4, 8x8, 16x16, 32x32
1102         {
1103             for (uint8_t predType = 0; predType < 2; predType++)  // Intra, Inter
1104             {
1105                 for (uint8_t color = 0; color < 3; color++)  // Y, Cb, Cr
1106                 {
1107                     if ((sizeId == 3) && (color != 0))
1108                         break;
1109 
1110                     params.sizeid         = sizeId;
1111                     params.predictionType = predType;
1112                     params.colorComponent = color;
1113                     switch (sizeId)
1114                     {
1115                         case 0:
1116                         case 1:
1117                         default:
1118                             params.dcCoefficient = 0;
1119                             break;
1120                         case 2:
1121                             params.dcCoefficient = iqMatrix->ListDC16x16[3 * predType + color];
1122                             break;
1123                         case 3:
1124                             params.dcCoefficient = iqMatrix->ListDC32x32[predType];
1125                             break;
1126                     }
1127 
1128                     if (sizeId == 0)
1129                     {
1130                         for (uint8_t i = 0; i < 4; i++)
1131                         {
1132                             for (uint8_t ii = 0; ii < 4; ii++)
1133                             {
1134                                 qMatrix[4 * i + ii] = iqMatrix->List4x4[3 * predType + color][4 * i + ii];
1135                             }
1136                         }
1137                     }
1138                     else if (sizeId == 1)
1139                     {
1140                         for (uint8_t i = 0; i < 8; i++)
1141                         {
1142                             for (uint8_t ii = 0; ii < 8; ii++)
1143                             {
1144                                 qMatrix[8 * i + ii] = iqMatrix->List8x8[3 * predType + color][8 * i + ii];
1145                             }
1146                         }
1147                     }
1148                     else if (sizeId == 2)
1149                     {
1150                         for (uint8_t i = 0; i < 8; i++)
1151                         {
1152                             for (uint8_t ii = 0; ii < 8; ii++)
1153                             {
1154                                 qMatrix[8 * i + ii] = iqMatrix->List16x16[3 * predType + color][8 * i + ii];
1155                             }
1156                         }
1157                     }
1158                     else  // 32x32
1159                     {
1160                         for (uint8_t i = 0; i < 8; i++)
1161                         {
1162                             for (uint8_t ii = 0; ii < 8; ii++)
1163                             {
1164                                 qMatrix[8 * i + ii] = iqMatrix->List32x32[predType][8 * i + ii];
1165                             }
1166                         }
1167                     }
1168 
1169                     m_hcpItf->MHW_ADDCMD_F(HCP_QM_STATE)(cmdBuffer);
1170                 }
1171             }
1172         }
1173 
1174         return MOS_STATUS_SUCCESS;
1175     }
1176 
AddHcpPakInsertObjectCmds(PMOS_COMMAND_BUFFER cmdBuffer) const1177     MOS_STATUS EncodePreEncPacket::AddHcpPakInsertObjectCmds(PMOS_COMMAND_BUFFER cmdBuffer) const
1178     {
1179         ENCODE_FUNC_CALL();
1180 
1181         ENCODE_CHK_NULL_RETURN(m_osInterface);
1182         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1183 
1184         auto &params = m_hcpItf->MHW_GETPAR_F(HCP_PAK_INSERT_OBJECT)();
1185         params       = {};
1186 
1187         PCODECHAL_NAL_UNIT_PARAMS *ppNalUnitParams = (CODECHAL_NAL_UNIT_PARAMS **)m_nalUnitParams;
1188 
1189         PBSBuffer pBsBuffer = &(m_basicFeature->m_bsBuffer);
1190         uint32_t  bitSize   = 0;
1191         uint32_t  offSet    = 0;
1192 
1193         //insert AU, SPS, PSP headers before first slice header
1194         uint32_t maxBytesInPakInsertObjCmd = ((2 << 11) - 1) * 4;  // 12 bits for Length field in PAK_INSERT_OBJ cmd
1195 
1196         for (uint32_t i = 0; i < m_basicFeature->m_NumNalUnits; i++)
1197         {
1198             uint32_t nalunitPosiSize   = ppNalUnitParams[i]->uiSize;
1199             uint32_t nalunitPosiOffset = ppNalUnitParams[i]->uiOffset;
1200 
1201             while (nalunitPosiSize > 0)
1202             {
1203                 bitSize = MOS_MIN(maxBytesInPakInsertObjCmd * 8, nalunitPosiSize * 8);
1204                 offSet  = nalunitPosiOffset;
1205 
1206                 params = {};
1207 
1208                 params.dwPadding                 = (MOS_ALIGN_CEIL((bitSize + 7) >> 3, sizeof(uint32_t))) / sizeof(uint32_t);
1209                 params.bEmulationByteBitsInsert  = ppNalUnitParams[i]->bInsertEmulationBytes;
1210                 params.uiSkipEmulationCheckCount = ppNalUnitParams[i]->uiSkipEmulationCheckCount;
1211                 params.dataBitsInLastDw          = bitSize % 32;
1212                 if (params.dataBitsInLastDw == 0)
1213                 {
1214                     params.dataBitsInLastDw = 32;
1215                 }
1216 
1217                 if (nalunitPosiSize > maxBytesInPakInsertObjCmd)
1218                 {
1219                     nalunitPosiSize -= maxBytesInPakInsertObjCmd;
1220                     nalunitPosiOffset += maxBytesInPakInsertObjCmd;
1221                 }
1222                 else
1223                 {
1224                     nalunitPosiSize = 0;
1225                 }
1226                 m_hcpItf->MHW_ADDCMD_F(HCP_PAK_INSERT_OBJECT)(cmdBuffer);
1227                 uint32_t byteSize = (bitSize + 7) >> 3;
1228                 if (byteSize)
1229                 {
1230                     MHW_MI_CHK_NULL(pBsBuffer);
1231                     MHW_MI_CHK_NULL(pBsBuffer->pBase);
1232                     uint8_t *data = (uint8_t *)(pBsBuffer->pBase + offSet);
1233                     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, data, byteSize));
1234                 }
1235             }
1236         }
1237 
1238         params = {};
1239         // Insert slice header
1240         params.bLastHeader              = true;
1241         params.bEmulationByteBitsInsert = true;
1242 
1243         // App does the slice header packing, set the skip count passed by the app
1244         PCODEC_ENCODER_SLCDATA slcData = m_basicFeature->m_slcData;
1245 
1246         params.uiSkipEmulationCheckCount = slcData->SkipEmulationByteCount;
1247         bitSize                          = slcData->BitSize;
1248         offSet                           = slcData->SliceOffset;
1249 
1250         // Hevc header needs slcData->BitSize > 0 to caculate params.dwPadding and params.dataBitsInLastDw for cmd  HCP_PAK_INSERT_OBJECT.
1251         // For Av1, slcData params are zeros. Av1 use Hevc preEnc packet, need to set bitSize>0.
1252         // The bitstream header size will have no effect on the mv.
1253         if (bitSize == 0)
1254         {
1255             bitSize = sizeof(uint8_t) * 8;
1256         }
1257 
1258         params.dwPadding        = (MOS_ALIGN_CEIL((bitSize + 7) >> 3, sizeof(uint32_t))) / sizeof(uint32_t);
1259         params.dataBitsInLastDw = bitSize % 32;
1260         if (params.dataBitsInLastDw == 0)
1261         {
1262             params.dataBitsInLastDw = 32;
1263         }
1264         m_hcpItf->MHW_ADDCMD_F(HCP_PAK_INSERT_OBJECT)(cmdBuffer);
1265         uint32_t byteSize = (bitSize + 7) >> 3;
1266         if (byteSize)
1267         {
1268             MHW_MI_CHK_NULL(pBsBuffer);
1269             MHW_MI_CHK_NULL(pBsBuffer->pBase);
1270             uint8_t *data = (uint8_t *)(pBsBuffer->pBase + offSet);
1271             MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, data, byteSize));
1272         }
1273 
1274         return MOS_STATUS_SUCCESS;
1275     }
1276 
AddHcpRefIdxStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const1277     MOS_STATUS EncodePreEncPacket::AddHcpRefIdxStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const
1278     {
1279         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1280         ENCODE_FUNC_CALL();
1281         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1282 
1283         auto &params = m_hcpItf->MHW_GETPAR_F(HCP_REF_IDX_STATE)();
1284         params       = {};
1285 
1286         CODEC_PICTURE currPic                                     = {};
1287         CODEC_PICTURE refPicList[2][CODEC_MAX_NUM_REF_FRAME_HEVC] = {};
1288         void **       hevcRefList                                 = nullptr;
1289         int32_t       pocCurrPic                                  = 0;
1290         int8_t *      pRefIdxMapping                              = nullptr;
1291         int32_t       pocList[CODEC_MAX_NUM_REF_FRAME_HEVC]       = {};
1292 
1293         if (m_basicFeature->m_preEncConfig.SliceType != encodeHevcISlice)
1294         {
1295             currPic                                    = m_basicFeature->m_preEncConfig.CurrReconstructedPic;
1296             params.ucList                              = LIST_0;
1297             params.numRefIdxLRefpiclistnumActiveMinus1 = 0;
1298             eStatus                                    = MOS_SecureMemcpy(&refPicList, sizeof(refPicList), &m_basicFeature->m_preEncConfig.RefPicList, sizeof(m_basicFeature->m_preEncConfig.RefPicList));
1299             if (eStatus != MOS_STATUS_SUCCESS)
1300             {
1301                 ENCODE_ASSERTMESSAGE("Failed to copy memory.");
1302                 return eStatus;
1303             }
1304 
1305             hevcRefList = (void **)m_basicFeature->GetRefList();
1306             pocCurrPic  = m_basicFeature->m_preEncConfig.CurrPicOrderCnt;
1307             for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
1308             {
1309                 pocList[i] = m_basicFeature->m_preEncConfig.RefFramePOCList[i];
1310             }
1311 
1312             pRefIdxMapping = m_basicFeature->GetRefIdxMapping();
1313 
1314             MHW_ASSERT(currPic.FrameIdx != 0x7F);
1315 
1316             for (uint8_t i = 0; i <= params.numRefIdxLRefpiclistnumActiveMinus1; i++)
1317             {
1318                 uint8_t refFrameIDx = refPicList[params.ucList][i].FrameIdx;
1319                 if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC)
1320                 {
1321                     MHW_ASSERT(*(pRefIdxMapping + refFrameIDx) >= 0);
1322 
1323                     params.listEntryLxReferencePictureFrameIdRefaddr07[i] = *(pRefIdxMapping + refFrameIDx);
1324                     int32_t pocDiff                                       = pocCurrPic - pocList[refFrameIDx];
1325                     params.referencePictureTbValue[i]                     = (uint8_t)CodecHal_Clip3(-128, 127, pocDiff);
1326                     CODEC_REF_LIST **refList                              = (CODEC_REF_LIST **)hevcRefList;
1327                     params.longtermreference[i]                           = CodecHal_PictureIsLongTermRef(refList[currPic.FrameIdx]->RefList[refFrameIDx]);
1328                     params.bottomFieldFlag[i]                             = 1;
1329                 }
1330                 else
1331                 {
1332                     params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0;
1333                     params.referencePictureTbValue[i]                     = 0;
1334                     params.longtermreference[i]                           = false;
1335                     params.bottomFieldFlag[i]                             = 0;
1336                 }
1337             }
1338 
1339             for (uint8_t i = (uint8_t)(params.numRefIdxLRefpiclistnumActiveMinus1 + 1); i < 16; i++)
1340             {
1341                 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0;
1342                 params.referencePictureTbValue[i]                     = 0;
1343                 params.longtermreference[i]                           = false;
1344                 params.bottomFieldFlag[i]                             = 0;
1345             }
1346 
1347             m_hcpItf->MHW_ADDCMD_F(HCP_REF_IDX_STATE)(cmdBuffer);
1348 
1349             params = {};
1350 
1351             if (m_basicFeature->m_preEncConfig.SliceType == encodeHevcBSlice)
1352             {
1353                 AddHcpBSliceRefIdxStateCmds(cmdBuffer);
1354             }
1355         }
1356 
1357         return MOS_STATUS_SUCCESS;
1358     }
1359 
AddHcpBSliceRefIdxStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const1360     MOS_STATUS EncodePreEncPacket::AddHcpBSliceRefIdxStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const
1361     {
1362         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1363         ENCODE_FUNC_CALL();
1364         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1365 
1366         auto &params = m_hcpItf->MHW_GETPAR_F(HCP_REF_IDX_STATE)();
1367         params       = {};
1368 
1369         CODEC_PICTURE currPic                                     = {};
1370         CODEC_PICTURE refPicList[2][CODEC_MAX_NUM_REF_FRAME_HEVC] = {};
1371         void **       hevcRefList                                 = nullptr;
1372         int32_t       pocCurrPic                                  = 0;
1373         int8_t *      pRefIdxMapping                              = nullptr;
1374         int32_t       pocList[CODEC_MAX_NUM_REF_FRAME_HEVC]       = {};
1375 
1376         currPic = m_basicFeature->m_preEncConfig.CurrReconstructedPic;
1377         eStatus = MOS_SecureMemcpy(&refPicList, sizeof(refPicList), &m_basicFeature->m_preEncConfig.RefPicList, sizeof(m_basicFeature->m_preEncConfig.RefPicList));
1378         if (eStatus != MOS_STATUS_SUCCESS)
1379         {
1380             ENCODE_ASSERTMESSAGE("Failed to copy memory.");
1381             return eStatus;
1382         }
1383         hevcRefList = (void **)m_basicFeature->GetRefList();
1384         pocCurrPic  = m_basicFeature->m_preEncConfig.CurrPicOrderCnt;
1385         for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
1386         {
1387             pocList[i] = m_basicFeature->m_preEncConfig.RefFramePOCList[i];
1388         }
1389 
1390         pRefIdxMapping = m_basicFeature->GetRefIdxMapping();
1391 
1392         MHW_ASSERT(currPic.FrameIdx != 0x7F);
1393 
1394         params.ucList                              = LIST_1;
1395         params.numRefIdxLRefpiclistnumActiveMinus1 = 0;
1396         for (uint8_t i = 0; i <= params.numRefIdxLRefpiclistnumActiveMinus1; i++)
1397         {
1398             uint8_t refFrameIDx = m_basicFeature->m_preEncConfig.isPToB ? refPicList[0][i].FrameIdx : refPicList[1][i].FrameIdx;
1399             if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC)
1400             {
1401                 MHW_ASSERT(*(pRefIdxMapping + refFrameIDx) >= 0);
1402 
1403                 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = *(pRefIdxMapping + refFrameIDx);
1404                 int32_t pocDiff                                       = pocCurrPic - pocList[refFrameIDx];
1405                 params.referencePictureTbValue[i]                     = (uint8_t)CodecHal_Clip3(-128, 127, pocDiff);
1406                 CODEC_REF_LIST **refList                              = (CODEC_REF_LIST **)hevcRefList;
1407                 params.longtermreference[i]                           = CodecHal_PictureIsLongTermRef(refList[currPic.FrameIdx]->RefList[refFrameIDx]);
1408                 params.bottomFieldFlag[i]                             = 1;
1409             }
1410             else
1411             {
1412                 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0;
1413                 params.referencePictureTbValue[i]                     = 0;
1414                 params.longtermreference[i]                           = false;
1415                 params.bottomFieldFlag[i]                             = 0;
1416             }
1417         }
1418 
1419         for (uint8_t i = (uint8_t)(params.numRefIdxLRefpiclistnumActiveMinus1 + 1); i < 16; i++)
1420         {
1421             params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0;
1422             params.referencePictureTbValue[i]                     = 0;
1423             params.longtermreference[i]                           = false;
1424             params.bottomFieldFlag[i]                             = 0;
1425         }
1426         m_hcpItf->MHW_ADDCMD_F(HCP_REF_IDX_STATE)(cmdBuffer);
1427         return eStatus;
1428     }
1429 }  // namespace encode
1430