xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_hcp_generic.h (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2014-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     mhw_vdbox_hcp_generic.h
24 //! \brief    MHW interface for constructing HCP commands for the Vdbox engine
25 //! \details  Impelements shared Vdbox HCP command construction functions across all platforms as templates
26 //!
27 
28 #ifndef _MHW_VDBOX_HCP_GENERIC_H_
29 #define _MHW_VDBOX_HCP_GENERIC_H_
30 
31 #include "mhw_vdbox_hcp_interface.h"
32 #include "mhw_cp_interface.h"
33 
34 //!  MHW Vdbox Hcp generic interface
35 /*!
36 This class defines the shared Hcp command construction functions across all platforms as templates
37 */
38 template <class THcpCmds>
39 class MhwVdboxHcpInterfaceGeneric : public MhwVdboxHcpInterface
40 {
41 protected:
42     static const uint32_t      m_vp9ScalingFactor = (1 << 14);
43     static const uint32_t      m_rawUVPlaneAlignment = 4; //! starting Gen9 the alignment is relaxed to 4x instead of 16x
44     static const uint32_t      m_reconUVPlaneAlignment = 8;
45     static const uint32_t      m_uvPlaneAlignmentLegacy = 8; //! starting Gen9 the alignment is relaxed to 4x instead of 16x
46 
47     //!
48     //! \brief    Constructor
49     //!
MhwVdboxHcpInterfaceGeneric(PMOS_INTERFACE osInterface,MhwMiInterface * miInterface,MhwCpInterface * cpInterface,bool decodeInUse)50     MhwVdboxHcpInterfaceGeneric(
51         PMOS_INTERFACE osInterface,
52         MhwMiInterface *miInterface,
53         MhwCpInterface *cpInterface,
54         bool decodeInUse) :
55         MhwVdboxHcpInterface(osInterface, miInterface, cpInterface, decodeInUse)
56     {
57         MHW_FUNCTION_ENTER;
58     }
59 
60     //!
61     //! \brief   Destructor
62     //!
~MhwVdboxHcpInterfaceGeneric()63     virtual ~MhwVdboxHcpInterfaceGeneric() {}
64 
AddHcpDecodeSurfaceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_SURFACE_PARAMS params)65     MOS_STATUS AddHcpDecodeSurfaceStateCmd(
66         PMOS_COMMAND_BUFFER              cmdBuffer,
67         PMHW_VDBOX_SURFACE_PARAMS        params)
68     {
69         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
70 
71         MHW_FUNCTION_ENTER;
72 
73         MHW_MI_CHK_NULL(m_osInterface);
74         MHW_MI_CHK_NULL(params);
75         MHW_ASSERT(params->Mode != CODECHAL_UNSUPPORTED_MODE);
76 
77         MHW_MI_CHK_NULL(params->psSurface);
78 
79         typename THcpCmds::HCP_SURFACE_STATE_CMD cmd;
80         uint32_t uvPlaneAlignment = m_uvPlaneAlignmentLegacy;
81 
82         cmd.DW1.SurfaceId = params->ucSurfaceStateId;
83         cmd.DW1.SurfacePitchMinus1 = params->psSurface->dwPitch - 1;
84 
85         if (params->ucSurfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
86         {
87             uvPlaneAlignment = params->dwUVPlaneAlignment ? params->dwUVPlaneAlignment : m_rawUVPlaneAlignment;
88         }
89         else
90         {
91             uvPlaneAlignment = params->dwUVPlaneAlignment ? params->dwUVPlaneAlignment : m_reconUVPlaneAlignment;
92         }
93 
94         cmd.DW2.YOffsetForUCbInPixel =
95             MOS_ALIGN_CEIL(params->psSurface->UPlaneOffset.iYOffset, uvPlaneAlignment);
96 
97         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
98 
99         return eStatus;
100     }
101 
AddHcpEncodeSurfaceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_SURFACE_PARAMS params)102     MOS_STATUS AddHcpEncodeSurfaceStateCmd(
103         PMOS_COMMAND_BUFFER              cmdBuffer,
104         PMHW_VDBOX_SURFACE_PARAMS        params)
105     {
106         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
107 
108         MHW_FUNCTION_ENTER;
109 
110         MHW_MI_CHK_NULL(m_osInterface);
111         MHW_MI_CHK_NULL(params);
112         MHW_ASSERT(params->Mode != CODECHAL_UNSUPPORTED_MODE);
113 
114         MHW_MI_CHK_NULL(params->psSurface);
115 
116         typename THcpCmds::HCP_SURFACE_STATE_CMD cmd;
117 
118         cmd.DW1.SurfaceId = params->ucSurfaceStateId;
119         cmd.DW1.SurfacePitchMinus1 = params->psSurface->dwPitch - 1;
120 
121         /* Handling of reconstructed surface is different for Y410 & AYUV formats */
122         if ((params->ucSurfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) &&
123             (params->psSurface->Format == Format_Y410))
124             cmd.DW1.SurfacePitchMinus1 = params->psSurface->dwPitch / 2 - 1;
125 
126         if ((params->ucSurfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) &&
127             (params->psSurface->Format == Format_AYUV))
128             cmd.DW1.SurfacePitchMinus1 = params->psSurface->dwPitch / 4 - 1;
129 
130         cmd.DW2.YOffsetForUCbInPixel = params->psSurface->UPlaneOffset.iYOffset;
131 
132         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
133 
134         return eStatus;
135     }
136 
AddHcpIndObjBaseAddrCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS params)137     MOS_STATUS AddHcpIndObjBaseAddrCmd(
138         PMOS_COMMAND_BUFFER                  cmdBuffer,
139         PMHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS  params)
140     {
141         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
142 
143         MHW_FUNCTION_ENTER;
144 
145         MHW_MI_CHK_NULL(m_osInterface);
146         MHW_MI_CHK_NULL(params);
147 
148         MHW_RESOURCE_PARAMS resourceParams;
149         typename THcpCmds::HCP_IND_OBJ_BASE_ADDR_STATE_CMD cmd;
150 
151         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
152         resourceParams.dwLsbNum = MHW_VDBOX_HCP_UPPER_BOUND_STATE_SHIFT;
153         resourceParams.HwCommandType = MOS_MFX_INDIRECT_OBJ_BASE_ADDR;
154 
155         // mode specific settings
156         if (CodecHalIsDecodeModeVLD(params->Mode))
157         {
158             MHW_MI_CHK_NULL(params->presDataBuffer);
159 
160             cmd.HcpIndirectBitstreamObjectMemoryAddressAttributes.DW0.Value |=
161                 m_cacheabilitySettings[MOS_CODEC_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE].Value;
162 
163             resourceParams.presResource = params->presDataBuffer;
164             resourceParams.dwOffset = params->dwDataOffset;
165             resourceParams.pdwCmd = cmd.HcpIndirectBitstreamObjectBaseAddress.DW0_1.Value;
166             resourceParams.dwLocationInCmd = 1;
167             resourceParams.dwSize = params->dwDataSize;
168             resourceParams.bIsWritable = false;
169 
170             // upper bound of the allocated resource will be set at 3 DW apart from address location
171             resourceParams.dwUpperBoundLocationOffsetFromCmd = 3;
172 
173             MHW_MI_CHK_STATUS(pfnAddResourceToCmd(
174                 m_osInterface,
175                 cmdBuffer,
176                 &resourceParams));
177         }
178 
179         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
180 
181         return eStatus;
182     }
183 
AddHcpQmStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_QM_PARAMS params)184     MOS_STATUS AddHcpQmStateCmd(
185         PMOS_COMMAND_BUFFER              cmdBuffer,
186         PMHW_VDBOX_QM_PARAMS             params)
187     {
188         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
189 
190         MHW_FUNCTION_ENTER;
191 
192         MHW_MI_CHK_NULL(m_osInterface);
193         MHW_MI_CHK_NULL(cmdBuffer);
194         MHW_MI_CHK_NULL(params);
195 
196         if (params->Standard == CODECHAL_HEVC)
197         {
198             typename THcpCmds::HCP_QM_STATE_CMD cmd;
199             uint8_t* qMatrix = nullptr;
200 
201             MHW_MI_CHK_NULL(params->pHevcIqMatrix);
202 
203             qMatrix = (uint8_t*)cmd.Quantizermatrix;
204 
205             for (uint8_t sizeId = 0; sizeId < 4; sizeId++)            // 4x4, 8x8, 16x16, 32x32
206             {
207                 for (uint8_t predType = 0; predType < 2; predType++)  // Intra, Inter
208                 {
209                     for (uint8_t color = 0; color < 3; color++)       // Y, Cb, Cr
210                     {
211                         if ((sizeId == 3) && (color != 0))
212                             break;
213 
214                         cmd.DW1.Sizeid = sizeId;
215                         cmd.DW1.PredictionType = predType;
216                         cmd.DW1.ColorComponent = color;
217                         switch (sizeId)
218                         {
219                         case cmd.SIZEID_4X4:
220                         case cmd.SIZEID_8X8:
221                         default:
222                             cmd.DW1.DcCoefficient = 0;
223                             break;
224                         case cmd.SIZEID_16X16:
225                             cmd.DW1.DcCoefficient = params->pHevcIqMatrix->ListDC16x16[3 * predType + color];
226                             break;
227                         case cmd.SIZEID_32X32:
228                             cmd.DW1.DcCoefficient = params->pHevcIqMatrix->ListDC32x32[predType];
229                             break;
230                         }
231 
232                         if (sizeId == cmd.SIZEID_4X4)
233                         {
234                             for (uint8_t i = 0; i < 4; i++)
235                             {
236                                 for (uint8_t ii = 0; ii < 4; ii++)
237                                 {
238                                     qMatrix[4 * i + ii] = params->pHevcIqMatrix->List4x4[3 * predType + color][4 * i + ii];
239                                 }
240                             }
241                         }
242                         else if (sizeId == cmd.SIZEID_8X8)
243                         {
244                             for (uint8_t i = 0; i < 8; i++)
245                             {
246                                 for (uint8_t ii = 0; ii < 8; ii++)
247                                 {
248                                     qMatrix[8 * i + ii] = params->pHevcIqMatrix->List8x8[3 * predType + color][8 * i + ii];
249                                 }
250                             }
251                         }
252                         else if (sizeId == cmd.SIZEID_16X16)
253                         {
254                             for (uint8_t i = 0; i < 8; i++)
255                             {
256                                 for (uint8_t ii = 0; ii < 8; ii++)
257                                 {
258                                     qMatrix[8 * i + ii] = params->pHevcIqMatrix->List16x16[3 * predType + color][8 * i + ii];
259                                 }
260                             }
261                         }
262                         else // 32x32
263                         {
264                             for (uint8_t i = 0; i < 8; i++)
265                             {
266                                 for (uint8_t ii = 0; ii < 8; ii++)
267                                 {
268                                     qMatrix[8 * i + ii] = params->pHevcIqMatrix->List32x32[predType][8 * i + ii];
269                                 }
270                             }
271                         }
272 
273                         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
274                     }
275                 }
276             }
277         }
278         else
279         {
280             eStatus = MOS_STATUS_INVALID_PARAMETER;
281         }
282 
283         return eStatus;
284     }
285 
AddHcpDecodePicStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_PIC_STATE params)286     MOS_STATUS AddHcpDecodePicStateCmd(
287         PMOS_COMMAND_BUFFER              cmdBuffer,
288         PMHW_VDBOX_HEVC_PIC_STATE        params)
289     {
290         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
291 
292         MHW_FUNCTION_ENTER;
293 
294         MHW_MI_CHK_NULL(m_osInterface);
295         MHW_MI_CHK_NULL(params);
296         MHW_MI_CHK_NULL(params->pHevcPicParams);
297 
298         typename THcpCmds::HCP_PIC_STATE_CMD cmd;
299 
300         auto hevcPicParams = params->pHevcPicParams;
301 
302         cmd.DW1.Framewidthinmincbminus1  = hevcPicParams->PicWidthInMinCbsY - 1;
303         cmd.DW1.Frameheightinmincbminus1 = hevcPicParams->PicHeightInMinCbsY - 1;
304 
305         cmd.DW2.Mincusize = (hevcPicParams->log2_min_luma_coding_block_size_minus3) & 0x3;
306         cmd.DW2.CtbsizeLcusize = (hevcPicParams->log2_diff_max_min_luma_coding_block_size
307             + hevcPicParams->log2_min_luma_coding_block_size_minus3) & 0x3;
308         cmd.DW2.Maxtusize = (hevcPicParams->log2_diff_max_min_transform_block_size
309             + hevcPicParams->log2_min_transform_block_size_minus2) & 0x3;
310         cmd.DW2.Mintusize = (hevcPicParams->log2_min_transform_block_size_minus2) & 0x3;
311         cmd.DW2.Minpcmsize = (hevcPicParams->log2_min_pcm_luma_coding_block_size_minus3) & 0x3;
312         cmd.DW2.Maxpcmsize = (hevcPicParams->log2_diff_max_min_pcm_luma_coding_block_size
313             + hevcPicParams->log2_min_pcm_luma_coding_block_size_minus3) & 0x3;
314 
315         // As per HW requirement, CurPicIsI and ColPicIsI should be set to either both correct or both zero
316         // Since driver doesn't know Collocated_Ref_Idx for SF, and cannot get accurate CurPicIsI for both LF/SF
317         // Have to make ColPicIsI = CurPicIsI = 0 for both LF/SF
318         cmd.DW3.Colpicisi = 0;
319         cmd.DW3.Curpicisi = 0;
320 
321         cmd.DW4.SampleAdaptiveOffsetEnabledFlag         = hevcPicParams->sample_adaptive_offset_enabled_flag;
322         cmd.DW4.PcmEnabledFlag                          = hevcPicParams->pcm_enabled_flag;
323         cmd.DW4.CuQpDeltaEnabledFlag                    = hevcPicParams->cu_qp_delta_enabled_flag;
324         cmd.DW4.DiffCuQpDeltaDepthOrNamedAsMaxDqpDepth  = hevcPicParams->diff_cu_qp_delta_depth;
325         cmd.DW4.PcmLoopFilterDisableFlag                = hevcPicParams->pcm_loop_filter_disabled_flag;
326         cmd.DW4.ConstrainedIntraPredFlag                = hevcPicParams->constrained_intra_pred_flag;
327         cmd.DW4.Log2ParallelMergeLevelMinus2            = hevcPicParams->log2_parallel_merge_level_minus2;
328         cmd.DW4.SignDataHidingFlag                      = hevcPicParams->sign_data_hiding_enabled_flag;
329         cmd.DW4.LoopFilterAcrossTilesEnabledFlag        = hevcPicParams->loop_filter_across_tiles_enabled_flag;
330         cmd.DW4.EntropyCodingSyncEnabledFlag            = hevcPicParams->entropy_coding_sync_enabled_flag;
331         cmd.DW4.TilesEnabledFlag                        = hevcPicParams->tiles_enabled_flag;
332         cmd.DW4.WeightedPredFlag                        = hevcPicParams->weighted_pred_flag;
333         cmd.DW4.WeightedBipredFlag                      = hevcPicParams->weighted_bipred_flag;
334         cmd.DW4.Fieldpic                                = (hevcPicParams->RefFieldPicFlag >> 15) & 0x01;
335         cmd.DW4.Bottomfield                             = ((hevcPicParams->RefBottomFieldFlag >> 15) & 0x01) ? 0 : 1;
336         cmd.DW4.TransformSkipEnabledFlag                = hevcPicParams->transform_skip_enabled_flag;
337         cmd.DW4.AmpEnabledFlag                          = hevcPicParams->amp_enabled_flag;
338         cmd.DW4.TransquantBypassEnableFlag              = hevcPicParams->transquant_bypass_enabled_flag;
339         cmd.DW4.StrongIntraSmoothingEnableFlag          = hevcPicParams->strong_intra_smoothing_enabled_flag;
340 
341         cmd.DW5.PicCbQpOffset = hevcPicParams->pps_cb_qp_offset & 0x1f;
342         cmd.DW5.PicCrQpOffset = hevcPicParams->pps_cr_qp_offset & 0x1f;
343         cmd.DW5.MaxTransformHierarchyDepthIntraOrNamedAsTuMaxDepthIntra = hevcPicParams->max_transform_hierarchy_depth_intra & 0x7;
344         cmd.DW5.MaxTransformHierarchyDepthInterOrNamedAsTuMaxDepthInter = hevcPicParams->max_transform_hierarchy_depth_inter & 0x7;
345         cmd.DW5.PcmSampleBitDepthChromaMinus1 = hevcPicParams->pcm_sample_bit_depth_chroma_minus1;
346         cmd.DW5.PcmSampleBitDepthLumaMinus1   = hevcPicParams->pcm_sample_bit_depth_luma_minus1;
347 
348         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
349 
350         return eStatus;
351     }
352 
AddHcpBsdObjectCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HCP_BSD_PARAMS params)353     MOS_STATUS AddHcpBsdObjectCmd(
354         PMOS_COMMAND_BUFFER cmdBuffer,
355         PMHW_VDBOX_HCP_BSD_PARAMS params)
356     {
357         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
358 
359         MHW_FUNCTION_ENTER;
360 
361         MHW_MI_CHK_NULL(m_osInterface);
362         typename THcpCmds::HCP_BSD_OBJECT_CMD   cmd;
363 
364         cmd.DW1.IndirectBsdDataLength = params->dwBsdDataLength;
365         cmd.DW2.IndirectDataStartAddress = params->dwBsdDataStartOffset;
366 
367         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd)));
368 
369         return eStatus;
370     }
371 
AddHcpTileStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_TILE_STATE params)372     MOS_STATUS AddHcpTileStateCmd(
373         PMOS_COMMAND_BUFFER              cmdBuffer,
374         PMHW_VDBOX_HEVC_TILE_STATE       params)
375     {
376         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
377 
378         MHW_FUNCTION_ENTER;
379 
380         typename THcpCmds::HCP_TILE_STATE_CMD cmd;
381 
382         MHW_MI_CHK_NULL(m_osInterface);
383         MHW_MI_CHK_NULL(params);
384         MHW_MI_CHK_NULL(params->pTileColWidth);
385         MHW_MI_CHK_NULL(params->pTileRowHeight);
386 
387         auto hevcPicParams = params->pHevcPicParams;
388         uint32_t colCumulativeValue = 0;
389         uint32_t rowCumulativeValue = 0;
390 
391         MHW_ASSERT(hevcPicParams->num_tile_rows_minus1 < HEVC_NUM_MAX_TILE_ROW);
392         MHW_ASSERT(hevcPicParams->num_tile_columns_minus1 < HEVC_NUM_MAX_TILE_COLUMN);
393 
394         cmd.DW1.Numtilecolumnsminus1 = hevcPicParams->num_tile_columns_minus1;
395         cmd.DW1.Numtilerowsminus1 = hevcPicParams->num_tile_rows_minus1;
396 
397         for (uint8_t i = 0; i < 5; i++)
398         {
399             cmd.CtbColumnPositionOfTileColumn[i].DW0.Ctbpos0I = colCumulativeValue;
400             if ((4 * i) == hevcPicParams->num_tile_columns_minus1)
401             {
402                 break;
403             }
404 
405             colCumulativeValue += params->pTileColWidth[4 * i];
406             cmd.CtbColumnPositionOfTileColumn[i].DW0.Ctbpos1I = colCumulativeValue;
407             if ((4 * i + 1) == hevcPicParams->num_tile_columns_minus1)
408             {
409                 break;
410             }
411 
412             colCumulativeValue += params->pTileColWidth[4 * i + 1];
413             cmd.CtbColumnPositionOfTileColumn[i].DW0.Ctbpos2I = colCumulativeValue;
414             if ((4 * i + 2) == hevcPicParams->num_tile_columns_minus1)
415             {
416                 break;
417             }
418 
419             colCumulativeValue += params->pTileColWidth[4 * i + 2];
420             cmd.CtbColumnPositionOfTileColumn[i].DW0.Ctbpos3I = colCumulativeValue;
421             if ((4 * i + 3) == hevcPicParams->num_tile_columns_minus1)
422             {
423                 break;
424             }
425 
426             colCumulativeValue += params->pTileColWidth[4 * i + 3];
427         }
428 
429         for (uint8_t i = 0; i < 5; i++)
430         {
431             cmd.CtbRowPositionOfTileRow[i].DW0.Ctbpos0I = rowCumulativeValue;
432             if ((4 * i) == hevcPicParams->num_tile_rows_minus1)
433             {
434                 break;
435             }
436 
437             rowCumulativeValue += params->pTileRowHeight[4 * i];
438             cmd.CtbRowPositionOfTileRow[i].DW0.Ctbpos1I = rowCumulativeValue;
439             if ((4 * i + 1) == hevcPicParams->num_tile_rows_minus1)
440             {
441                 break;
442             }
443 
444             rowCumulativeValue += params->pTileRowHeight[4 * i + 1];
445             cmd.CtbRowPositionOfTileRow[i].DW0.Ctbpos2I = rowCumulativeValue;
446             if ((4 * i + 2) == hevcPicParams->num_tile_rows_minus1)
447             {
448                 break;
449             }
450 
451             rowCumulativeValue += params->pTileRowHeight[4 * i + 2];
452             cmd.CtbRowPositionOfTileRow[i].DW0.Ctbpos3I = rowCumulativeValue;
453             if ((4 * i + 3) == hevcPicParams->num_tile_rows_minus1)
454             {
455                 break;
456             }
457 
458             rowCumulativeValue += params->pTileRowHeight[4 * i + 3];
459         }
460 
461         if (hevcPicParams->num_tile_rows_minus1 == 20)
462         {
463             cmd.CtbRowPositionOfTileRow[5].DW0.Ctbpos0I = rowCumulativeValue;
464         }
465 
466         if (hevcPicParams->num_tile_rows_minus1 == 21)
467         {
468             cmd.CtbRowPositionOfTileRow[5].DW0.Ctbpos0I = rowCumulativeValue;
469             rowCumulativeValue += params->pTileRowHeight[20];
470             cmd.CtbRowPositionOfTileRow[5].DW0.Ctbpos1I = rowCumulativeValue;
471         }
472 
473         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
474 
475         return eStatus;
476     }
477 
AddHcpRefIdxStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_HEVC_REF_IDX_PARAMS params)478     MOS_STATUS AddHcpRefIdxStateCmd(
479         PMOS_COMMAND_BUFFER             cmdBuffer,
480         PMHW_BATCH_BUFFER               batchBuffer,
481         PMHW_VDBOX_HEVC_REF_IDX_PARAMS  params)
482     {
483         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
484 
485         MHW_FUNCTION_ENTER;
486 
487         MHW_MI_CHK_NULL(params);
488 
489         typename THcpCmds::HCP_REF_IDX_STATE_CMD cmd;
490 
491         // Need to add an empty HCP_REF_IDX_STATE_CMD for dummy reference on I-Frame
492         // ucNumRefForList could be 0 for encode
493         if (!params->bDummyReference)
494         {
495             MHW_ASSERT(params->CurrPic.FrameIdx != 0x7F);
496 
497             cmd.DW1.Refpiclistnum = params->ucList;
498             cmd.DW1.NumRefIdxLRefpiclistnumActiveMinus1 = params->ucNumRefForList - 1;
499 
500             for (uint8_t i = 0; i < params->ucNumRefForList; i++)
501             {
502                 uint8_t refFrameIDx = params->RefPicList[params->ucList][i].FrameIdx;
503                 if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC)
504                 {
505                     MHW_ASSERT(*(params->pRefIdxMapping + refFrameIDx) >= 0);
506 
507                     cmd.Entries[i].DW0.ListEntryLxReferencePictureFrameIdRefaddr07 = *(params->pRefIdxMapping + refFrameIDx);
508                     int32_t pocDiff = params->poc_curr_pic - params->poc_list[refFrameIDx];
509                     cmd.Entries[i].DW0.ReferencePictureTbValue = CodecHal_Clip3(-128, 127, pocDiff);
510                     CODEC_REF_LIST** refList = (CODEC_REF_LIST**)params->hevcRefList;
511                     cmd.Entries[i].DW0.Longtermreference = CodecHal_PictureIsLongTermRef(refList[params->CurrPic.FrameIdx]->RefList[refFrameIDx]);
512                     cmd.Entries[i].DW0.FieldPicFlag = (params->RefFieldPicFlag >> refFrameIDx) & 0x01;
513                     cmd.Entries[i].DW0.BottomFieldFlag = ((params->RefBottomFieldFlag >> refFrameIDx) & 0x01) ? 0 : 1;
514                 }
515                 else
516                 {
517                     cmd.Entries[i].DW0.ListEntryLxReferencePictureFrameIdRefaddr07 = 0;
518                     cmd.Entries[i].DW0.ReferencePictureTbValue = 0;
519                     cmd.Entries[i].DW0.Longtermreference = false;
520                     cmd.Entries[i].DW0.FieldPicFlag = 0;
521                     cmd.Entries[i].DW0.BottomFieldFlag = 0;
522                 }
523             }
524 
525             for (uint8_t i = (uint8_t)params->ucNumRefForList; i < 16; i++)
526             {
527                 cmd.Entries[i].DW0.Value = 0x00;
528             }
529         }
530 
531         if (cmdBuffer == nullptr && batchBuffer == nullptr)
532         {
533             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
534             return MOS_STATUS_INVALID_PARAMETER;
535         }
536 
537         MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize));
538 
539         return eStatus;
540     }
541 
AddHcpWeightOffsetStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS params)542     MOS_STATUS AddHcpWeightOffsetStateCmd(
543         PMOS_COMMAND_BUFFER                  cmdBuffer,
544         PMHW_BATCH_BUFFER                    batchBuffer,
545         PMHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS  params)
546     {
547         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
548 
549         MHW_FUNCTION_ENTER;
550 
551         MHW_MI_CHK_NULL(params);
552 
553         typename THcpCmds::HCP_WEIGHTOFFSET_STATE_CMD       cmd;
554         uint8_t i = 0;
555 
556         cmd.DW1.Refpiclistnum = i = params->ucList;
557 
558         // Luma
559         for (uint8_t refIdx = 0; refIdx < CODEC_MAX_NUM_REF_FRAME_HEVC; refIdx++)
560         {
561             cmd.Lumaoffsets[refIdx].DW0.DeltaLumaWeightLxI = params->LumaWeights[i][refIdx];
562             cmd.Lumaoffsets[refIdx].DW0.LumaOffsetLxI = params->LumaOffsets[i][refIdx];
563         }
564 
565         // Chroma
566         for (uint8_t refIdx = 0; refIdx < CODEC_MAX_NUM_REF_FRAME_HEVC; refIdx++)
567         {
568             cmd.Chromaoffsets[refIdx].DW0.DeltaChromaWeightLxI0 = params->ChromaWeights[i][refIdx][0];
569             cmd.Chromaoffsets[refIdx].DW0.ChromaoffsetlxI0 = params->ChromaOffsets[i][refIdx][0];
570             cmd.Chromaoffsets[refIdx].DW0.DeltaChromaWeightLxI1 = params->ChromaWeights[i][refIdx][1];
571             cmd.Chromaoffsets[refIdx].DW0.ChromaoffsetlxI1 = params->ChromaOffsets[i][refIdx][1];
572         }
573 
574         //cmd.DW2[15] and cmd.DW18[15] not be used
575 
576         if (cmdBuffer == nullptr && batchBuffer == nullptr)
577         {
578             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
579             return MOS_STATUS_INVALID_PARAMETER;
580         }
581 
582         MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize));
583 
584         return eStatus;
585     }
586 
AddHcpDecodeSliceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState)587     MOS_STATUS AddHcpDecodeSliceStateCmd(
588         PMOS_COMMAND_BUFFER              cmdBuffer,
589         PMHW_VDBOX_HEVC_SLICE_STATE      hevcSliceState)
590     {
591         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
592 
593         MHW_FUNCTION_ENTER;
594 
595         MHW_MI_CHK_NULL(m_osInterface);
596         MHW_MI_CHK_NULL(hevcSliceState);
597 
598         typename THcpCmds::HCP_SLICE_STATE_CMD cmd;
599 
600         auto hevcSliceParams = hevcSliceState->pHevcSliceParams;
601         auto hevcPicParams = hevcSliceState->pHevcPicParams;
602 
603         uint32_t ctbSize = 1 << (hevcPicParams->log2_diff_max_min_luma_coding_block_size +
604             hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
605         uint32_t widthInPix = (1 << (hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) *
606             (hevcPicParams->PicWidthInMinCbsY);
607         uint32_t widthInCtb = MOS_ROUNDUP_DIVIDE(widthInPix, ctbSize);
608 
609         // It is a hardware requirement that the first HCP_SLICE_STATE of the workload starts at LCU X,Y = 0,0.
610         // If first slice doesn't starts from (0,0), that means this is error bitstream.
611         if (hevcSliceState->dwSliceIndex == 0)
612         {
613             cmd.DW1.SlicestartctbxOrSliceStartLcuXEncoder = 0;
614             cmd.DW1.SlicestartctbyOrSliceStartLcuYEncoder = 0;
615         }
616         else
617         {
618             cmd.DW1.SlicestartctbxOrSliceStartLcuXEncoder = hevcSliceParams->slice_segment_address % widthInCtb;
619             cmd.DW1.SlicestartctbyOrSliceStartLcuYEncoder = hevcSliceParams->slice_segment_address / widthInCtb;
620         }
621 
622         if (hevcSliceState->bLastSlice)
623         {
624             cmd.DW2.NextslicestartctbxOrNextSliceStartLcuXEncoder = 0;
625             cmd.DW2.NextslicestartctbyOrNextSliceStartLcuYEncoder = 0;
626         }
627         else
628         {
629             cmd.DW2.NextslicestartctbxOrNextSliceStartLcuXEncoder = (hevcSliceParams + 1)->slice_segment_address % widthInCtb;
630             cmd.DW2.NextslicestartctbyOrNextSliceStartLcuYEncoder = (hevcSliceParams + 1)->slice_segment_address / widthInCtb;
631         }
632 
633         cmd.DW3.SliceType = hevcSliceParams->LongSliceFlags.fields.slice_type;
634         cmd.DW3.Lastsliceofpic = hevcSliceState->bLastSlice;
635         cmd.DW3.DependentSliceFlag = hevcSliceParams->LongSliceFlags.fields.dependent_slice_segment_flag;
636         cmd.DW3.SliceTemporalMvpEnableFlag = hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag;
637         cmd.DW3.SliceCbQpOffset = hevcSliceParams->slice_cb_qp_offset;
638         cmd.DW3.SliceCrQpOffset = hevcSliceParams->slice_cr_qp_offset;
639 
640         cmd.DW4.SliceHeaderDisableDeblockingFilterFlag = hevcSliceParams->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag;
641         cmd.DW4.SliceTcOffsetDiv2OrFinalTcOffsetDiv2Encoder = hevcSliceParams->slice_tc_offset_div2;
642         cmd.DW4.SliceBetaOffsetDiv2OrFinalBetaOffsetDiv2Encoder = hevcSliceParams->slice_beta_offset_div2;
643         cmd.DW4.SliceLoopFilterAcrossSlicesEnabledFlag = hevcSliceParams->LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag;
644         cmd.DW4.SliceSaoChromaFlag = hevcSliceParams->LongSliceFlags.fields.slice_sao_chroma_flag;
645         cmd.DW4.SliceSaoLumaFlag = hevcSliceParams->LongSliceFlags.fields.slice_sao_luma_flag;
646         cmd.DW4.MvdL1ZeroFlag = hevcSliceParams->LongSliceFlags.fields.mvd_l1_zero_flag;
647 
648         uint8_t isLowDelay = 1;
649 
650         if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE)
651         {
652             isLowDelay = 0;
653         }
654         else
655         {
656             for (uint8_t i = 0; i < hevcSliceParams->num_ref_idx_l0_active_minus1 + 1; i++)
657             {
658                 uint8_t  refFrameID = hevcSliceParams->RefPicList[0][i].FrameIdx;
659                 if (hevcPicParams->PicOrderCntValList[refFrameID] > hevcPicParams->CurrPicOrderCntVal)
660                 {
661                     isLowDelay = 0;
662                     break;
663                 }
664             }
665 
666             if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_B_SLICE)
667             {
668                 for (uint8_t i = 0; i < hevcSliceParams->num_ref_idx_l1_active_minus1 + 1; i++)
669                 {
670                     uint8_t  refFrameID = hevcSliceParams->RefPicList[1][i].FrameIdx;
671                     if (hevcPicParams->PicOrderCntValList[refFrameID] > hevcPicParams->CurrPicOrderCntVal)
672                     {
673                         isLowDelay = 0;
674                         break;
675                     }
676                 }
677             }
678         }
679 
680         cmd.DW4.Islowdelay = isLowDelay & 0x1;
681 
682         cmd.DW4.CollocatedFromL0Flag = hevcSliceParams->LongSliceFlags.fields.collocated_from_l0_flag;
683         cmd.DW4.Chromalog2Weightdenom = hevcSliceParams->luma_log2_weight_denom + hevcSliceParams->delta_chroma_log2_weight_denom;
684         cmd.DW4.LumaLog2WeightDenom = hevcSliceParams->luma_log2_weight_denom;
685         cmd.DW4.CabacInitFlag = hevcSliceParams->LongSliceFlags.fields.cabac_init_flag;
686         cmd.DW4.Maxmergeidx = 5 - hevcSliceParams->five_minus_max_num_merge_cand - 1;
687 
688         uint8_t collocatedRefIndex, collocatedFrameIdx, collocatedFromL0Flag;
689 
690         if (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1)
691         {
692             //Get Collocated Picture POC
693             collocatedRefIndex = hevcSliceParams->collocated_ref_idx;
694             collocatedFrameIdx = 0;
695             collocatedFromL0Flag = hevcSliceParams->LongSliceFlags.fields.collocated_from_l0_flag;
696             if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_P_SLICE)
697             {
698                 collocatedFrameIdx = hevcSliceParams->RefPicList[0][collocatedRefIndex].FrameIdx;
699             }
700             else if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_B_SLICE)
701             {
702                 collocatedFrameIdx = hevcSliceParams->RefPicList[!collocatedFromL0Flag][collocatedRefIndex].FrameIdx;
703             }
704 
705             if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE)
706             {
707                 cmd.DW4.Collocatedrefidx = 0;
708             }
709             else
710             {
711                 MHW_CHK_COND(*(hevcSliceState->pRefIdxMapping + collocatedFrameIdx) < 0, "Invalid parameter");
712                 cmd.DW4.Collocatedrefidx = *(hevcSliceState->pRefIdxMapping + collocatedFrameIdx);
713             }
714         }
715         else
716         {
717             cmd.DW4.Collocatedrefidx = 0;
718         }
719 
720         static uint8_t  ucFirstInterSliceCollocatedFrameIdx;
721         static uint8_t  ucFirstInterSliceCollocatedFromL0Flag;
722         static bool   bFinishFirstInterSlice;
723 
724         //Need to save the first interSlice collocatedRefIdx value to use on subsequent intra slices
725         //this is a HW requrement as collcoated ref fetching from memory may not be complete yet
726         if (hevcSliceState->dwSliceIndex == 0)
727         {
728             ucFirstInterSliceCollocatedFrameIdx = 0;
729             ucFirstInterSliceCollocatedFromL0Flag = 0;
730             bFinishFirstInterSlice = false;
731         }
732 
733         if ((!bFinishFirstInterSlice) &&
734             (hevcSliceParams->LongSliceFlags.fields.slice_type != cmd.SLICE_TYPE_I_SLICE) &&
735             (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1))
736         {
737             ucFirstInterSliceCollocatedFrameIdx = cmd.DW4.Collocatedrefidx;
738             ucFirstInterSliceCollocatedFromL0Flag = cmd.DW4.CollocatedFromL0Flag;
739             bFinishFirstInterSlice = true;
740         }
741 
742         if (bFinishFirstInterSlice &&
743             ((hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE) ||
744                 (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 0)))
745         {
746             cmd.DW4.Collocatedrefidx = ucFirstInterSliceCollocatedFrameIdx;
747             cmd.DW4.CollocatedFromL0Flag = ucFirstInterSliceCollocatedFromL0Flag;
748         }
749 
750         cmd.DW5.Sliceheaderlength = hevcSliceParams->ByteOffsetToSliceData;
751 
752         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
753 
754         return eStatus;
755     }
756 
AddHcpEncodeSliceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState)757     MOS_STATUS AddHcpEncodeSliceStateCmd(
758         PMOS_COMMAND_BUFFER              cmdBuffer,
759         PMHW_VDBOX_HEVC_SLICE_STATE      hevcSliceState)
760     {
761         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
762 
763         MHW_FUNCTION_ENTER;
764 
765         MHW_MI_CHK_NULL(cmdBuffer);
766         MHW_MI_CHK_NULL(m_osInterface);
767         MHW_MI_CHK_NULL(hevcSliceState);
768 
769         typename THcpCmds::HCP_SLICE_STATE_CMD      cmd;
770 
771         auto hevcSliceParams = hevcSliceState->pHevcSliceParams;
772         auto hevcPicParams = hevcSliceState->pHevcPicParams;
773 
774         uint32_t ctbSize = 1 << (hevcPicParams->log2_diff_max_min_luma_coding_block_size +
775             hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
776         uint32_t widthInPix = (1 << (hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) *
777             (hevcPicParams->PicWidthInMinCbsY);
778         uint32_t widthInCtb = MOS_ROUNDUP_DIVIDE(widthInPix, ctbSize);
779 
780         // It is a hardware requirement that the first HCP_SLICE_STATE of the workload starts at LCU X,Y = 0,0.
781         // If first slice doesn't starts from (0,0), that means this is error bitstream.
782         if (hevcSliceState->dwSliceIndex == 0)
783         {
784             cmd.DW1.SlicestartctbxOrSliceStartLcuXEncoder = 0;
785             cmd.DW1.SlicestartctbyOrSliceStartLcuYEncoder = 0;
786         }
787         else
788         {
789             cmd.DW1.SlicestartctbxOrSliceStartLcuXEncoder = hevcSliceParams->slice_segment_address % widthInCtb;
790             cmd.DW1.SlicestartctbyOrSliceStartLcuYEncoder = hevcSliceParams->slice_segment_address / widthInCtb;
791         }
792 
793         if (hevcSliceState->bLastSlice)
794         {
795             cmd.DW2.NextslicestartctbxOrNextSliceStartLcuXEncoder = 0;
796             cmd.DW2.NextslicestartctbyOrNextSliceStartLcuYEncoder = 0;
797         }
798         else
799         {
800             cmd.DW2.NextslicestartctbxOrNextSliceStartLcuXEncoder = (hevcSliceParams + 1)->slice_segment_address % widthInCtb;
801             cmd.DW2.NextslicestartctbyOrNextSliceStartLcuYEncoder = (hevcSliceParams + 1)->slice_segment_address / widthInCtb;
802         }
803 
804         cmd.DW3.SliceType = hevcSliceParams->LongSliceFlags.fields.slice_type;
805         cmd.DW3.Lastsliceofpic = hevcSliceState->bLastSlice;
806         cmd.DW3.DependentSliceFlag = hevcSliceParams->LongSliceFlags.fields.dependent_slice_segment_flag;
807         cmd.DW3.SliceTemporalMvpEnableFlag = hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag;
808         cmd.DW3.Sliceqp = hevcSliceParams->slice_qp_delta + hevcPicParams->init_qp_minus26 + 26;
809         cmd.DW3.SliceCbQpOffset = hevcSliceParams->slice_cb_qp_offset;
810         cmd.DW3.SliceCrQpOffset = hevcSliceParams->slice_cr_qp_offset;
811 
812         cmd.DW4.SliceHeaderDisableDeblockingFilterFlag = hevcSliceParams->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag;
813         cmd.DW4.SliceTcOffsetDiv2OrFinalTcOffsetDiv2Encoder = hevcSliceParams->slice_tc_offset_div2;
814         cmd.DW4.SliceBetaOffsetDiv2OrFinalBetaOffsetDiv2Encoder = hevcSliceParams->slice_beta_offset_div2;
815         cmd.DW4.SliceLoopFilterAcrossSlicesEnabledFlag = hevcSliceParams->LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag;
816         cmd.DW4.SliceSaoChromaFlag = hevcSliceParams->LongSliceFlags.fields.slice_sao_chroma_flag;
817         cmd.DW4.SliceSaoLumaFlag = hevcSliceParams->LongSliceFlags.fields.slice_sao_luma_flag;
818         cmd.DW4.MvdL1ZeroFlag = hevcSliceParams->LongSliceFlags.fields.mvd_l1_zero_flag;
819 
820         uint32_t  numNegativePic = 0;
821         uint32_t  numPositivePic = 0;
822 
823         if (hevcSliceParams->LongSliceFlags.fields.slice_type != cmd.SLICE_TYPE_I_SLICE)
824         {
825             for (uint8_t i = 0; i < hevcSliceParams->num_ref_idx_l0_active_minus1 + 1; i++)
826             {
827                 uint8_t  refFrameID = hevcSliceParams->RefPicList[0][i].FrameIdx;
828                 int32_t  pocDiff = hevcPicParams->CurrPicOrderCntVal - hevcPicParams->PicOrderCntValList[refFrameID];
829                 if (pocDiff > 0)
830                 {
831                     numNegativePic++;
832                 }
833             }
834         }
835         else
836         {
837             numNegativePic = 0;
838         }
839 
840         if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_B_SLICE)
841         {
842             for (uint8_t i = 0; i < hevcSliceParams->num_ref_idx_l1_active_minus1 + 1; i++)
843             {
844                 uint8_t  refFrameID = hevcSliceParams->RefPicList[1][i].FrameIdx;
845                 int32_t  pocDiff = hevcPicParams->CurrPicOrderCntVal - hevcPicParams->PicOrderCntValList[refFrameID];
846                 if (pocDiff < 0)
847                 {
848                     numPositivePic++;
849                 }
850             }
851         }
852         else
853         {
854             numPositivePic = 0;
855         }
856 
857         if ((numNegativePic == (hevcSliceParams->num_ref_idx_l0_active_minus1 + 1)) &&
858             (numPositivePic == 0))
859         {
860             cmd.DW4.Islowdelay = 1;
861         }
862         else
863         {
864             cmd.DW4.Islowdelay = 0;
865         }
866 
867         cmd.DW4.CollocatedFromL0Flag = hevcSliceParams->LongSliceFlags.fields.collocated_from_l0_flag;
868         cmd.DW4.Chromalog2Weightdenom = (hevcPicParams->weighted_pred_flag || hevcPicParams->weighted_bipred_flag) ?
869             (hevcSliceParams->luma_log2_weight_denom + hevcSliceParams->delta_chroma_log2_weight_denom) : 0;
870         cmd.DW4.LumaLog2WeightDenom = (hevcPicParams->weighted_pred_flag || hevcPicParams->weighted_bipred_flag) ?
871             hevcSliceParams->luma_log2_weight_denom : 0;
872         cmd.DW4.CabacInitFlag = hevcSliceParams->LongSliceFlags.fields.cabac_init_flag;
873         cmd.DW4.Maxmergeidx = 5 - hevcSliceParams->five_minus_max_num_merge_cand - 1;
874 
875         uint8_t   collocatedRefIndex, collocatedFrameIdx, collocatedFromL0Flag;
876 
877         if (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1)
878         {
879             //Get Collocated Picture POC
880             collocatedRefIndex = hevcSliceParams->collocated_ref_idx;
881             collocatedFrameIdx = 0;
882             collocatedFromL0Flag = hevcSliceParams->LongSliceFlags.fields.collocated_from_l0_flag;
883             if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_P_SLICE)
884             {
885                 collocatedFrameIdx = hevcSliceParams->RefPicList[0][collocatedRefIndex].FrameIdx;
886             }
887             else if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_B_SLICE)
888             {
889                 collocatedFrameIdx = hevcSliceParams->RefPicList[!collocatedFromL0Flag][collocatedRefIndex].FrameIdx;
890             }
891 
892             if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE)
893             {
894                 cmd.DW4.Collocatedrefidx = 0;
895             }
896             else
897             {
898                 MHW_CHK_COND(*(hevcSliceState->pRefIdxMapping + collocatedFrameIdx) < 0, "Invalid parameter");
899                 cmd.DW4.Collocatedrefidx = *(hevcSliceState->pRefIdxMapping + collocatedFrameIdx);
900             }
901         }
902         else
903         {
904             cmd.DW4.Collocatedrefidx = 0;
905         }
906 
907         static uint8_t   ucFirstInterSliceCollocatedFrameIdx;
908         static uint8_t   ucFirstInterSliceCollocatedFromL0Flag;
909         static bool      bFinishFirstInterSlice;
910 
911         //Need to save the first interSlice collocatedRefIdx value to use on subsequent intra slices
912         //this is a HW requrement as collcoated ref fetching from memory may not be complete yet
913         if (hevcSliceState->dwSliceIndex == 0)
914         {
915             ucFirstInterSliceCollocatedFrameIdx = 0;
916             ucFirstInterSliceCollocatedFromL0Flag = 0;
917             bFinishFirstInterSlice = false;
918         }
919 
920         if ((!bFinishFirstInterSlice) &&
921             (hevcSliceParams->LongSliceFlags.fields.slice_type != cmd.SLICE_TYPE_I_SLICE) &&
922             (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1))
923         {
924             ucFirstInterSliceCollocatedFrameIdx = cmd.DW4.Collocatedrefidx;
925             ucFirstInterSliceCollocatedFromL0Flag = cmd.DW4.CollocatedFromL0Flag;
926             bFinishFirstInterSlice = true;
927         }
928 
929         if (bFinishFirstInterSlice &&
930             ((hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE) ||
931                 (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 0)))
932         {
933             cmd.DW4.Collocatedrefidx = ucFirstInterSliceCollocatedFrameIdx;
934             cmd.DW4.CollocatedFromL0Flag = ucFirstInterSliceCollocatedFromL0Flag;
935         }
936 
937         cmd.DW5.Sliceheaderlength = hevcSliceParams->ByteOffsetToSliceData;
938 
939         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
940 
941         return eStatus;
942     }
943 
AddHcpDecodeProtectStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState)944     MOS_STATUS AddHcpDecodeProtectStateCmd(
945         PMOS_COMMAND_BUFFER              cmdBuffer,
946         PMHW_VDBOX_HEVC_SLICE_STATE      hevcSliceState)
947     {
948         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
949 
950         MHW_FUNCTION_ENTER;
951 
952         MHW_MI_CHK_NULL(hevcSliceState);
953 
954         MHW_CP_SLICE_INFO_PARAMS sliceInfoParam;
955         sliceInfoParam.presDataBuffer = hevcSliceState->presDataBuffer;
956         sliceInfoParam.dwSliceIndex = hevcSliceState->dwSliceIndex;
957         sliceInfoParam.dwTotalBytesConsumed = 0;
958         sliceInfoParam.bLastPass = hevcSliceState->bLastSlice;
959         sliceInfoParam.dwDataStartOffset[0] = hevcSliceState->pHevcSliceParams->slice_data_offset + hevcSliceState->dwOffset;
960         sliceInfoParam.dwDataStartOffset[1] = hevcSliceState->pHevcSliceParams->slice_data_offset + hevcSliceState->dwOffset;
961         sliceInfoParam.dwDataLength[0] = hevcSliceState->pHevcSliceParams->slice_data_size;
962         sliceInfoParam.dwDataLength[1] = hevcSliceState->pHevcSliceParams->slice_data_size;
963 
964         MHW_MI_CHK_STATUS(m_cpInterface->SetHcpProtectionState(
965             true,
966             cmdBuffer,
967             nullptr,
968             &sliceInfoParam));
969 
970         return eStatus;
971     }
972 };
973 
974 #endif
975