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), ¶ms.mmcStateRaw));
933 ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcFormat(const_cast<PMOS_SURFACE>(&m_rawSurface), ¶ms.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