1 /*
2 * Copyright (c) 2023, 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_hevc_basic_feature.cpp
24 //! \brief    Defines the common interface for encode hevc parameter
25 //!
26 
27 #include "encode_hevc_basic_feature.h"
28 #include "encode_utils.h"
29 #include "encode_allocator.h"
30 #include "encode_hevc_header_packer.h"
31 #include "encode_hevc_vdenc_const_settings.h"
32 #include "mos_solo_generic.h"
33 #include "mos_os_cp_interface_specific.h"
34 
35 using namespace mhw::vdbox;
36 namespace encode
37 {
~HevcBasicFeature()38 HevcBasicFeature::~HevcBasicFeature()
39 {
40     if (m_422State)
41     {
42         MOS_Delete(m_422State);
43         m_422State = nullptr;
44     }
45 }
46 
Init(void * setting)47 MOS_STATUS HevcBasicFeature::Init(void *setting)
48 {
49     ENCODE_FUNC_CALL();
50     ENCODE_CHK_NULL_RETURN(setting);
51 
52     EncodeBasicFeature::Init(setting);
53 
54     // It is assumed to be frame-mode always
55     m_frameFieldHeight     = m_frameHeight;
56     m_frameFieldHeightInMb = m_picHeightInMb;
57     m_picWidthInMinLCU = MOS_ROUNDUP_DIVIDE(m_frameWidth, CODECHAL_HEVC_MIN_LCU_SIZE);        //assume smallest LCU to get max width;
58     m_picHeightInMinLCU = MOS_ROUNDUP_DIVIDE(m_frameHeight, CODECHAL_HEVC_MIN_LCU_SIZE);      //assume smallest LCU to get max height
59     m_widthAlignedMaxLCU  = MOS_ALIGN_CEIL(m_frameWidth, m_maxLCUSize);
60     m_heightAlignedMaxLCU = MOS_ALIGN_CEIL(m_frameHeight, m_maxLCUSize);
61     m_sizeOfSseSrcPixelRowStoreBufferPerLcu = CODECHAL_CACHELINE_SIZE * (4 + 4) << 1;
62 
63     //cannot remove as it used by reference frame
64     m_maxTileNumber = CODECHAL_GET_WIDTH_IN_BLOCKS(m_frameWidth, CODECHAL_HEVC_MIN_TILE_SIZE) *
65         CODECHAL_GET_HEIGHT_IN_BLOCKS(m_frameHeight, CODECHAL_HEVC_MIN_TILE_SIZE);
66 
67     MOS_ALLOC_GFXRES_PARAMS allocParams{};
68     allocParams.Type     = MOS_GFXRES_BUFFER;
69     allocParams.TileType = MOS_TILE_LINEAR;
70     allocParams.Format   = Format_Buffer;
71 
72     allocParams.dwBytes  = MOS_ALIGN_CEIL(m_sizeOfHcpPakFrameStats * m_maxTileNumber, CODECHAL_PAGE_SIZE);
73     allocParams.pBufName = "FrameStatStreamOutBuffer";
74     allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
75     m_recycleBuf->RegisterResource(FrameStatStreamOutBuffer, allocParams, 1);
76 
77     allocParams.dwBytes  = MOS_ALIGN_CEIL(1216 * m_maxTileNumber, CODECHAL_PAGE_SIZE);
78     allocParams.pBufName = "vdencStats";
79     allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
80     m_recycleBuf->RegisterResource(VdencStatsBuffer, allocParams, 1);
81 
82     uint32_t numOfLCU    = MOS_ROUNDUP_DIVIDE(m_frameWidth, m_maxLCUSize) * (MOS_ROUNDUP_DIVIDE(m_frameHeight, m_maxLCUSize) + 1);
83     allocParams.dwBytes  = MOS_ALIGN_CEIL(2 * sizeof(uint32_t) * (numOfLCU * 5 + numOfLCU * 64 * 8), CODECHAL_PAGE_SIZE);
84     allocParams.pBufName = "CuRecordStreamOutBuffer";
85     allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_OUTPUT_STATISTICS_WRITE;
86     ENCODE_NORMALMESSAGE("osCpInterface = %p\n", m_osInterface->osCpInterface);
87     if (m_osInterface->osCpInterface != nullptr)
88     {
89         ENCODE_NORMALMESSAGE("IsCpEnabled = %u\n", m_osInterface->osCpInterface->IsCpEnabled());
90     }
91     if (m_osInterface->osCpInterface == nullptr || !m_osInterface->osCpInterface->IsCpEnabled())
92     {
93         allocParams.dwMemType = MOS_MEMPOOL_SYSTEMMEMORY;
94     }
95     allocParams.Flags.bCacheable = true;
96     m_recycleBuf->RegisterResource(CuRecordStreamOutBuffer, allocParams, m_maxSyncDepth);
97 
98     ENCODE_CHK_STATUS_RETURN(m_ref.Init(this, m_allocator));
99 
100     MediaUserSetting::Value outValue;
101 #if (_DEBUG || _RELEASE_INTERNAL)
102     ReadUserSettingForDebug(
103         m_userSettingPtr,
104         outValue,
105         "Disable HEVC RDOQ Perf",
106         MediaUserSetting::Group::Sequence);
107 #endif  // _DEBUG || _RELEASE_INTERNAL
108     m_hevcRDOQPerfDisabled = outValue.Get<bool>();
109 
110     ENCODE_CHK_STATUS_RETURN(Init422State());
111 
112     return MOS_STATUS_SUCCESS;
113 }
114 
Update(void * params)115 MOS_STATUS HevcBasicFeature::Update(void *params)
116 {
117     ENCODE_FUNC_CALL();
118     ENCODE_CHK_NULL_RETURN(params);
119 
120     ENCODE_CHK_STATUS_RETURN(EncodeBasicFeature::Update(params));
121 
122     EncoderParams* encodeParams = (EncoderParams*)params;
123 
124     m_hevcSeqParams = static_cast<PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
125     ENCODE_CHK_NULL_RETURN(m_hevcSeqParams);
126     m_hevcPicParams = static_cast<PCODEC_HEVC_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams);
127     ENCODE_CHK_NULL_RETURN(m_hevcPicParams);
128     m_hevcSliceParams = static_cast<PCODEC_HEVC_ENCODE_SLICE_PARAMS>(encodeParams->pSliceParams);
129     ENCODE_CHK_NULL_RETURN(m_hevcSliceParams);
130     m_hevcIqMatrixParams = static_cast<PCODECHAL_HEVC_IQ_MATRIX_PARAMS>(encodeParams->pIQMatrixBuffer);
131     ENCODE_CHK_NULL_RETURN(m_hevcIqMatrixParams);
132     m_nalUnitParams = encodeParams->ppNALUnitParams;
133     ENCODE_CHK_NULL_RETURN(m_nalUnitParams);
134     m_NumNalUnits   = encodeParams->uiNumNalUnits;
135     m_bEnableSubPelMode = encodeParams->bEnableSubPelMode;
136     m_SubPelMode        = encodeParams->SubPelMode;
137 
138     if (m_422State && m_422State->GetFeature422Flag())
139     {
140         ENCODE_CHK_STATUS_RETURN(m_422State->Update422Format(m_hevcSeqParams, m_outputChromaFormat, m_reconSurface.Format, m_is10Bit));
141     }
142 
143     if (encodeParams->bAcceleratorHeaderPackingCaps)
144     {
145         HevcHeaderPacker Packer;
146         Packer.SliceHeaderPacker(encodeParams);  //after here, slice parameters will be modified; here is th elast place to deliver encodeParams
147     }
148 
149     ENCODE_CHK_STATUS_RETURN(SetPictureStructs());
150     ENCODE_CHK_STATUS_RETURN(SetSliceStructs());
151 
152 #if (_DEBUG || _RELEASE_INTERNAL)
153     // To enable rounding precision here
154     MediaUserSetting::Value outValue;
155     ReadUserSetting(
156         m_userSettingPtr,
157         outValue,
158         "HEVC VDEnc Rounding Enable",
159         MediaUserSetting::Group::Sequence);
160     m_hevcVdencRoundingPrecisionEnabled = outValue.Get<bool>();
161     ReportUserSettingForDebug(
162         m_userSettingPtr,
163         "HEVC VDEnc Rounding Enable",
164         m_hevcVdencRoundingPrecisionEnabled,
165         MediaUserSetting::Group::Sequence);
166 #endif
167 
168     ENCODE_CHK_STATUS_RETURN(SetRoundingValues());
169 
170     uint32_t frameWidth = (m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3);
171 
172     uint32_t frameHeight = (m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3);
173 
174     // Only for first frame
175     if (m_frameNum == 0)
176     {
177         m_oriFrameHeight = frameHeight;
178         m_oriFrameWidth = frameWidth;
179         m_resolutionChanged = true;
180     }
181     else
182     {
183         // check if there is a dynamic resolution change
184         if ((m_oriFrameHeight && (m_oriFrameHeight != frameHeight)) ||
185             (m_oriFrameWidth && (m_oriFrameWidth != frameWidth)))
186         {
187             m_resolutionChanged = true;
188             m_oriFrameHeight = frameHeight;
189             m_oriFrameWidth = frameWidth;
190         }
191         else
192         {
193             m_resolutionChanged = false;
194         }
195     }
196 
197     if (m_resolutionChanged)
198     {
199         ENCODE_CHK_STATUS_RETURN(UpdateTrackedBufferParameters());
200     }
201 
202     ENCODE_CHK_STATUS_RETURN(GetTrackedBuffers());
203     ENCODE_CHK_STATUS_RETURN(GetRecycleBuffers());
204 
205     if (m_hevcSeqParams->LowDelayMode)
206     {
207         m_lambdaType = 1;
208         m_qpFactors  = {0.578, 0.3524, 0.3524};
209     }
210     else
211     {
212         m_lambdaType = 2;
213         m_qpFactors  = {0.442, 0.3536, 0.3536, 0.68}; // seems not used;
214     }
215 
216     return MOS_STATUS_SUCCESS;
217 }
218 
CalcLCUMaxCodingSize()219 MOS_STATUS HevcBasicFeature::CalcLCUMaxCodingSize()
220 {
221     ENCODE_FUNC_CALL();
222 
223     uint16_t log2_max_coding_block_size = m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3;
224     uint32_t rawCTUBits = (1 << (2 * log2_max_coding_block_size));
225 
226     switch (m_hevcSeqParams->chroma_format_idc)
227     {
228         // 420
229     case 1:
230         rawCTUBits = rawCTUBits * 3 / 2;
231         break;
232         // 422
233     case 2:
234         rawCTUBits = rawCTUBits * 2;
235         break;
236         // 444
237     case 3:
238         rawCTUBits = rawCTUBits * 3;
239         break;
240     default:
241         break;
242     };
243 
244     rawCTUBits = rawCTUBits * (m_hevcSeqParams->bit_depth_luma_minus8 + 8);
245     rawCTUBits = (5 * rawCTUBits / 3);
246 
247     if (m_hevcPicParams->LcuMaxBitsizeAllowed == 0 || m_hevcPicParams->LcuMaxBitsizeAllowed > rawCTUBits)
248     {
249         m_hevcPicParams->LcuMaxBitsizeAllowed = rawCTUBits;
250     }
251 
252     return MOS_STATUS_SUCCESS;
253 }
254 
CreateFlatScalingList()255 void HevcBasicFeature::CreateFlatScalingList()
256 {
257     ENCODE_FUNC_CALL();
258 
259     for (auto i = 0; i < 6; i++)
260     {
261         memset(&(m_hevcIqMatrixParams->ucScalingLists0[i][0]),
262             0x10,
263             sizeof(m_hevcIqMatrixParams->ucScalingLists0[i]));
264 
265         memset(&(m_hevcIqMatrixParams->ucScalingLists1[i][0]),
266             0x10,
267             sizeof(m_hevcIqMatrixParams->ucScalingLists1[i]));
268 
269         memset(&(m_hevcIqMatrixParams->ucScalingLists2[i][0]),
270             0x10,
271             sizeof(m_hevcIqMatrixParams->ucScalingLists2[i]));
272     }
273 
274     memset(&(m_hevcIqMatrixParams->ucScalingLists3[0][0]),
275         0x10,
276         sizeof(m_hevcIqMatrixParams->ucScalingLists3[0]));
277 
278     memset(&(m_hevcIqMatrixParams->ucScalingLists3[1][0]),
279         0x10,
280         sizeof(m_hevcIqMatrixParams->ucScalingLists3[1]));
281 
282     memset(&(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID2[0]),
283         0x10,
284         sizeof(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID2));
285 
286     memset(&(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID3[0]),
287         0x10,
288         sizeof(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID3));
289 }
290 
CreateDefaultScalingList()291 void HevcBasicFeature::CreateDefaultScalingList()
292 {
293     ENCODE_FUNC_CALL();
294 
295     const uint8_t flatScalingList4x4[16] =
296     {
297         16,16,16,16,
298         16,16,16,16,
299         16,16,16,16,
300         16,16,16,16
301     };
302 
303     const uint8_t defaultScalingList8x8[2][64] =
304     {
305         {
306             16,16,16,16,17,18,21,24,
307             16,16,16,16,17,19,22,25,
308             16,16,17,18,20,22,25,29,
309             16,16,18,21,24,27,31,36,
310             17,17,20,24,30,35,41,47,
311             18,19,22,27,35,44,54,65,
312             21,22,25,31,41,54,70,88,
313             24,25,29,36,47,65,88,115
314         },
315         {
316             16,16,16,16,17,18,20,24,
317             16,16,16,17,18,20,24,25,
318             16,16,17,18,20,24,25,28,
319             16,17,18,20,24,25,28,33,
320             17,18,20,24,25,28,33,41,
321             18,20,24,25,28,33,41,54,
322             20,24,25,28,33,41,54,71,
323             24,25,28,33,41,54,71,91
324         }
325     };
326 
327     for (auto i = 0; i < 6; i++)
328     {
329         memcpy(&(m_hevcIqMatrixParams->ucScalingLists0[i][0]),
330             flatScalingList4x4,
331             sizeof(m_hevcIqMatrixParams->ucScalingLists0[i]));
332     }
333 
334     for (auto i = 0; i < 3; i++)
335     {
336         memcpy(&(m_hevcIqMatrixParams->ucScalingLists1[i][0]),
337             defaultScalingList8x8[0],
338             sizeof(m_hevcIqMatrixParams->ucScalingLists1[i]));
339 
340         memcpy(&(m_hevcIqMatrixParams->ucScalingLists1[3 + i][0]),
341             defaultScalingList8x8[1],
342             sizeof(m_hevcIqMatrixParams->ucScalingLists1[3 + i]));
343 
344         memcpy(&(m_hevcIqMatrixParams->ucScalingLists2[i][0]),
345             defaultScalingList8x8[0],
346             sizeof(m_hevcIqMatrixParams->ucScalingLists2[i]));
347 
348         memcpy(&(m_hevcIqMatrixParams->ucScalingLists2[3 + i][0]),
349             defaultScalingList8x8[1],
350             sizeof(m_hevcIqMatrixParams->ucScalingLists2[3 + i]));
351     }
352 
353     memcpy(&(m_hevcIqMatrixParams->ucScalingLists3[0][0]),
354         defaultScalingList8x8[0],
355         sizeof(m_hevcIqMatrixParams->ucScalingLists3[0]));
356 
357     memcpy(&(m_hevcIqMatrixParams->ucScalingLists3[1][0]),
358         defaultScalingList8x8[1],
359         sizeof(m_hevcIqMatrixParams->ucScalingLists3[1]));
360 
361     memset(&(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID2[0]),
362         0x10,
363         sizeof(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID2));
364 
365     memset(&(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID3[0]),
366         0x10,
367         sizeof(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID3));
368 }
369 
370 
SetPictureStructs()371 MOS_STATUS HevcBasicFeature::SetPictureStructs()
372 {
373     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
374 
375     ENCODE_FUNC_CALL();
376 
377     m_targetUsage                = m_hevcSeqParams->TargetUsage;
378     m_lastPicInSeq               = m_hevcPicParams->bLastPicInSeq;
379     m_lastPicInStream            = m_hevcPicParams->bLastPicInStream;
380     m_currOriginalPic            = m_hevcPicParams->CurrOriginalPic;
381     m_currReconstructedPic       = m_hevcPicParams->CurrReconstructedPic;
382 
383     ENCODE_CHK_STATUS_RETURN(m_ref.UpdatePicture());
384     m_pictureCodingType = m_ref.GetPictureCodingType();
385 
386     if (m_hevcPicParams->QpY > m_maxSliceQP)
387     {
388         return MOS_STATUS_INVALID_PARAMETER;
389     }
390 
391     if (Mos_ResourceIsNull(&m_reconSurface.OsResource) &&
392         (!m_hevcPicParams->bUseRawPicForRef || m_codecFunction != CODECHAL_FUNCTION_ENC))
393     {
394         return MOS_STATUS_INVALID_PARAMETER;
395     }
396 
397     if (m_hevcSeqParams->scaling_list_enable_flag && !m_hevcPicParams->scaling_list_data_present_flag)
398     {
399         CreateDefaultScalingList();
400     }
401     else if (!m_hevcSeqParams->scaling_list_enable_flag)
402     {
403         CreateFlatScalingList();
404     }
405 
406     ENCODE_CHK_STATUS_RETURN(CalcLCUMaxCodingSize());
407 
408     // EOS is not working on GEN12, disable it by setting below to false (WA), only needed by HEVC VDENC
409     m_lastPicInSeq = false;
410     m_lastPicInStream = false;
411 
412     return eStatus;
413 }
414 
SetSliceStructs()415 MOS_STATUS HevcBasicFeature::SetSliceStructs()
416 {
417     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
418 
419     ENCODE_FUNC_CALL();
420 
421     ENCODE_CHK_STATUS_RETURN(m_ref.UpdateSlice());
422 
423     if(m_hevcPicParams->bEnableRollingIntraRefresh != 0)
424     {
425         ENCODE_CHK_STATUS_RETURN(m_ref.UpdateRollingIReferenceLocation());
426     }
427     return MOS_STATUS_SUCCESS;
428 }
429 
UpdateTrackedBufferParameters()430 MOS_STATUS HevcBasicFeature::UpdateTrackedBufferParameters()
431 {
432     // The MB/MV code size here, are just for HEVC VDENC, maybe different in Dual Pipe(VME) cases
433     uint32_t numOfLCU = MOS_ROUNDUP_DIVIDE(m_frameWidth, m_maxLCUSize) * (MOS_ROUNDUP_DIVIDE(m_frameHeight, m_maxLCUSize) + 1);
434 
435     m_mbCodeSize = MOS_ALIGN_CEIL(2 * sizeof(uint32_t) * (numOfLCU * 5 + numOfLCU * 64 * 8), CODECHAL_PAGE_SIZE);
436 
437     m_mvDataSize = 0;
438 
439     uint32_t mvt_size        = MOS_ALIGN_CEIL(((m_frameWidth + 63) >> 6) * ((m_frameHeight + 15) >> 4), 2) * CODECHAL_CACHELINE_SIZE;
440     uint32_t mvtb_size       = MOS_ALIGN_CEIL(((m_frameWidth + 31) >> 5) * ((m_frameHeight + 31) >> 5), 2) * CODECHAL_CACHELINE_SIZE;
441     m_sizeOfMvTemporalBuffer = MOS_MAX(mvt_size, mvtb_size);
442 
443     uint32_t downscaledWidthInMb4x =
444         CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_4x);
445     uint32_t downscaledHeightInMb4x =
446         CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
447 
448     m_downscaledWidth4x =
449         downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
450 
451     // Account for field case, offset needs to be 4K aligned if tiled for DI surface state.
452     // Width will be allocated tile Y aligned, so also tile align height.
453     uint32_t downscaledSurfaceHeight4x = ((downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
454 
455     m_downscaledHeight4x = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
456 
457     MOS_ALLOC_GFXRES_PARAMS allocParams;
458     MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
459     allocParams.Type     = MOS_GFXRES_BUFFER;
460     allocParams.TileType = MOS_TILE_LINEAR;
461     allocParams.Format   = Format_Buffer;
462 
463     if (m_sizeOfMvTemporalBuffer > 0)
464     {
465         allocParams.dwBytes  = m_sizeOfMvTemporalBuffer;
466         allocParams.pBufName = "mvTemporalBuffer";
467         allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
468         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::mvTemporalBuffer, allocParams));
469     }
470 
471     if (m_422State && m_422State->GetFeature422Flag())
472     {
473         ENCODE_CHK_STATUS_RETURN(m_422State->RegisterMbCodeBuffer(m_trackedBuf, m_isMbCodeRegistered, m_mbCodeSize));
474     }
475 
476     ENCODE_CHK_STATUS_RETURN(EncodeBasicFeature::UpdateTrackedBufferParameters());
477 
478     return MOS_STATUS_SUCCESS;
479 }
480 
GetMaxMBPS(uint32_t levelIdc,uint32_t * maxMBPS,uint64_t * maxBytePerPic)481 MOS_STATUS HevcBasicFeature::GetMaxMBPS(uint32_t levelIdc, uint32_t* maxMBPS, uint64_t* maxBytePerPic)
482 {
483     ENCODE_FUNC_CALL();
484 
485     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
486 
487     ENCODE_CHK_NULL_RETURN(maxMBPS);
488     ENCODE_CHK_NULL_RETURN(maxBytePerPic);
489 
490     switch (levelIdc)
491     {
492     case 30:
493         *maxMBPS = 552960;
494         *maxBytePerPic = 36864;
495         break;
496     case 60:
497         *maxMBPS = 3686400;
498         *maxBytePerPic = 122880;
499         break;
500     case 63:
501         *maxMBPS = 7372800;
502         *maxBytePerPic = 245760;
503         break;
504     case 90:
505         *maxMBPS = 16588800;
506         *maxBytePerPic = 552760;
507         break;
508     case 93:
509         *maxMBPS = 33177600;
510         *maxBytePerPic = 983040;
511         break;
512     case 120:
513         *maxMBPS = 66846720;
514         *maxBytePerPic = 2228224;
515         break;
516     case 123:
517         *maxMBPS = 133693440;
518         *maxBytePerPic = 2228224;
519         break;
520     case 150:
521         *maxMBPS = 267386880;
522         *maxBytePerPic = 8912896;
523         break;
524     case 153:
525         *maxMBPS = 534773760;
526         *maxBytePerPic = 8912896;
527         break;
528     case 156:
529         *maxMBPS = 1069547520;
530         *maxBytePerPic = 8912896;
531         break;
532     case 180:
533         *maxMBPS = 1069547520;
534         *maxBytePerPic = 35651584;
535         break;
536     case 183:
537         *maxMBPS = 2139095040;
538         *maxBytePerPic = 35651584;
539         break;
540     case 186:
541         *maxMBPS = 4278190080;
542         *maxBytePerPic = 35651584;
543         break;
544     default:
545         *maxMBPS = 16588800;
546         *maxBytePerPic = 552760; // CModel defaults to level 3.0 value if not found,
547                                  // we can do the same, just output that the issue exists and continue
548         ENCODE_ASSERTMESSAGE("Unsupported LevelIDC setting for HEVC");
549         break;
550     }
551 
552     return eStatus;
553 }
554 
GetProfileLevelMaxFrameSize()555 uint32_t HevcBasicFeature::GetProfileLevelMaxFrameSize()
556 {
557     ENCODE_FUNC_CALL();
558 
559     uint8_t         minCR = 2;
560     float_t         formatFactor = 1.5;
561     float_t         fminCrScale = 1.0;
562     int32_t         levelIdc = m_hevcSeqParams->Level * 3;
563 
564     if (levelIdc == 186 || levelIdc == 150)
565     {
566         minCR = 6;
567     }
568     else if (levelIdc >150)
569     {
570         minCR = 8;
571     }
572     else if (levelIdc >93)
573     {
574         minCR = 4;
575     }
576 
577     if (m_hevcSeqParams->chroma_format_idc == 0)
578     {
579         if (m_hevcSeqParams->bit_depth_luma_minus8 == 0)
580             formatFactor = 1.0;
581         else if (m_hevcSeqParams->bit_depth_luma_minus8 == 8)
582             formatFactor = 2.0;
583     }
584     else if (m_hevcSeqParams->chroma_format_idc == 1)
585     {
586         if (m_hevcSeqParams->bit_depth_luma_minus8 == 2)
587         {
588             formatFactor = 1.875;
589         }
590         else if (m_hevcSeqParams->bit_depth_luma_minus8 == 4)
591         {
592             formatFactor = 2.25;
593         }
594     }
595     else if (m_hevcSeqParams->chroma_format_idc == 2)
596     {
597         fminCrScale = 0.5;
598         if (m_hevcSeqParams->bit_depth_luma_minus8 == 2)
599         {
600             formatFactor = 2.5;
601         }
602         else if (m_hevcSeqParams->bit_depth_luma_minus8 == 4)
603         {
604             formatFactor = 3.0;
605         }
606     }
607     else
608     {
609         fminCrScale = 0.5;
610         formatFactor = 3.0;
611 
612         if (m_hevcSeqParams->bit_depth_luma_minus8 == 2)
613         {
614             formatFactor = 3.75;
615         }
616         else if (m_hevcSeqParams->bit_depth_luma_minus8 == 4)
617         {
618             formatFactor = 4.5;
619         }
620     }
621 
622     fminCrScale *= minCR;
623     formatFactor /= fminCrScale;
624 
625     uint32_t        maxMBPS = 0;
626     uint64_t        maxBytePerPic = 0;
627     GetMaxMBPS(levelIdc, &maxMBPS, &maxBytePerPic);
628     auto     maxBytePerPicNot0    = (uint64_t)((((float_t)maxMBPS * (float_t)m_hevcSeqParams->FrameRate.Denominator) / (float_t)m_hevcSeqParams->FrameRate.Numerator) * formatFactor);
629     uint32_t profileLevelMaxFrame = 0;
630 
631     profileLevelMaxFrame = (uint32_t)MOS_MIN(maxBytePerPicNot0, maxBytePerPic);
632     profileLevelMaxFrame = (uint32_t)MOS_MIN((m_frameHeight * m_frameWidth), profileLevelMaxFrame);
633 
634     return profileLevelMaxFrame;
635 }
636 
GetTrackedBuffers()637 MOS_STATUS HevcBasicFeature::GetTrackedBuffers()
638 {
639     ENCODE_CHK_NULL_RETURN(m_trackedBuf);
640     ENCODE_CHK_NULL_RETURN(m_hevcPicParams);
641     ENCODE_CHK_NULL_RETURN(m_allocator);
642 
643     auto currRefList = m_ref.GetCurrRefList();
644     m_trackedBuf->Acquire(currRefList, false);
645 
646     m_resMbCodeBuffer = m_trackedBuf->GetBuffer(BufferType::mbCodedBuffer, m_trackedBuf->GetCurrIndex());
647     ENCODE_CHK_NULL_RETURN(m_resMbCodeBuffer);
648 
649     m_resMvTemporalBuffer = m_trackedBuf->GetBuffer(BufferType::mvTemporalBuffer, m_trackedBuf->GetCurrIndex());
650     ENCODE_CHK_NULL_RETURN(m_resMvTemporalBuffer);
651 
652     m_4xDSSurface = m_trackedBuf->GetSurface(BufferType::ds4xSurface, m_trackedBuf->GetCurrIndex());
653     ENCODE_CHK_NULL_RETURN(m_4xDSSurface);
654     ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(m_4xDSSurface));
655 
656     m_8xDSSurface = m_trackedBuf->GetSurface(BufferType::ds8xSurface, m_trackedBuf->GetCurrIndex());
657     ENCODE_CHK_NULL_RETURN(m_8xDSSurface);
658     ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(m_8xDSSurface));
659 
660     return MOS_STATUS_SUCCESS;
661 }
662 
GetRecycleBuffers()663 MOS_STATUS HevcBasicFeature::GetRecycleBuffers()
664 {
665     ENCODE_CHK_NULL_RETURN(m_recycleBuf);
666 
667     uint32_t recycleBufferIdx = -1;
668     for (uint32_t i = 0; i < m_maxSyncDepth; i++)
669     {
670         auto pos = find(m_recycleBufferIdxes.begin(), m_recycleBufferIdxes.end(), i);
671         if (pos == m_recycleBufferIdxes.end())
672         {
673             recycleBufferIdx = i;
674             break;
675         }
676     }
677 
678     if (recycleBufferIdx == -1)
679     {
680         return MOS_STATUS_SUCCESS;
681     }
682 
683     m_resMbCodeBuffer = m_recycleBuf->GetBuffer(RecycleResId::CuRecordStreamOutBuffer, recycleBufferIdx);
684     ENCODE_CHK_NULL_RETURN(m_resMbCodeBuffer);
685 
686     m_recycleBufferIdxes.push_back(recycleBufferIdx);
687 
688     return MOS_STATUS_SUCCESS;
689 }
690 
SetRoundingValues()691 MOS_STATUS HevcBasicFeature::SetRoundingValues()
692 {
693     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
694 
695     ENCODE_FUNC_CALL();
696 
697     if (m_hevcPicParams->CustomRoundingOffsetsParams.fields.EnableCustomRoudingIntra)
698     {
699         m_roundingIntra = m_hevcPicParams->CustomRoundingOffsetsParams.fields.RoundingOffsetIntra;
700     }
701     else
702     {
703         if (m_hevcPicParams->CodingType == I_TYPE)
704         {
705             m_roundingIntra = 10;
706         }
707         else if (m_hevcSeqParams->HierarchicalFlag && m_hevcPicParams->HierarchLevelPlus1 > 0)
708         {
709             //Hierachical GOP
710             if (m_hevcPicParams->HierarchLevelPlus1 == 1)
711             {
712                 m_roundingIntra = 10;
713             }
714             else if (m_hevcPicParams->HierarchLevelPlus1 == 2)
715             {
716                 m_roundingIntra = 9;
717             }
718             else
719             {
720                 m_roundingIntra = 8;
721             }
722         }
723         else
724         {
725             m_roundingIntra = 10;
726         }
727     }
728 
729     if (m_hevcPicParams->CustomRoundingOffsetsParams.fields.EnableCustomRoudingInter)
730     {
731         m_roundingInter = m_hevcPicParams->CustomRoundingOffsetsParams.fields.RoundingOffsetInter;
732     }
733     else
734     {
735         if (m_hevcPicParams->CodingType == I_TYPE)
736         {
737             m_roundingInter = 4;
738         }
739         else if (m_hevcSeqParams->HierarchicalFlag && m_hevcPicParams->HierarchLevelPlus1 > 0)
740         {
741             //Hierachical GOP
742             if (m_hevcPicParams->HierarchLevelPlus1 == 1)
743             {
744                 m_roundingInter = 4;
745             }
746             else if (m_hevcPicParams->HierarchLevelPlus1 == 2)
747             {
748                 m_roundingInter = 3;
749             }
750             else
751             {
752                 m_roundingInter = 2;
753             }
754         }
755         else
756         {
757             m_roundingInter = 4;
758         }
759     }
760 
761     return eStatus;
762 }
763 
Init422State()764 MOS_STATUS HevcBasicFeature::Init422State()
765 {
766     ENCODE_FUNC_CALL();
767 
768     m_422State = MOS_New(HevcBasicFeature422);
769     ENCODE_CHK_NULL_RETURN(m_422State);
770 
771     return MOS_STATUS_SUCCESS;
772 }
773 
GetSurfaceMmcInfo(PMOS_SURFACE surface,MOS_MEMCOMP_STATE & mmcState,uint32_t & compressionFormat) const774 MOS_STATUS HevcBasicFeature::GetSurfaceMmcInfo(PMOS_SURFACE surface, MOS_MEMCOMP_STATE &mmcState, uint32_t &compressionFormat) const
775 {
776     ENCODE_FUNC_CALL();
777 
778     ENCODE_CHK_NULL_RETURN(surface);
779 
780 #ifdef _MMC_SUPPORTED
781     ENCODE_CHK_NULL_RETURN(m_mmcState);
782     if (m_mmcState->IsMmcEnabled())
783     {
784         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(surface, &mmcState));
785         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcFormat(surface, &compressionFormat));
786     }
787     else
788     {
789         mmcState = MOS_MEMCOMP_DISABLED;
790     }
791 #endif
792 
793     return MOS_STATUS_SUCCESS;
794 }
795 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,HevcBasicFeature)796 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, HevcBasicFeature)
797 {
798     params.frameStatisticsStreamOut              = m_hevcPicParams->StatusReportEnable.fields.FrameStats;
799     params.bitDepthMinus8                        = m_hevcSeqParams->bit_depth_luma_minus8;
800     params.chromaType                            = m_hevcSeqParams->chroma_format_idc;
801     params.wirelessSessionId                     = 0;
802     params.randomAccess                          = !m_ref.IsLowDelay();
803     params.bt2020RGB2YUV                         = m_hevcSeqParams->InputColorSpace == ECOLORSPACE_P2020;
804     params.rgbInputStudioRange                   = params.bt2020RGB2YUV ? m_hevcSeqParams->RGBInputStudioRange : 0;
805     params.convertedYUVStudioRange               = params.bt2020RGB2YUV ? m_hevcSeqParams->ConvertedYUVStudioRange : 0;
806 
807     if (m_captureModeEnable)
808     {
809         params.captureMode              = 1;
810         params.tailPointerReadFrequency = 0x50;
811     }
812 
813     if (m_hevcSeqParams->EnableStreamingBufferLLC || m_hevcSeqParams->EnableStreamingBufferDDR)
814     {
815         params.streamingBufferConfig = 1;
816         params.captureMode           = 2;
817     }
818 
819     return MOS_STATUS_SUCCESS;
820 }
821 
MHW_SETPAR_DECL_SRC(VDENC_SRC_SURFACE_STATE,HevcBasicFeature)822 MHW_SETPAR_DECL_SRC(VDENC_SRC_SURFACE_STATE, HevcBasicFeature)
823 {
824     params.pitch                = m_rawSurfaceToPak->dwPitch;
825     params.tileType             = m_rawSurfaceToPak->TileType;
826     params.tileModeGmm          = m_rawSurfaceToPak->TileModeGMM;
827     params.format               = m_rawSurfaceToPak->Format;
828     params.gmmTileEn            = m_rawSurfaceToPak->bGMMTileEnabled;
829     params.uOffset              = m_rawSurfaceToPak->YoffsetForUplane;
830     params.vOffset              = m_rawSurfaceToPak->YoffsetForVplane;
831     params.displayFormatSwizzle = m_hevcPicParams->bDisplayFormatSwizzle;
832     params.height               = ((m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3));
833     params.width                = ((m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3));
834     params.colorSpaceSelection  = (m_hevcSeqParams->InputColorSpace == ECOLORSPACE_P709) ? 1 : 0;
835     params.chromaDownsampleFilterControl = 7;
836     return MOS_STATUS_SUCCESS;
837 }
838 
GetHwTileType(MOS_TILE_TYPE tileType,MOS_TILE_MODE_GMM tileModeGMM,bool gmmTileEnabled)839 static inline uint32_t GetHwTileType(MOS_TILE_TYPE tileType, MOS_TILE_MODE_GMM tileModeGMM, bool gmmTileEnabled)
840 {
841     uint32_t tileMode = 0;
842 
843     if (gmmTileEnabled)
844     {
845         return tileModeGMM;
846     }
847 
848     switch (tileType)
849     {
850     case MOS_TILE_LINEAR:
851         tileMode = 0;
852         break;
853     case MOS_TILE_YS:
854         tileMode = 1;
855         break;
856     case MOS_TILE_X:
857         tileMode = 2;
858         break;
859     default:
860         tileMode = 3;
861         break;
862     }
863 
864     return tileMode;
865 }
866 
MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE,HevcBasicFeature)867 MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE, HevcBasicFeature)
868 {
869     params.pitch       = m_reconSurface.dwPitch;
870     params.tileType    = m_reconSurface.TileType;
871     params.tileModeGmm = m_reconSurface.TileModeGMM;
872     params.format      = m_reconSurface.Format;
873     params.gmmTileEn   = m_reconSurface.bGMMTileEnabled;
874     params.uOffset     = m_reconSurface.YoffsetForUplane;
875     params.vOffset     = m_reconSurface.YoffsetForVplane;
876     params.height      = ((m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3));
877     params.width       = ((m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3));
878     uint32_t tileMode   = GetHwTileType(params.tileType, params.tileModeGmm, params.gmmTileEn);
879 
880     if (m_reconSurface.Format == Format_Y410 || m_reconSurface.Format == Format_444P || m_reconSurface.Format == Format_AYUV)
881     {
882         if (m_reconSurface.Format == Format_Y410)
883         {
884             params.pitch = m_reconSurface.dwPitch / 2;
885         }
886         else
887         {
888             params.pitch = m_reconSurface.dwPitch / 4;
889         }
890         params.uOffset = m_rawSurfaceToPak->dwHeight;
891         params.vOffset = m_rawSurfaceToPak->dwHeight << 1;
892     }
893     else if (m_reconSurface.Format == Format_Y216 || m_reconSurface.Format == Format_YUY2 || m_reconSurface.Format == Format_YUYV)
894     {
895         params.uOffset = m_rawSurfaceToPak->dwHeight;
896         params.vOffset = m_rawSurfaceToPak->dwHeight;
897     }
898 
899     return MOS_STATUS_SUCCESS;
900 }
901 
MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE,HevcBasicFeature)902 MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE, HevcBasicFeature)
903 {
904     params.pitchStage1       = m_8xDSSurface->dwPitch;
905     params.tileTypeStage1    = m_8xDSSurface->TileType;
906     params.tileModeGmmStage1 = m_8xDSSurface->TileModeGMM;
907     params.gmmTileEnStage1   = m_8xDSSurface->bGMMTileEnabled;
908     params.uOffsetStage1     = m_8xDSSurface->YoffsetForUplane;
909     params.vOffsetStage1     = m_8xDSSurface->YoffsetForVplane;
910     params.heightStage1      = m_8xDSSurface->dwHeight;
911     params.widthStage1       = m_8xDSSurface->dwWidth;
912 
913     params.pitchStage2       = m_4xDSSurface->dwPitch;
914     params.tileTypeStage2    = m_4xDSSurface->TileType;
915     params.tileModeGmmStage2 = m_4xDSSurface->TileModeGMM;
916     params.gmmTileEnStage2   = m_4xDSSurface->bGMMTileEnabled;
917     params.uOffsetStage2     = m_4xDSSurface->YoffsetForUplane;
918     params.vOffsetStage2     = m_4xDSSurface->YoffsetForVplane;
919     params.heightStage2      = m_4xDSSurface->dwHeight;
920     params.widthStage2       = m_4xDSSurface->dwWidth;
921 
922     return MOS_STATUS_SUCCESS;
923 }
924 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,HevcBasicFeature)925 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, HevcBasicFeature)
926 {
927 #ifdef _MMC_SUPPORTED
928     ENCODE_CHK_NULL_RETURN(m_mmcState);
929     if (m_mmcState->IsMmcEnabled())
930     {
931         params.mmcEnabled = true;
932         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(const_cast<PMOS_SURFACE>(&m_rawSurface), &params.mmcStateRaw));
933         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcFormat(const_cast<PMOS_SURFACE>(&m_rawSurface), &params.compressionFormatRaw));
934     }
935     else
936     {
937         params.mmcEnabled           = false;
938         params.mmcStateRaw          = MOS_MEMCOMP_DISABLED;
939         params.compressionFormatRaw = 0;
940     }
941 #endif
942 
943     params.surfaceRaw               = m_rawSurfaceToPak;
944     params.surfaceDsStage1          = m_8xDSSurface;
945     params.surfaceDsStage2          = m_4xDSSurface;
946     params.pakObjCmdStreamOutBuffer = m_resMbCodeBuffer;
947     params.streamOutBuffer          = m_recycleBuf->GetBuffer(VdencStatsBuffer, 0);
948     params.streamOutOffset          = 0;
949 
950     params.numActiveRefL0           = m_hevcSliceParams->num_ref_idx_l0_active_minus1 + 1;
951     params.numActiveRefL1           = m_hevcSliceParams->num_ref_idx_l1_active_minus1 + 1;
952     if (m_hevcPicParams->CodingType == I_TYPE)
953     {
954         params.numActiveRefL0 = 0;
955         params.numActiveRefL1 = 0;
956     }
957 
958     if (m_hevcPicParams->CodingType == P_TYPE)
959     {
960         params.isPFrame = true;
961     }
962 
963     //make m_ref and m_streamIn a feature
964     m_ref.MHW_SETPAR_F(VDENC_PIPE_BUF_ADDR_STATE)(params);
965 
966     auto waTable = m_osInterface->pfnGetWaTable(m_osInterface);
967     ENCODE_CHK_NULL_RETURN(waTable);
968 
969     if (MEDIA_IS_WA(waTable, Wa_22011549751) &&
970         m_hevcPicParams->CodingType == I_TYPE &&
971         !m_osInterface->bSimIsActive &&
972         !Mos_Solo_Extension((MOS_CONTEXT_HANDLE)m_osInterface->pOsContext) &&
973         !m_hevcPicParams->pps_curr_pic_ref_enabled_flag)
974     {
975         params.numActiveRefL0  = 1;
976         params.numActiveRefL1  = 1;
977         params.refsDsStage1[0] = &m_8xDSSurface->OsResource;
978         params.refsDsStage2[0] = &m_4xDSSurface->OsResource;
979     }
980 
981     return MOS_STATUS_SUCCESS;
982 }
983 
MHW_SETPAR_DECL_SRC(VDENC_CMD1,HevcBasicFeature)984 MHW_SETPAR_DECL_SRC(VDENC_CMD1, HevcBasicFeature)
985 {
986     auto settings = static_cast<HevcVdencFeatureSettings *>(m_constSettings);
987     ENCODE_CHK_NULL_RETURN(settings);
988 
989     for (const auto &lambda : settings->vdencCmd1Settings)
990     {
991         ENCODE_CHK_STATUS_RETURN(lambda(params, m_ref.IsLowDelay()));
992     }
993 
994     return MOS_STATUS_SUCCESS;
995 }
996 
MHW_SETPAR_DECL_SRC(VDENC_CMD2,HevcBasicFeature)997 MHW_SETPAR_DECL_SRC(VDENC_CMD2, HevcBasicFeature)
998 {
999     params.width  = (m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3);
1000     params.height = (m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3);
1001 
1002     params.pictureType                      = (m_hevcPicParams->CodingType == I_TYPE) ? 0 : ((m_hevcPicParams->CodingType == P_TYPE || m_ref.IsLowDelay()) ? 3 : 2);
1003     params.temporalMvp                      = (m_hevcPicParams->CodingType == I_TYPE || m_hevcPicParams->CodingType == P_TYPE) ? 0 : m_hevcSliceParams->slice_temporal_mvp_enable_flag;
1004     params.temporalMvEnableForIntegerSearch = m_ref.IsLowDelay() ? params.temporalMvp : 0;
1005 
1006     if (m_hevcPicParams->CodingType != I_TYPE)
1007     {
1008         params.numRefL0 = m_hevcSliceParams->num_ref_idx_l0_active_minus1 + 1;
1009         params.numRefL1 = m_hevcSliceParams->num_ref_idx_l1_active_minus1 + 1;
1010     }
1011 
1012     params.tiling = m_hevcPicParams->tiles_enabled_flag;
1013 
1014     if (m_hevcPicParams->CodingType != I_TYPE)
1015     {
1016         uint8_t refFrameId;
1017         int8_t  diffPoc;
1018 
1019         refFrameId                        = m_hevcSliceParams->RefPicList[0][0].FrameIdx;
1020         diffPoc                           = ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : m_hevcPicParams->RefFramePOCList[refFrameId]) - m_hevcPicParams->CurrPicOrderCnt;
1021         params.pocL0Ref0                 = (int8_t)CodecHal_Clip3(-16, 16, -diffPoc);
1022         params.longTermReferenceFlagsL0  = (refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : CodecHal_PictureIsLongTermRef(m_hevcPicParams->RefFrameList[refFrameId]);
1023         refFrameId                        = m_hevcSliceParams->RefPicList[0][1].FrameIdx;
1024         diffPoc                           = ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : m_hevcPicParams->RefFramePOCList[refFrameId]) - m_hevcPicParams->CurrPicOrderCnt;
1025         params.pocL0Ref1                 = (int8_t)CodecHal_Clip3(-16, 16, -diffPoc);
1026         params.longTermReferenceFlagsL0 |= ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : CodecHal_PictureIsLongTermRef(m_hevcPicParams->RefFrameList[refFrameId])) << 1;
1027         refFrameId                        = m_hevcSliceParams->RefPicList[0][2].FrameIdx;
1028         diffPoc                           = ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : m_hevcPicParams->RefFramePOCList[refFrameId]) - m_hevcPicParams->CurrPicOrderCnt;
1029         params.pocL0Ref2                 = (int8_t)CodecHal_Clip3(-16, 16, -diffPoc);
1030         params.longTermReferenceFlagsL0 |= ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : CodecHal_PictureIsLongTermRef(m_hevcPicParams->RefFrameList[refFrameId])) << 2;
1031 
1032         refFrameId                        = m_hevcSliceParams->RefPicList[1][0].FrameIdx;
1033         diffPoc                           = ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : m_hevcPicParams->RefFramePOCList[refFrameId]) - m_hevcPicParams->CurrPicOrderCnt;
1034         params.pocL1Ref0                 = (int8_t)CodecHal_Clip3(-16, 16, -diffPoc);
1035         params.longTermReferenceFlagsL1  = (refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : CodecHal_PictureIsLongTermRef(m_hevcPicParams->RefFrameList[refFrameId]);
1036 
1037         params.pocL1Ref1 = params.pocL0Ref1;
1038         params.pocL1Ref2 = params.pocL0Ref2;
1039     }
1040     else
1041     {
1042         params.pocL0Ref0 = params.pocL0Ref1 = params.pocL1Ref0 = params.pocL1Ref1 = 0;
1043         params.pocL0Ref2 = params.pocL0Ref3 = params.pocL1Ref2 = params.pocL1Ref3 = 0;
1044     }
1045 
1046     if ((m_hevcPicParams->bEnableRollingIntraRefresh) && (m_hevcPicParams->CodingType != I_TYPE))
1047     {
1048         uint32_t rollingILimit = (m_hevcPicParams->bEnableRollingIntraRefresh == ROLLING_I_ROW) ? MOS_ROUNDUP_DIVIDE(params.height, 32) : MOS_ROUNDUP_DIVIDE(params.width, 32);
1049 
1050         params.intraRefresh                = 1;
1051         params.qpAdjustmentForRollingI     = MOS_CLAMP_MIN_MAX(m_hevcPicParams->QpDeltaForInsertedIntra, -8, 7);
1052         params.intraRefreshMode            = (m_hevcPicParams->bEnableRollingIntraRefresh == ROLLING_I_ROW) ? 0 : 1;
1053         params.intraRefreshMbSizeMinus1    = m_hevcPicParams->IntraInsertionSize - 1;
1054         params.intraRefreshPos            = m_hevcPicParams->IntraInsertionLocation;
1055         params.intraRefreshBoundary[0]     = CodecHal_Clip3(0, rollingILimit, m_hevcPicParams->RollingIntraReferenceLocation[0] - 1);
1056         params.intraRefreshBoundary[1]     = CodecHal_Clip3(0, rollingILimit, m_hevcPicParams->RollingIntraReferenceLocation[1] - 1);
1057         params.intraRefreshBoundary[2]     = CodecHal_Clip3(0, rollingILimit, m_hevcPicParams->RollingIntraReferenceLocation[2] - 1);
1058     }
1059     else
1060     {
1061         params.intraRefreshMbSizeMinus1 = 0;
1062     }
1063 
1064     params.qpPrimeYAc = m_hevcPicParams->QpY + m_hevcSliceParams->slice_qp_delta;
1065 
1066     // For IBC
1067     if (m_hevcPicParams->pps_curr_pic_ref_enabled_flag)
1068     {
1069         params.numRefL0++;
1070 
1071         if (m_hevcPicParams->CodingType == I_TYPE)
1072         {
1073             params.numRefL0                  = 0;
1074             params.pocL0Ref0                 = 0;
1075             params.longTermReferenceFlagsL0  = 1;
1076         }
1077         else
1078         {
1079             // For LDB here
1080             switch (params.numRefL0 - 1)
1081             {
1082             case 0:
1083                 params.pocL0Ref0 = 0;
1084                 params.longTermReferenceFlagsL0 |= 1;
1085                 break;
1086             case 1:
1087                 params.pocL0Ref1 = 0;
1088                 params.longTermReferenceFlagsL0 |= 2;
1089                 break;
1090             case 2:
1091                 params.pocL0Ref2 = 0;
1092                 params.longTermReferenceFlagsL0 |= 4;
1093                 break;
1094             case 3:
1095                 params.pocL0Ref3 = 0;
1096                 params.longTermReferenceFlagsL0 |= 0;
1097                 break;
1098             default:
1099                 MHW_ASSERTMESSAGE("Invalid NumRefIdxL0");
1100                 return MOS_STATUS_INVALID_PARAMETER;
1101             }
1102         }
1103     }
1104 
1105     uint8_t frameIdxForL0L1[4] = {0x7, 0x7, 0x7, 0x7};
1106 
1107     MHW_MI_CHK_NULL(m_ref.GetRefIdxMapping());
1108     for (int i = 0; i < m_hevcSliceParams->num_ref_idx_l0_active_minus1 + 1 && i < 3; i++)
1109     {
1110         uint8_t refFrameIDx = m_hevcSliceParams->RefPicList[0][i].FrameIdx;
1111         if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC)
1112         {
1113             frameIdxForL0L1[i] = *(m_ref.GetRefIdxMapping() + refFrameIDx);
1114         }
1115     }
1116 
1117     if (!m_ref.IsLowDelay())
1118     {
1119         uint8_t refFrameIDx = m_hevcSliceParams->RefPicList[1][0].FrameIdx;
1120         if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC)
1121         {
1122             frameIdxForL0L1[3] = *(m_ref.GetRefIdxMapping() + refFrameIDx);
1123         }
1124     }
1125 
1126     params.frameIdxL0Ref0 = frameIdxForL0L1[0];
1127     params.frameIdxL0Ref1 = frameIdxForL0L1[1];
1128     params.frameIdxL0Ref2 = frameIdxForL0L1[2];
1129     params.frameIdxL1Ref0 = frameIdxForL0L1[3];
1130 
1131     params.minQp = m_hevcPicParams->BRCMinQp < 0x0a ? 0x0a : m_hevcPicParams->BRCMinQp;
1132     params.maxQp = m_hevcPicParams->BRCMaxQp < 0x0a ? 0x33 : (m_hevcPicParams->BRCMaxQp > 0x33 ? 0x33 : m_hevcPicParams->BRCMaxQp);
1133 
1134     auto waTable = m_osInterface->pfnGetWaTable(m_osInterface);
1135     ENCODE_CHK_NULL_RETURN(waTable);
1136 
1137     if (MEDIA_IS_WA(waTable, Wa_22011549751) &&
1138         m_hevcPicParams->CodingType == I_TYPE &&
1139         !m_osInterface->bSimIsActive &&
1140         !Mos_Solo_Extension((MOS_CONTEXT_HANDLE)m_osInterface->pOsContext) &&
1141         !m_hevcPicParams->pps_curr_pic_ref_enabled_flag)
1142     {
1143         params.pictureType = 3;
1144         params.frameIdxL0Ref0 = 0;
1145         params.frameIdxL1Ref0 = 0;
1146     }
1147 
1148     ENCODE_CHK_COND_RETURN(m_SubPelMode > 3, "Invalid subPelMode");
1149     params.subPelMode = m_bEnableSubPelMode ? m_SubPelMode : 3;
1150     auto settings = static_cast<HevcVdencFeatureSettings *>(m_constSettings);
1151     ENCODE_CHK_NULL_RETURN(settings);
1152 
1153     for (const auto &lambda : settings->vdencCmd2Settings)
1154     {
1155         ENCODE_CHK_STATUS_RETURN(lambda(params, m_ref.IsLowDelay()));
1156     }
1157 
1158     return MOS_STATUS_SUCCESS;
1159 }
1160 
MHW_SETPAR_DECL_SRC(HCP_PIC_STATE,HevcBasicFeature)1161 MHW_SETPAR_DECL_SRC(HCP_PIC_STATE, HevcBasicFeature)
1162 {
1163     params.framewidthinmincbminus1         = m_hevcSeqParams->wFrameWidthInMinCbMinus1;
1164     params.frameheightinmincbminus1        = m_hevcSeqParams->wFrameHeightInMinCbMinus1;
1165     params.mincusize                       = m_hevcSeqParams->log2_min_coding_block_size_minus3;
1166     params.ctbsizeLcusize                  = m_hevcSeqParams->log2_max_coding_block_size_minus3;
1167     params.maxtusize                       = m_hevcSeqParams->log2_max_transform_block_size_minus2;
1168     params.mintusize                       = m_hevcSeqParams->log2_min_transform_block_size_minus2;
1169     params.cuQpDeltaEnabledFlag            = m_hevcPicParams->cu_qp_delta_enabled_flag;  // In VDENC mode, this field should always be set to 1.
1170     params.diffCuQpDeltaDepth              = m_hevcPicParams->diff_cu_qp_delta_depth;
1171     params.pcmLoopFilterDisableFlag        = m_hevcSeqParams->pcm_loop_filter_disable_flag;
1172     params.weightedPredFlag                = m_hevcPicParams->weighted_pred_flag;
1173     params.weightedBipredFlag              = m_hevcPicParams->weighted_bipred_flag;
1174     params.ampEnabledFlag                  = m_hevcSeqParams->amp_enabled_flag;
1175     params.transquantBypassEnableFlag      = m_hevcPicParams->transquant_bypass_enabled_flag;
1176     params.strongIntraSmoothingEnableFlag  = m_hevcSeqParams->strong_intra_smoothing_enable_flag;
1177     params.picCbQpOffset                   = m_hevcPicParams->pps_cb_qp_offset & 0x1f;
1178     params.picCrQpOffset                   = m_hevcPicParams->pps_cr_qp_offset & 0x1f;
1179     params.maxTransformHierarchyDepthIntra = m_hevcSeqParams->max_transform_hierarchy_depth_intra;
1180     params.maxTransformHierarchyDepthInter = m_hevcSeqParams->max_transform_hierarchy_depth_inter;
1181     params.pcmSampleBitDepthChromaMinus1   = m_hevcSeqParams->pcm_sample_bit_depth_chroma_minus1;
1182     params.pcmSampleBitDepthLumaMinus1     = m_hevcSeqParams->pcm_sample_bit_depth_luma_minus1;
1183     params.bitDepthChromaMinus8            = m_hevcSeqParams->bit_depth_chroma_minus8;
1184     params.bitDepthLumaMinus8              = m_hevcSeqParams->bit_depth_luma_minus8;
1185     params.lcuMaxBitsizeAllowed            = m_hevcPicParams->LcuMaxBitsizeAllowed & 0xffff;
1186     params.lcuMaxBitSizeAllowedMsb2its     = (m_hevcPicParams->LcuMaxBitsizeAllowed & 0x00030000) >> 16;
1187     if (m_hevcSeqParams->SliceSizeControl == 1)
1188     {
1189         params.pakDynamicSliceModeEnable = 1;
1190         params.slicePicParameterSetId    = m_hevcPicParams->slice_pic_parameter_set_id;
1191         params.nalunittypeflag           = (m_hevcPicParams->nal_unit_type >= HEVC_NAL_UT_BLA_W_LP) && (m_hevcPicParams->nal_unit_type <= HEVC_NAL_UT_RSV_IRAP_VCL23);
1192         params.noOutputOfPriorPicsFlag   = m_hevcPicParams->no_output_of_prior_pics_flag;
1193         params.sliceSizeThresholdInBytes = m_hevcPicParams->MaxSliceSizeInBytes;
1194         params.targetSliceSizeInBytes    = m_hevcPicParams->MaxSliceSizeInBytes;
1195     }
1196     params.tilesEnabledFlag             = m_hevcPicParams->tiles_enabled_flag;
1197     params.chromaSubsampling            = m_hevcSeqParams->chroma_format_idc;
1198     params.loopFilterAcrossTilesEnabled = m_hevcPicParams->loop_filter_across_tiles_flag;
1199     params.partialFrameUpdateMode       = false;
1200     params.temporalMvPredDisable        = !m_hevcSeqParams->sps_temporal_mvp_enable_flag;
1201 
1202     if (m_hevcSeqParams->chroma_format_idc == 2)
1203     {
1204         params.sseEnable = false;
1205     }
1206     params.constrainedIntraPredFlag = m_hevcPicParams->constrained_intra_pred_flag;
1207 
1208     return MOS_STATUS_SUCCESS;
1209 }
1210 
MHW_SETPAR_DECL_SRC(HEVC_VP9_RDOQ_STATE,HevcBasicFeature)1211 MHW_SETPAR_DECL_SRC(HEVC_VP9_RDOQ_STATE, HevcBasicFeature)
1212 {
1213     uint8_t bitDepthLumaMinus8   = m_hevcSeqParams->bit_depth_luma_minus8;
1214     uint8_t bitDepthChromaMinus8 = m_hevcSeqParams->bit_depth_chroma_minus8;
1215     uint8_t codingType           = m_hevcPicParams->CodingType;
1216     auto    settings             = static_cast<HevcVdencFeatureSettings *>(m_constSettings);
1217 
1218     if (bitDepthLumaMinus8 < 8)
1219     {
1220         uint32_t sliceTypeIdx = (codingType == I_TYPE) ? 0 : 1;
1221 
1222         //Intra lambda
1223         MOS_ZeroMemory(params.lambdaTab, sizeof(params.lambdaTab));
1224         if (bitDepthLumaMinus8 == 0)
1225         {
1226             std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][0][0].begin(),
1227                 settings->rdoqLamdas8bits[sliceTypeIdx][0][0].end(),
1228                 std::begin(params.lambdaTab[0][0]));
1229 
1230             std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][0][1].begin(),
1231                 settings->rdoqLamdas8bits[sliceTypeIdx][0][1].end(),
1232                 std::begin(params.lambdaTab[0][1]));
1233 
1234             std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][1][0].begin(),
1235                 settings->rdoqLamdas8bits[sliceTypeIdx][1][0].end(),
1236                 std::begin(params.lambdaTab[1][0]));
1237 
1238             std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][1][1].begin(),
1239                 settings->rdoqLamdas8bits[sliceTypeIdx][1][1].end(),
1240                 std::begin(params.lambdaTab[1][1]));
1241         }
1242         else if (bitDepthLumaMinus8 == 2)
1243         {
1244             std::copy(settings->rdoqLamdas10bits[sliceTypeIdx][0][0].begin(),
1245                 settings->rdoqLamdas10bits[sliceTypeIdx][0][0].end(),
1246                 std::begin(params.lambdaTab[0][0]));
1247 
1248             std::copy(settings->rdoqLamdas10bits[sliceTypeIdx][0][1].begin(),
1249                 settings->rdoqLamdas10bits[sliceTypeIdx][0][1].end(),
1250                 std::begin(params.lambdaTab[0][1]));
1251 
1252             std::copy(settings->rdoqLamdas10bits[sliceTypeIdx][1][0].begin(),
1253                 settings->rdoqLamdas10bits[sliceTypeIdx][1][0].end(),
1254                 std::begin(params.lambdaTab[1][0]));
1255 
1256             std::copy(settings->rdoqLamdas10bits[sliceTypeIdx][1][1].begin(),
1257                 settings->rdoqLamdas10bits[sliceTypeIdx][1][1].end(),
1258                 std::begin(params.lambdaTab[1][1]));
1259         }
1260         else if (bitDepthLumaMinus8 == 4)
1261         {
1262             std::copy(settings->rdoqLamdas12bits[sliceTypeIdx][0][0].begin(),
1263                 settings->rdoqLamdas12bits[sliceTypeIdx][0][0].end(),
1264                 std::begin(params.lambdaTab[0][0]));
1265 
1266             std::copy(settings->rdoqLamdas12bits[sliceTypeIdx][0][1].begin(),
1267                 settings->rdoqLamdas12bits[sliceTypeIdx][0][1].end(),
1268                 std::begin(params.lambdaTab[0][1]));
1269 
1270             std::copy(settings->rdoqLamdas12bits[sliceTypeIdx][1][0].begin(),
1271                 settings->rdoqLamdas12bits[sliceTypeIdx][1][0].end(),
1272                 std::begin(params.lambdaTab[1][0]));
1273 
1274             std::copy(settings->rdoqLamdas12bits[sliceTypeIdx][1][1].begin(),
1275                 settings->rdoqLamdas12bits[sliceTypeIdx][1][1].end(),
1276                 std::begin(params.lambdaTab[1][1]));
1277         }
1278     }
1279     else
1280     {
1281         int32_t shiftQP = 12;
1282 #if INTRACONF
1283         double lambdaScale = 1.8;  //Intra
1284 #else
1285         double lambdaScale = 1.0 - 0.35;  //LD or RA
1286 #endif
1287         double   qpTemp       = 0;
1288         double   lambdaDouble = 0;
1289         uint32_t lambda       = 0;
1290         double   qpFactor     = 0.55;
1291 
1292         MOS_ZeroMemory(params.lambdaTab, sizeof(params.lambdaTab));
1293 
1294         int32_t bitdepthLumaQpScaleLuma   = 6 * bitDepthLumaMinus8;
1295         int32_t bitdepthLumaQpScaleChroma = 6 * bitDepthChromaMinus8;
1296 
1297         //Intra lambda
1298         qpFactor = 0.25 * lambdaScale;
1299         for (uint8_t qp = 0; qp < 52 + bitdepthLumaQpScaleLuma; qp++)
1300         {
1301             qpTemp              = (double)qp - bitdepthLumaQpScaleLuma - shiftQP;
1302             lambdaDouble        = qpFactor * pow(2.0, qpTemp / 3.0);
1303             lambdaDouble        = lambdaDouble * 16 + 0.5;
1304             lambdaDouble        = (lambdaDouble > 65535) ? 65535 : lambdaDouble;
1305             lambda              = (uint32_t)floor(lambdaDouble);
1306             params.lambdaTab[0][0][qp] = (uint16_t)lambda;
1307         }
1308         for (uint8_t qp = 0; qp < 52 + bitdepthLumaQpScaleChroma; qp++)
1309         {
1310             qpTemp              = (double)qp - bitdepthLumaQpScaleChroma - shiftQP;
1311             lambdaDouble        = qpFactor * pow(2.0, qpTemp / 3.0);
1312             lambdaDouble        = lambdaDouble * 16 + 0.5;
1313             lambdaDouble        = (lambdaDouble > 65535) ? 65535 : lambdaDouble;
1314             lambda              = (uint32_t)floor(lambdaDouble);
1315             params.lambdaTab[0][1][qp] = (uint16_t)lambda;
1316         }
1317 
1318         ////Inter lambda
1319         qpFactor = 0.55;
1320         for (uint8_t qp = 0; qp < 52 + bitdepthLumaQpScaleLuma; qp++)
1321         {
1322             qpTemp       = (double)qp - bitdepthLumaQpScaleLuma - shiftQP;
1323             lambdaDouble = qpFactor * pow(2.0, qpTemp / 3.0);
1324             lambdaDouble *= MOS_MAX(1.00, MOS_MIN(1.6, 1.0 + 0.6 / 12.0 * (qpTemp - 10.0)));
1325             lambdaDouble        = lambdaDouble * 16 + 0.5;
1326             lambda              = (uint32_t)floor(lambdaDouble);
1327             lambda              = CodecHal_Clip3(0, 0xffff, lambda);
1328             params.lambdaTab[1][0][qp] = (uint16_t)lambda;
1329         }
1330         for (uint8_t qp = 0; qp < 52 + bitdepthLumaQpScaleChroma; qp++)
1331         {
1332             qpTemp       = (double)qp - bitdepthLumaQpScaleChroma - shiftQP;
1333             lambdaDouble = qpFactor * pow(2.0, qpTemp / 3.0);
1334             lambdaDouble *= MOS_MAX(0.95, MOS_MIN(1.20, 0.25 / 12.0 * (qpTemp - 10.0) + 0.95));
1335             lambdaDouble        = lambdaDouble * 16 + 0.5;
1336             lambda              = (uint32_t)floor(lambdaDouble);
1337             lambda              = CodecHal_Clip3(0, 0xffff, lambda);
1338             params.lambdaTab[1][1][qp] = (uint16_t)lambda;
1339         }
1340     }
1341 
1342     if (m_hevcRDOQPerfDisabled)
1343     {
1344         params.disableHtqPerformanceFix0 = true;
1345         params.disableHtqPerformanceFix1 = true;
1346     }
1347     return MOS_STATUS_SUCCESS;
1348 }
1349 
MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE,HevcBasicFeature)1350 MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE, HevcBasicFeature)
1351 {
1352     PMOS_SURFACE psSurface            = nullptr;
1353     uint8_t      ucBitDepthLumaMinus8 = 0;
1354     uint8_t      chromaType           = 0;
1355     uint32_t     reconSurfHeight      = 0;
1356 
1357     ucBitDepthLumaMinus8 = m_hevcSeqParams->bit_depth_luma_minus8;
1358     chromaType           = m_outputChromaFormat;
1359     switch (params.surfaceStateId)
1360     {
1361     case CODECHAL_HCP_SRC_SURFACE_ID:
1362         psSurface = m_rawSurfaceToPak;
1363         break;
1364     case CODECHAL_HCP_DECODED_SURFACE_ID:
1365         psSurface                 = const_cast<PMOS_SURFACE>(&m_reconSurface);
1366         reconSurfHeight = m_rawSurfaceToPak->dwHeight;
1367         break;
1368     case CODECHAL_HCP_REF_SURFACE_ID:
1369         psSurface                 = const_cast<PMOS_SURFACE>(&m_reconSurface);
1370         reconSurfHeight = m_rawSurfaceToPak->dwHeight;
1371         break;
1372     }
1373 #ifdef _MMC_SUPPORTED
1374     GetSurfaceMmcInfo(psSurface, params.mmcState, params.dwCompressionFormat);
1375     if (params.surfaceStateId == CODECHAL_HCP_REF_SURFACE_ID)
1376     {
1377         m_ref.MHW_SETPAR_F(HCP_SURFACE_STATE)(params);
1378     }
1379 #endif
1380 
1381     ENCODE_CHK_NULL_RETURN(psSurface);
1382     params.surfacePitchMinus1 = psSurface->dwPitch - 1;
1383 
1384     /* Handling of reconstructed surface is different for Y410 & AYUV formats */
1385     if ((params.surfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) &&
1386         (psSurface->Format == Format_Y410))
1387         params.surfacePitchMinus1 = psSurface->dwPitch / 2 - 1;
1388 
1389     if ((params.surfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) &&
1390         (psSurface->Format == Format_AYUV))
1391         params.surfacePitchMinus1 = psSurface->dwPitch / 4 - 1;
1392 
1393     bool surf10bit = (psSurface->Format == Format_P010) ||
1394                      (psSurface->Format == Format_P210) ||
1395                      (psSurface->Format == Format_Y210) ||
1396                      (psSurface->Format == Format_Y410) ||
1397                      (psSurface->Format == Format_R10G10B10A2) ||
1398                      (psSurface->Format == Format_B10G10R10A2) ||
1399                      (psSurface->Format == Format_P016) ||
1400                      (psSurface->Format == Format_Y216);
1401 
1402     if (chromaType == HCP_CHROMA_FORMAT_YUV422)
1403     {
1404         if (ucBitDepthLumaMinus8 > 0)
1405         {
1406             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1407             {
1408                 params.surfaceFormat = surf10bit ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216Y210FORMAT : hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2FORMAT;
1409             }
1410             else
1411             {
1412                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216VARIANT;
1413             }
1414         }
1415         else
1416         {
1417             params.surfaceFormat = (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID) ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2FORMAT : hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2VARIANT;
1418         }
1419     }
1420     else if (chromaType == HCP_CHROMA_FORMAT_YUV444)
1421     {
1422         if (ucBitDepthLumaMinus8 == 0)
1423         {
1424             params.surfaceFormat = params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444FORMAT : hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444VARIANT;
1425         }
1426         else if (ucBitDepthLumaMinus8 <= 2)
1427         {
1428             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1429             {
1430                 params.surfaceFormat = surf10bit ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y410FORMAT : hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444FORMAT;
1431             }
1432             else
1433             {
1434                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416VARIANT;
1435             }
1436         }
1437         else
1438         {
1439             params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416FORMAT;
1440         }
1441     }
1442     else  //chromaType == HCP_CHROMA_FORMAT_YUV420
1443     {
1444         if (ucBitDepthLumaMinus8 > 0)
1445         {
1446             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1447             {
1448                 params.surfaceFormat = surf10bit ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_P010 : hcp::SURFACE_FORMAT::SURFACE_FORMAT_PLANAR4208;
1449             }
1450             else
1451             {
1452                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_P010VARIANT;
1453             }
1454         }
1455         else
1456         {
1457             params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_PLANAR4208;
1458         }
1459     }
1460 
1461     params.yOffsetForUCbInPixel = params.yOffsetForVCr =
1462         (uint16_t)((psSurface->UPlaneOffset.iSurfaceOffset - psSurface->dwOffset) / psSurface->dwPitch + psSurface->RenderOffset.YUV.U.YOffset);
1463 
1464     //Set U/V offsets for Variant surfaces
1465     if (params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416VARIANT ||
1466         params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444VARIANT)
1467     {
1468         params.yOffsetForUCbInPixel = (uint16_t)reconSurfHeight;
1469         params.yOffsetForVCr        = (uint16_t)reconSurfHeight << 1;
1470     }
1471     else if (params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216VARIANT ||
1472              params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2VARIANT)
1473     {
1474         params.yOffsetForUCbInPixel = params.yOffsetForVCr = (uint16_t)reconSurfHeight;
1475     }
1476 
1477     return MOS_STATUS_SUCCESS;
1478 }
1479 
MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE,HevcBasicFeature)1480 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE, HevcBasicFeature)
1481 {
1482     ENCODE_CHK_NULL_RETURN(m_hevcSliceParams);
1483     PCODEC_HEVC_ENCODE_SLICE_PARAMS pEncodeHevcSliceParams = (CODEC_HEVC_ENCODE_SLICE_PARAMS *) &m_hevcSliceParams[m_curNumSlices];
1484     uint32_t ctbSize    = 1 << (m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3);
1485     uint32_t widthInPix = (1 << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3)) *
1486                           (m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1);
1487     uint32_t widthInCtb = (widthInPix / ctbSize) +
1488                           ((widthInPix % ctbSize) ? 1 : 0);  // round up
1489 
1490     uint32_t ctbAddr = pEncodeHevcSliceParams->slice_segment_address;
1491 
1492     params.slicestartctbxOrSliceStartLcuXEncoder = ctbAddr % widthInCtb;
1493     params.slicestartctbyOrSliceStartLcuYEncoder = ctbAddr / widthInCtb;
1494 
1495     if (m_curNumSlices == m_numSlices - 1)
1496     {
1497         params.nextslicestartctbxOrNextSliceStartLcuXEncoder   = 0;
1498         params.nextslicestartctbyOrNextSliceStartLcuYEncoder  = 0;
1499     }
1500     else
1501     {
1502         if (m_hevcPicParams->tiles_enabled_flag)
1503         {
1504             params.nextslicestartctbxOrNextSliceStartLcuXEncoder = pEncodeHevcSliceParams[1].slice_segment_address % widthInCtb;
1505             params.nextslicestartctbyOrNextSliceStartLcuYEncoder = pEncodeHevcSliceParams[1].slice_segment_address / widthInCtb;
1506         }
1507         else
1508         {
1509             ctbAddr                                               = pEncodeHevcSliceParams->slice_segment_address + pEncodeHevcSliceParams->NumLCUsInSlice;
1510             params.nextslicestartctbxOrNextSliceStartLcuXEncoder = ctbAddr % widthInCtb;
1511             params.nextslicestartctbyOrNextSliceStartLcuYEncoder = ctbAddr / widthInCtb;
1512         }
1513     }
1514     params.sliceType = pEncodeHevcSliceParams->slice_type;
1515     params.lastsliceofpic = (m_curNumSlices == m_numSlices - 1);
1516     params.sliceqpSignFlag = ((pEncodeHevcSliceParams->slice_qp_delta + m_hevcPicParams->QpY) >= 0) ? 0 : 1;
1517     params.dependentSliceFlag = false;
1518     params.sliceTemporalMvpEnableFlag = pEncodeHevcSliceParams->slice_temporal_mvp_enable_flag;
1519     if (m_hevcPicParams->CodingType == I_TYPE)
1520     {
1521         params.sliceTemporalMvpEnableFlag = 0;
1522     }
1523     params.sliceqp = (uint8_t)abs(pEncodeHevcSliceParams->slice_qp_delta + m_hevcPicParams->QpY);
1524     params.sliceCbQpOffset = pEncodeHevcSliceParams->slice_cb_qp_offset;
1525     params.sliceCrQpOffset = pEncodeHevcSliceParams->slice_cr_qp_offset;
1526 
1527     params.loopFilterAcrossSlicesEnabled = m_hevcPicParams->loop_filter_across_slices_flag;
1528     params.mvdL1ZeroFlag                 = 0;
1529     params.isLowDelay                    = m_ref.IsLowDelay();
1530 
1531     params.collocatedFromL0Flag = pEncodeHevcSliceParams->collocated_from_l0_flag;
1532     params.chromalog2Weightdenom = (m_hevcPicParams->weighted_pred_flag || m_hevcPicParams->weighted_bipred_flag) ? (m_hevcPicParams->bEnableGPUWeightedPrediction ? 6 : pEncodeHevcSliceParams->luma_log2_weight_denom + pEncodeHevcSliceParams->delta_chroma_log2_weight_denom) : 0;
1533     params.lumaLog2WeightDenom   = (m_hevcPicParams->weighted_pred_flag || m_hevcPicParams->weighted_bipred_flag) ? (m_hevcPicParams->bEnableGPUWeightedPrediction ? 6 : pEncodeHevcSliceParams->luma_log2_weight_denom) : 0;
1534 
1535     params.cabacInitFlag = pEncodeHevcSliceParams->cabac_init_flag;
1536     params.maxmergeidx   = pEncodeHevcSliceParams->MaxNumMergeCand - 1;
1537 
1538     if (params.sliceTemporalMvpEnableFlag)
1539     {
1540         if (params.sliceType == 2)
1541         {
1542             params.collocatedrefidx = 0;
1543         }
1544         else
1545         {
1546             // need to check with Ce for DDI issues
1547             uint8_t collocatedFromL0Flag = params.collocatedFromL0Flag;
1548 
1549             uint8_t collocatedRefIndex = m_hevcPicParams->CollocatedRefPicIndex;
1550             MHW_ASSERT(collocatedRefIndex < CODEC_MAX_NUM_REF_FRAME_HEVC);
1551 
1552             const int8_t *pRefIdxMapping     = m_ref.GetRefIdxMapping();
1553             uint8_t       collocatedFrameIdx = pRefIdxMapping[collocatedRefIndex];
1554             MHW_ASSERT(collocatedRefIndex < CODEC_MAX_NUM_REF_FRAME_HEVC);
1555 
1556             params.collocatedrefidx = collocatedFrameIdx;
1557         }
1558     }
1559     else
1560     {
1561         params.collocatedrefidx = 0;
1562     }
1563 
1564     params.sliceheaderlength = 0;
1565 
1566     params.emulationbytesliceinsertenable = 1;
1567     params.slicedataEnable                = 1;
1568     params.headerInsertionEnable          = 1;
1569 
1570     if (m_useDefaultRoundingForHcpSliceState)
1571     {
1572         params.roundinter = m_roundingInter;
1573         params.roundintra = m_roundingIntra;
1574     }
1575     else
1576     {
1577         params.roundinter = 4;
1578         params.roundintra = 10;
1579     }
1580 
1581     return MOS_STATUS_SUCCESS;
1582 }
1583 
1584 }  // namespace encode
1585