1 /*
2 * Copyright (c) 2017-2018, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file codechal_encode_hevc_base.cpp
24 //! \brief Defines base class for HEVC encoder.
25 //!
26
27 #include "codechal_encode_hevc_base.h"
28 #include "codechal_vdenc_hevc.h"
29 #include "codechal_encode_hevc.h"
30 #include "encode_hevc_header_packer.h"
31 #if USE_CODECHAL_DEBUG_TOOL
32 #include "codechal_debug.h"
33 #endif
34
35 const uint8_t CodechalEncodeHevcBase::TransformSkipCoeffsTable[4][2][2][2][2] =
36 {
37 { { { { 42, 37 },{ 32, 40 } },{ { 40, 40 },{ 32, 45 } } },{ { { 29, 48 },{ 26, 53 } },{ { 26, 56 },{ 24, 62 } } } },
38 { { { { 42, 40 },{ 32, 45 } },{ { 40, 46 },{ 32, 48 } } },{ { { 26, 53 },{ 24, 58 } },{ { 32, 53 },{ 26, 64 } } } },
39 { { { { 38, 42 },{ 32, 51 } },{ { 43, 43 },{ 35, 46 } } },{ { { 26, 56 },{ 24, 64 } },{ { 35, 50 },{ 32, 57 } } } },
40 { { { { 35, 46 },{ 32, 52 } },{ { 51, 42 },{ 38, 53 } } },{ { { 29, 56 },{ 29, 70 } },{ { 38, 47 },{ 37, 64 } } } },
41 };
42
43 const uint16_t CodechalEncodeHevcBase::TransformSkipLambdaTable[QP_NUM] =
44 {
45 149, 149, 149, 149, 149, 149, 149, 149,
46 149, 149, 149, 149, 149, 149, 149, 149,
47 149, 149, 149, 149, 149, 149, 149, 149,
48 149, 162, 174, 186, 199, 211, 224, 236,
49 249, 261, 273, 286, 298, 298, 298, 298,
50 298, 298, 298, 298, 298, 298, 298, 298,
51 298, 298, 298, 298
52 };
53
InitMmcState()54 MOS_STATUS CodechalEncodeHevcBase::InitMmcState()
55 {
56 #ifdef _MMC_SUPPORTED
57 m_mmcState = MOS_New(CodechalMmcEncodeHevc, m_hwInterface, this);
58 CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
59 #endif
60 return MOS_STATUS_SUCCESS;
61 }
62
Initialize(CodechalSetting * settings)63 MOS_STATUS CodechalEncodeHevcBase::Initialize(CodechalSetting * settings)
64 {
65 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
66
67 CODECHAL_ENCODE_FUNCTION_ENTER;
68
69 CODECHAL_ENCODE_CHK_NULL_RETURN(settings);
70
71 #ifndef _FULL_OPEN_SOURCE
72 // for HEVC: the Ds+Copy kernel is by default used to do CSC and copy non-aligned surface
73 CODECHAL_ENCODE_CHK_NULL_RETURN(m_cscDsState);
74 m_cscDsState->EnableCopy();
75 m_cscDsState->EnableColor();
76 #endif
77 m_mfeEnabled = settings->isMfeEnabled;
78
79 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::Initialize(settings));
80
81 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMmcState());
82
83 m_is10BitHevc = (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_10_BITS) ? true : false;
84 m_chromaFormat = settings->chromaFormat;
85 m_bitDepth = (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_8_BITS) ? 8 : ((settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_10_BITS) ? 10 : 12);
86 m_frameNum = 0;
87
88 const uint32_t picWidthInLCU = MOS_ROUNDUP_DIVIDE(m_frameWidth, CODECHAL_HEVC_MIN_LCU_SIZE); //assume smallest LCU to get max width
89 const uint32_t picHeightInLCU = MOS_ROUNDUP_DIVIDE(m_frameHeight, CODECHAL_HEVC_MIN_LCU_SIZE); //assume smallest LCU to get max height // MaxNumLcu is when LCU size is min lcu size(16)
90 const uint32_t maxNumLCUs = picWidthInLCU * picHeightInLCU;
91 m_mvOffset = MOS_ALIGN_CEIL((maxNumLCUs * (m_hcpInterface->GetHcpPakObjSize()) * sizeof(uint32_t)), CODECHAL_PAGE_SIZE);
92
93 // MaxNumCuRecords is when LCU size is max lcu size(64)
94 const uint32_t maxNumCuRecords = MOS_ROUNDUP_DIVIDE(m_frameWidth, MAX_LCU_SIZE) *
95 MOS_ROUNDUP_DIVIDE(m_frameHeight, MAX_LCU_SIZE) * 64;
96 m_mbCodeSize =
97 m_mvOffset + MOS_ALIGN_CEIL((maxNumCuRecords * m_hcpInterface->GetHevcEncCuRecordSize()), CODECHAL_PAGE_SIZE);
98
99 m_widthAlignedMaxLcu = MOS_ALIGN_CEIL(m_frameWidth, MAX_LCU_SIZE);
100 m_heightAlignedMaxLcu = MOS_ALIGN_CEIL(m_frameHeight, MAX_LCU_SIZE);
101
102 m_hevcBrcPakStatisticsSize = HEVC_BRC_PAK_STATISTCS_SIZE; // size for sturcture: CODECHAL_ENCODE_HEVC_PAK_STATS_BUFFER
103 m_sizeOfHcpPakFrameStats = 8 * CODECHAL_CACHELINE_SIZE;
104
105 // Initialize kernel State
106 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelState());
107
108 // Get max binding table count
109 m_maxBtCount = GetMaxBtCount();
110
111 // Picture Level Commands
112 CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculatePictureStateCommandSize());
113
114 // Slice Level Commands
115 CODECHAL_ENCODE_CHK_STATUS_RETURN(
116 m_hwInterface->GetHxxPrimitiveCommandSize(
117 CODECHAL_ENCODE_MODE_HEVC,
118 &m_defaultSliceStatesSize,
119 &m_defaultSlicePatchListSize,
120 m_singleTaskPhaseSupported));
121
122 #if (_DEBUG || _RELEASE_INTERNAL)
123 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
124 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
125 MOS_UserFeature_ReadValue_ID(
126 nullptr,
127 __MEDIA_USER_FEATURE_VALUE_HEVC_ENCODE_IFRAME_RDOQ_ENABLE_ID,
128 &userFeatureData,
129 m_osInterface->pOsContext);
130 m_hevcIFrameRdoqEnabled = userFeatureData.i32Data ? true : false;
131
132 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
133 MOS_UserFeature_ReadValue_ID(
134 nullptr,
135 __MEDIA_USER_FEATURE_VALUE_CODECHAL_RDOQ_INTRA_TU_OVERRIDE_ID,
136 &userFeatureData,
137 m_osInterface->pOsContext);
138 m_rdoqIntraTuOverride = (uint32_t)userFeatureData.u32Data;
139
140 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
141 MOS_UserFeature_ReadValue_ID(
142 nullptr,
143 __MEDIA_USER_FEATURE_VALUE_CODECHAL_RDOQ_INTRA_TU_DISABLE_ID,
144 &userFeatureData,
145 m_osInterface->pOsContext);
146 m_rdoqIntraTuDisableOverride = (uint32_t)userFeatureData.u32Data;
147
148 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
149 MOS_UserFeature_ReadValue_ID(
150 nullptr,
151 __MEDIA_USER_FEATURE_VALUE_CODECHAL_RDOQ_INTRA_TU_THRESHOLD_ID,
152 &userFeatureData,
153 m_osInterface->pOsContext);
154 m_rdoqIntraTuThresholdOverride = (uint32_t)userFeatureData.u32Data;
155 #endif
156 return eStatus;
157 }
158
AllocatePakResources()159 MOS_STATUS CodechalEncodeHevcBase::AllocatePakResources()
160 {
161 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
162
163 CODECHAL_ENCODE_FUNCTION_ENTER;
164
165 const uint32_t minLcuSize = 16;
166 const uint32_t picWidthInMinLCU = MOS_ROUNDUP_DIVIDE(m_frameWidth, minLcuSize); //assume smallest LCU to get max width
167 const uint32_t picHeightInMinLCU = MOS_ROUNDUP_DIVIDE(m_frameHeight, minLcuSize); //assume smallest LCU to get max height
168
169 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
170 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
171 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
172 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
173 allocParamsForBufferLinear.Format = Format_Buffer;
174
175 // Deblocking Filter Row Store Scratch data surface
176 const uint32_t formatDenom = 2;
177 uint32_t formatMultiFactor = m_chromaFormat == HCP_CHROMA_FORMAT_YUV444 ? 3 : 2;
178 formatMultiFactor *= m_is10BitHevc ? 2 : 1;
179
180 uint32_t size = ((m_frameWidth + 31) & 0xFFFFFFE0) >> 3;
181 size = MOS_ALIGN_CEIL(MOS_ROUNDUP_DIVIDE(size * formatMultiFactor, formatDenom), 4);
182 size *= CODECHAL_CACHELINE_SIZE;
183 allocParamsForBufferLinear.dwBytes = size;
184 allocParamsForBufferLinear.pBufName = "DeblockingScratchBuffer";
185
186 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
187 m_osInterface,
188 &allocParamsForBufferLinear,
189 &m_resDeblockingFilterRowStoreScratchBuffer);
190
191 if (eStatus != MOS_STATUS_SUCCESS)
192 {
193 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate Deblocking Filter Row Store Scratch Buffer.");
194 return eStatus;
195 }
196
197 // Deblocking Filter Tile Row Store Scratch data surface
198 allocParamsForBufferLinear.dwBytes = size;
199 allocParamsForBufferLinear.pBufName = "DeblockingTileScratchBuffer";
200
201 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
202 m_osInterface,
203 &allocParamsForBufferLinear,
204 &m_resDeblockingFilterTileRowStoreScratchBuffer);
205
206 if (eStatus != MOS_STATUS_SUCCESS)
207 {
208 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate Deblocking Filter Tile Row Store Scratch Buffer.");
209 return eStatus;
210 }
211
212 // Deblocking Filter Column Row Store Scratch data surface
213 size = ((m_frameHeight + picHeightInMinLCU * 6 + 31) & 0xFFFFFFE0) >> 3;
214 size = MOS_ALIGN_CEIL(MOS_ROUNDUP_DIVIDE(size * formatMultiFactor, formatDenom), 4);
215 size *= CODECHAL_CACHELINE_SIZE;
216 allocParamsForBufferLinear.dwBytes = size;
217 allocParamsForBufferLinear.pBufName = "DeblockingColumnScratchBuffer";
218
219 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
220 m_osInterface,
221 &allocParamsForBufferLinear,
222 &m_resDeblockingFilterColumnRowStoreScratchBuffer);
223
224 if (eStatus != MOS_STATUS_SUCCESS)
225 {
226 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate Deblocking Filter Column Row Store Scratch Buffer.");
227 return eStatus;
228 }
229
230 // Metadata Line buffer
231 size = MOS_MAX(
232 MOS_ALIGN_CEIL((m_frameWidth + picWidthInMinLCU * 8 + 1023) >> 9, 2) * CODECHAL_CACHELINE_SIZE, // intra-slice
233 MOS_ALIGN_CEIL((((m_frameWidth + 15) >> 4) * 188 + picWidthInMinLCU * 9 + 1023) >> 9, 2) * CODECHAL_CACHELINE_SIZE // inter-slice
234 );
235 allocParamsForBufferLinear.dwBytes = size;
236 allocParamsForBufferLinear.pBufName = "MetadataLineBuffer";
237
238 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
239 m_osInterface,
240 &allocParamsForBufferLinear,
241 &m_resMetadataLineBuffer);
242
243 if (eStatus != MOS_STATUS_SUCCESS)
244 {
245 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate Metadata Line Buffer.");
246 return eStatus;
247 }
248
249 // Metadata Tile Line buffer
250 size = MOS_MAX(
251 MOS_ALIGN_CEIL((m_frameWidth + picWidthInMinLCU * 8 + 1023) >> 9, 2) * CODECHAL_CACHELINE_SIZE, // intra-slice
252 MOS_ALIGN_CEIL((((m_frameWidth + 15) >> 4) * 172 + picWidthInMinLCU * 9 + 1023) >> 9, 2) * CODECHAL_CACHELINE_SIZE // inter-slice
253 );
254 allocParamsForBufferLinear.dwBytes = size;
255 allocParamsForBufferLinear.pBufName = "MetadataTileLineBuffer";
256
257 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
258 m_osInterface,
259 &allocParamsForBufferLinear,
260 &m_resMetadataTileLineBuffer);
261
262 if (eStatus != MOS_STATUS_SUCCESS)
263 {
264 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate Metadata Tile Line Buffer.");
265 return eStatus;
266 }
267
268 // Metadata Tile Column buffer
269 size = MOS_MAX(
270 MOS_ALIGN_CEIL((m_frameHeight + picHeightInMinLCU * 8 + 1023) >> 9, 2) * CODECHAL_CACHELINE_SIZE, // intra-slice
271 MOS_ALIGN_CEIL((((m_frameHeight + 15) >> 4) * 172 + picHeightInMinLCU * 9 + 1023) >> 9, 2) * CODECHAL_CACHELINE_SIZE // inter-slice
272 );
273 allocParamsForBufferLinear.dwBytes = size;
274 allocParamsForBufferLinear.pBufName = "MetadataTileColumnBuffer";
275
276 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
277 m_osInterface,
278 &allocParamsForBufferLinear,
279 &m_resMetadataTileColumnBuffer);
280
281 if (eStatus != MOS_STATUS_SUCCESS)
282 {
283 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate Metadata Tile Column Buffer.");
284 return eStatus;
285 }
286
287 MHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam;
288 MOS_ZeroMemory(&hcpBufSizeParam, sizeof(hcpBufSizeParam));
289 hcpBufSizeParam.ucMaxBitDepth = m_bitDepth;
290 hcpBufSizeParam.ucChromaFormat = m_chromaFormat;
291
292 hcpBufSizeParam.dwCtbLog2SizeY = 6; // assume Max LCU size
293 hcpBufSizeParam.dwPicWidth = MOS_ALIGN_CEIL(m_frameWidth, MAX_LCU_SIZE);
294 hcpBufSizeParam.dwPicHeight = MOS_ALIGN_CEIL(m_frameHeight, MAX_LCU_SIZE);
295 // SAO Line buffer
296 eStatus = (MOS_STATUS)m_hcpInterface->GetHevcBufferSize(
297 MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_LINE,
298 &hcpBufSizeParam);
299
300 if (eStatus != MOS_STATUS_SUCCESS)
301 {
302 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to get the size for SAO Line Buffer.");
303 return eStatus;
304 }
305
306 allocParamsForBufferLinear.dwBytes = hcpBufSizeParam.dwBufferSize;
307 allocParamsForBufferLinear.pBufName = "SaoLineBuffer";
308 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
309 m_osInterface,
310 &allocParamsForBufferLinear,
311 &m_resSaoLineBuffer);
312
313 if (eStatus != MOS_STATUS_SUCCESS)
314 {
315 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate SAO Line Buffer.");
316 return eStatus;
317 }
318
319 // SAO Tile Line buffer
320 eStatus = (MOS_STATUS)m_hcpInterface->GetHevcBufferSize(
321 MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_LINE,
322 &hcpBufSizeParam);
323
324 if (eStatus != MOS_STATUS_SUCCESS)
325 {
326 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to get the size for SAO Tile Line Buffer.");
327 return eStatus;
328 }
329
330 allocParamsForBufferLinear.dwBytes = hcpBufSizeParam.dwBufferSize;
331 allocParamsForBufferLinear.pBufName = "SaoTileLineBuffer";
332
333 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
334 m_osInterface,
335 &allocParamsForBufferLinear,
336 &m_resSaoTileLineBuffer);
337
338 if (eStatus != MOS_STATUS_SUCCESS)
339 {
340 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate SAO Tile Line Buffer.");
341 return eStatus;
342 }
343
344 // SAO Tile Column buffer
345 eStatus = (MOS_STATUS)m_hcpInterface->GetHevcBufferSize(
346 MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_COL,
347 &hcpBufSizeParam);
348
349 if (eStatus != MOS_STATUS_SUCCESS)
350 {
351 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to get the size for SAO Tile Column Buffer.");
352 return eStatus;
353 }
354
355 allocParamsForBufferLinear.dwBytes = hcpBufSizeParam.dwBufferSize;
356 allocParamsForBufferLinear.pBufName = "SaoTileColumnBuffer";
357
358 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
359 m_osInterface,
360 &allocParamsForBufferLinear,
361 &m_resSaoTileColumnBuffer);
362
363 if (eStatus != MOS_STATUS_SUCCESS)
364 {
365 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate SAO Tile Column Buffer.");
366 return eStatus;
367 }
368
369 // Lcu ILDB StreamOut buffer
370 size = 1000000;
371 allocParamsForBufferLinear.dwBytes = size;
372 allocParamsForBufferLinear.pBufName = "LcuILDBStreamOutBuffer";
373
374 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
375 m_osInterface,
376 &allocParamsForBufferLinear,
377 &m_resLcuIldbStreamOutBuffer);
378
379 if (eStatus != MOS_STATUS_SUCCESS)
380 {
381 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate LCU ILDB StreamOut Buffer.");
382 return eStatus;
383 }
384
385 // Lcu Base Address buffer
386 // HEVC Encoder Mode: Slice size is written to this buffer when slice size conformance is enabled.
387 // 1 CL (= 16 DWs = 64 bytes) per slice * Maximum number of dynamic slice = 600
388 // Note that simulation is assigning much larger space for this.
389 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6 * CODECHAL_CACHELINE_SIZE, CODECHAL_PAGE_SIZE);
390 allocParamsForBufferLinear.pBufName = "LcuBaseAddressBuffer";
391
392 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
393 m_osInterface,
394 &allocParamsForBufferLinear,
395 &m_resLcuBaseAddressBuffer);
396
397 if (eStatus != MOS_STATUS_SUCCESS)
398 {
399 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate LCU Base Address Buffer.");
400 return eStatus;
401 }
402
403 uint32_t mvt_size = MOS_ALIGN_CEIL(((m_frameWidth + 63) >> 6)*((m_frameHeight + 15) >> 4), 2) * CODECHAL_CACHELINE_SIZE;
404 uint32_t mvtb_size = MOS_ALIGN_CEIL(((m_frameWidth + 31) >> 5)*((m_frameHeight + 31) >> 5), 2) * CODECHAL_CACHELINE_SIZE;
405 m_sizeOfMvTemporalBuffer = MOS_MAX(mvt_size, mvtb_size);
406
407 // SAO StreamOut buffer
408 size = MOS_ALIGN_CEIL(picWidthInMinLCU * picHeightInMinLCU * 16, CODECHAL_CACHELINE_SIZE); // 16 bytes per LCU
409 allocParamsForBufferLinear.dwBytes = size;
410 allocParamsForBufferLinear.pBufName = "SaoStreamOutBuffer";
411
412 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
413 m_osInterface,
414 &allocParamsForBufferLinear,
415 &m_resSaoStreamOutBuffer);
416
417 if (eStatus != MOS_STATUS_SUCCESS)
418 {
419 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate SAO StreamOut Buffer.");
420 return eStatus;
421 }
422
423 return eStatus;
424 }
425
AllocateResources()426 MOS_STATUS CodechalEncodeHevcBase::AllocateResources()
427 {
428 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
429
430 CODECHAL_ENCODE_FUNCTION_ENTER;
431
432 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::AllocateResources());
433
434 // Allocate Ref Lists
435 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAllocateDataList(
436 m_refList,
437 CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC));
438
439 // Create the sync objects which will be used by each reference frame
440 for (uint32_t i = 0; i < CODECHAL_GET_ARRAY_LENGTH(m_refSync); i++)
441 {
442 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(m_osInterface, &m_refSync[i].resSyncObject));
443 m_refSync[i].bInUsed = false;
444 }
445
446 CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(AllocatePakResources(), "Failed to allocate PAK resources.");
447
448 if (m_encEnabled)
449 {
450 CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(AllocateEncResources(), "Failed to allocate ENC resources.");
451
452 CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(AllocateBrcResources(), "Failed to allocate BRC resources.");
453 }
454
455 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitSurfaceInfoTable());
456 CreateMhwParams();
457
458 return eStatus;
459 }
460
AllocateBuffer(PCODECHAL_ENCODE_BUFFER buffer,uint32_t size,const char * name,int32_t dwMemType)461 MOS_STATUS CodechalEncodeHevcBase::AllocateBuffer(
462 PCODECHAL_ENCODE_BUFFER buffer,
463 uint32_t size,
464 const char* name,
465 int32_t dwMemType)
466 {
467 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
468
469 CODECHAL_ENCODE_FUNCTION_ENTER;
470
471 CODECHAL_ENCODE_CHK_NULL_RETURN(buffer);
472
473 MOS_ALLOC_GFXRES_PARAMS allocParams;
474 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
475 allocParams.Type = MOS_GFXRES_BUFFER;
476 allocParams.TileType = MOS_TILE_LINEAR;
477 allocParams.Format = Format_Buffer;
478 allocParams.dwBytes = size;
479 allocParams.pBufName = name;
480 allocParams.dwMemType = dwMemType;
481 buffer->dwSize = size;
482
483 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
484 m_osInterface,
485 &allocParams,
486 &buffer->sResource);
487
488 if (eStatus != MOS_STATUS_SUCCESS)
489 {
490 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
491 return eStatus;
492 }
493
494 MOS_LOCK_PARAMS lockFlags;
495 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
496 lockFlags.WriteOnly = 1;
497
498 uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
499 m_osInterface,
500 &buffer->sResource,
501 &lockFlags);
502 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
503
504 MOS_ZeroMemory(data, size);
505
506 m_osInterface->pfnUnlockResource(
507 m_osInterface,
508 &buffer->sResource);
509
510 return eStatus;
511 }
512
AllocateBuffer2D(PMOS_SURFACE surface,uint32_t width,uint32_t height,const char * name,MOS_TILE_TYPE tileType,int32_t dwMemType)513 MOS_STATUS CodechalEncodeHevcBase::AllocateBuffer2D(
514 PMOS_SURFACE surface,
515 uint32_t width,
516 uint32_t height,
517 const char* name,
518 MOS_TILE_TYPE tileType,
519 int32_t dwMemType)
520 {
521 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
522
523 CODECHAL_ENCODE_FUNCTION_ENTER;
524
525 CODECHAL_ENCODE_CHK_NULL_RETURN(surface);
526
527 MOS_ZeroMemory(surface, sizeof(*surface));
528
529 surface->TileType = tileType;
530 surface->bArraySpacing = true;
531 surface->Format = Format_Buffer_2D;
532 surface->dwWidth = MOS_ALIGN_CEIL(width, 64);
533 surface->dwHeight = height;
534 surface->dwPitch = surface->dwWidth;
535
536 MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
537 MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
538 allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
539 allocParamsForBuffer2D.TileType = surface->TileType;
540 allocParamsForBuffer2D.Format = surface->Format;
541 allocParamsForBuffer2D.dwWidth = surface->dwWidth;
542 allocParamsForBuffer2D.dwHeight = surface->dwHeight;
543 allocParamsForBuffer2D.pBufName = name;
544 allocParamsForBuffer2D.dwMemType = dwMemType;
545
546 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
547 m_osInterface,
548 &allocParamsForBuffer2D,
549 &surface->OsResource);
550
551 if (eStatus != MOS_STATUS_SUCCESS)
552 {
553 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
554 return eStatus;
555 }
556
557 MOS_LOCK_PARAMS lockFlagsWriteOnly;
558 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
559 lockFlagsWriteOnly.WriteOnly = true;
560
561 uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
562 m_osInterface,
563 &(surface->OsResource),
564 &lockFlagsWriteOnly);
565
566 if (data == nullptr)
567 {
568 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock 2D Surface.");
569 eStatus = MOS_STATUS_UNKNOWN;
570 return eStatus;
571 }
572
573 MOS_ZeroMemory(data, surface->dwWidth * surface->dwHeight);
574
575 m_osInterface->pfnUnlockResource(m_osInterface, &(surface->OsResource));
576
577 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
578 m_osInterface,
579 surface));
580
581 return eStatus;
582 }
583
AllocateSurface(PMOS_SURFACE surface,uint32_t width,uint32_t height,const char * name,int32_t dwMemType)584 MOS_STATUS CodechalEncodeHevcBase::AllocateSurface(
585 PMOS_SURFACE surface,
586 uint32_t width,
587 uint32_t height,
588 const char* name,
589 int32_t dwMemType)
590 {
591 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
592
593 CODECHAL_ENCODE_FUNCTION_ENTER;
594
595 CODECHAL_ENCODE_CHK_NULL_RETURN(surface);
596
597 MOS_ALLOC_GFXRES_PARAMS allocParams;
598 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
599 allocParams.Type = MOS_GFXRES_2D;
600 allocParams.TileType = MOS_TILE_Y;
601 allocParams.Format = Format_NV12;
602 allocParams.dwWidth = width;
603 allocParams.dwHeight = height;
604 allocParams.pBufName = name;
605 allocParams.dwMemType = dwMemType;
606
607 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
608 m_osInterface,
609 &allocParams,
610 &surface->OsResource);
611
612 if (eStatus != MOS_STATUS_SUCCESS)
613 {
614 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
615 return eStatus;
616 }
617
618 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
619 m_osInterface,
620 surface));
621
622 return eStatus;
623 }
624
AllocateBatchBufferForPakSlices(uint32_t numSlices,uint8_t numPakPasses)625 MOS_STATUS CodechalEncodeHevcBase::AllocateBatchBufferForPakSlices(
626 uint32_t numSlices,
627 uint8_t numPakPasses)
628 {
629 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
630
631 CODECHAL_ENCODE_FUNCTION_ENTER;
632
633 MOS_ZeroMemory(
634 &m_batchBufferForPakSlices[m_currPakSliceIdx],
635 sizeof(MHW_BATCH_BUFFER));
636
637 // Get the slice size
638 uint32_t size = (numPakPasses + 1) * numSlices * m_sliceStatesSize;
639
640 m_batchBufferForPakSlices[m_currPakSliceIdx].bSecondLevel = true;
641 CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
642 m_osInterface,
643 &m_batchBufferForPakSlices[m_currPakSliceIdx],
644 nullptr,
645 size));
646
647 MOS_LOCK_PARAMS lockFlags;
648 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
649 lockFlags.WriteOnly = 1;
650 uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
651 m_osInterface,
652 &m_batchBufferForPakSlices[m_currPakSliceIdx].OsResource,
653 &lockFlags);
654
655 if (data == nullptr)
656 {
657 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to lock batch buffer for PAK slices.");
658 eStatus = MOS_STATUS_UNKNOWN;
659 return eStatus;
660 }
661
662 MOS_ZeroMemory(data, size);
663 m_osInterface->pfnUnlockResource(
664 m_osInterface,
665 &m_batchBufferForPakSlices[m_currPakSliceIdx].OsResource);
666
667 return eStatus;
668 }
669
ReadSseStatistics(PMOS_COMMAND_BUFFER cmdBuffer)670 MOS_STATUS CodechalEncodeHevcBase::ReadSseStatistics(PMOS_COMMAND_BUFFER cmdBuffer)
671 {
672 CODECHAL_ENCODE_FUNCTION_ENTER;
673
674 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
675
676 // encodeStatus is offset by 2 DWs in the resource
677 uint32_t sseOffsetinBytes = (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) + sizeof(uint32_t) * 2 + m_encodeStatusBuf.dwSumSquareErrorOffset;
678 for (auto i = 0; i < 6; i++) // 64 bit SSE values for luma/ chroma channels need to be copied
679 {
680 MHW_MI_COPY_MEM_MEM_PARAMS miCpyMemMemParams;
681 MOS_ZeroMemory(&miCpyMemMemParams, sizeof(miCpyMemMemParams));
682 miCpyMemMemParams.presSrc = &m_resFrameStatStreamOutBuffer;
683 miCpyMemMemParams.dwSrcOffset = (HEVC_PAK_STATISTICS_SSE_OFFSET + i) * sizeof(uint32_t); // SSE luma offset is located at DW32 in Frame statistics, followed by chroma
684 miCpyMemMemParams.presDst = &m_encodeStatusBuf.resStatusBuffer;
685 miCpyMemMemParams.dwDstOffset = sseOffsetinBytes + i * sizeof(uint32_t);
686 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd(cmdBuffer, &miCpyMemMemParams));
687 }
688 return eStatus;
689 }
690
CalculatePSNR(EncodeStatus * encodeStatus,EncodeStatusReport * encodeStatusReport)691 MOS_STATUS CodechalEncodeHevcBase::CalculatePSNR(
692 EncodeStatus *encodeStatus,
693 EncodeStatusReport *encodeStatusReport)
694 {
695 CODECHAL_ENCODE_FUNCTION_ENTER;
696
697 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
698
699 CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatus);
700 CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatusReport);
701 uint32_t numLumaPixels = 0, numPixelsPerChromaChannel = 0;
702
703 numLumaPixels = m_frameHeight * m_frameWidth;
704 switch (m_hevcSeqParams->chroma_format_idc)
705 {
706 case HCP_CHROMA_FORMAT_MONOCHROME:
707 numPixelsPerChromaChannel = 0;
708 break;
709 case HCP_CHROMA_FORMAT_YUV420:
710 numPixelsPerChromaChannel = numLumaPixels / 4;
711 break;
712 case HCP_CHROMA_FORMAT_YUV422:
713 numPixelsPerChromaChannel = numLumaPixels / 2;
714 break;
715 case HCP_CHROMA_FORMAT_YUV444:
716 numPixelsPerChromaChannel = numLumaPixels;
717 break;
718 default:
719 numPixelsPerChromaChannel = numLumaPixels / 2;
720 break;
721 }
722
723 double squarePeakPixelValue = pow((1 << (m_hevcSeqParams->bit_depth_luma_minus8 + 8)) - 1, 2);
724
725 for (auto i = 0; i < 3; i++)
726 {
727 uint32_t numPixels = i ? numPixelsPerChromaChannel : numLumaPixels;
728
729 if (m_hevcSeqParams->bit_depth_luma_minus8 == 0)
730 {
731 //8bit pixel data is represented in 10bit format in HW. so SSE should right shift by 4.
732 encodeStatus->sumSquareError[i] >>= 4;
733 }
734 encodeStatusReport->PSNRx100[i] = (uint16_t) CodecHal_Clip3(0, 10000,
735 (uint16_t) (encodeStatus->sumSquareError[i] ? 1000 * log10(squarePeakPixelValue * numPixels / encodeStatus->sumSquareError[i]) : -1));
736
737 CODECHAL_ENCODE_VERBOSEMESSAGE("PSNRx100[%d]:%d.\n", i, encodeStatusReport->PSNRx100[i]);
738 }
739
740 return eStatus;
741 }
742
ReleaseBatchBufferForPakSlices(uint32_t index)743 MOS_STATUS CodechalEncodeHevcBase::ReleaseBatchBufferForPakSlices(uint32_t index)
744 {
745 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
746
747 if (m_batchBufferForPakSlices[index].iSize)
748 {
749 Mhw_FreeBb(m_osInterface, &m_batchBufferForPakSlices[index], nullptr);
750 m_batchBufferForPakSlices[index].iSize = 0;
751 }
752
753 return eStatus;
754 }
755
FreePakResources()756 MOS_STATUS CodechalEncodeHevcBase::FreePakResources()
757 {
758 CODECHAL_ENCODE_FUNCTION_ENTER;
759
760 for (auto i = 0; i < CODECHAL_HEVC_NUM_PAK_SLICE_BATCH_BUFFERS; i++)
761 {
762 ReleaseBatchBufferForPakSlices(i);
763 }
764
765 m_osInterface->pfnFreeResource(m_osInterface, &m_resDeblockingFilterRowStoreScratchBuffer);
766 m_osInterface->pfnFreeResource(m_osInterface, &m_resDeblockingFilterTileRowStoreScratchBuffer);
767 m_osInterface->pfnFreeResource(m_osInterface, &m_resDeblockingFilterColumnRowStoreScratchBuffer);
768 m_osInterface->pfnFreeResource(m_osInterface, &m_resMetadataLineBuffer);
769 m_osInterface->pfnFreeResource(m_osInterface, &m_resMetadataTileLineBuffer);
770 m_osInterface->pfnFreeResource(m_osInterface, &m_resMetadataTileColumnBuffer);
771 m_osInterface->pfnFreeResource(m_osInterface, &m_resSaoLineBuffer);
772 m_osInterface->pfnFreeResource(m_osInterface, &m_resSaoTileLineBuffer);
773 m_osInterface->pfnFreeResource(m_osInterface, &m_resSaoTileColumnBuffer);
774 m_osInterface->pfnFreeResource(m_osInterface, &m_resLcuIldbStreamOutBuffer);
775 m_osInterface->pfnFreeResource(m_osInterface, &m_resLcuBaseAddressBuffer);
776 m_osInterface->pfnFreeResource(m_osInterface, &m_resSaoStreamOutBuffer);
777
778 return MOS_STATUS_SUCCESS;
779 }
780
FreeResources()781 void CodechalEncodeHevcBase::FreeResources()
782 {
783 CODECHAL_ENCODE_FUNCTION_ENTER;
784
785 CodechalEncoderState::FreeResources();
786
787 FreeEncResources();
788 FreeBrcResources();
789 FreePakResources();
790
791 // Release Ref Lists
792 CodecHalFreeDataList(m_refList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC);
793
794 for (uint32_t i = 0; i < CODECHAL_GET_ARRAY_LENGTH(m_refSync); i++)
795 {
796 m_osInterface->pfnDestroySyncResource(m_osInterface, &m_refSync[i].resSyncObject);
797 }
798
799 if (m_sliceStateParams)
800 {
801 MOS_Delete(m_sliceStateParams);
802 m_sliceStateParams = nullptr;
803 }
804 if (m_pipeModeSelectParams)
805 {
806 MOS_Delete(m_pipeModeSelectParams);
807 m_pipeModeSelectParams = nullptr;
808 }
809 if (m_pipeBufAddrParams)
810 {
811 MOS_Delete(m_pipeBufAddrParams);
812 m_pipeBufAddrParams = nullptr;
813 }
814 }
815
SetSequenceStructs()816 MOS_STATUS CodechalEncodeHevcBase::SetSequenceStructs()
817 {
818 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
819
820 CODECHAL_ENCODE_FUNCTION_ENTER;
821
822 uint32_t frameWidth = (m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3);
823
824 uint32_t frameHeight = (m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3);
825
826 // check if there is a dynamic resolution change
827 if ((m_oriFrameHeight && (m_oriFrameHeight != frameHeight)) ||
828 (m_oriFrameWidth && (m_oriFrameWidth != frameWidth)))
829 {
830 if (frameHeight > m_createHeight || frameWidth > m_createWidth)
831 {
832 CODECHAL_ENCODE_ASSERTMESSAGE("Resolution reset from lower resolution to higher resolution not supported if it is higher than the resolution of first frame.%d, %d %d, %d", m_createWidth, m_createHeight, frameWidth, frameHeight);
833 eStatus = MOS_STATUS_INVALID_PARAMETER;
834 return eStatus;
835 }
836 m_resolutionChanged = true;
837 m_brcInit = true;
838 }
839 else
840 {
841 m_resolutionChanged = false;
842 }
843
844 // setup internal parameters
845 m_oriFrameWidth = m_frameWidth = frameWidth;
846 m_oriFrameHeight = m_frameHeight = frameHeight;
847
848 m_picWidthInMb = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_oriFrameWidth);
849 m_picHeightInMb = (uint16_t)CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_oriFrameHeight);
850
851 if (m_resolutionChanged)
852 {
853 m_widthAlignedMaxLcu = MOS_ALIGN_CEIL(m_frameWidth, MAX_LCU_SIZE);
854 m_heightAlignedMaxLcu = MOS_ALIGN_CEIL(m_frameHeight, MAX_LCU_SIZE);
855 }
856
857 // Get row store cache params: as all the needed information is got here
858 if (m_hcpInterface->IsRowStoreCachingSupported())
859 {
860 MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams = {};
861 rowstoreParams.Mode = m_mode;
862 rowstoreParams.dwPicWidth = m_frameWidth;
863 rowstoreParams.ucChromaFormat = m_chromaFormat;
864 rowstoreParams.ucBitDepthMinus8 = m_hevcSeqParams->bit_depth_luma_minus8;
865 rowstoreParams.ucLCUSize = 1 << (m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3);
866 m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams);
867 }
868
869 m_brcEnabled = IsRateControlBrc(m_hevcSeqParams->RateControlMethod);
870
871 if (m_brcEnabled)
872 {
873 switch (m_hevcSeqParams->MBBRC)
874 {
875 case mbBrcInternal:
876 m_lcuBrcEnabled = (m_hevcSeqParams->TargetUsage == 1);
877 break;
878 case mbBrcDisabled:
879 m_lcuBrcEnabled = false;
880 break;
881 case mbBrcEnabled:
882 m_lcuBrcEnabled = true;
883 break;
884 }
885
886 if (m_hevcSeqParams->RateControlMethod == RATECONTROL_ICQ ||
887 m_hevcSeqParams->RateControlMethod == RATECONTROL_QVBR ||
888 m_hevcPicParams->NumROI)
889 {
890 // ICQ or ROI must result in LCU-based BRC to be enabled.
891 m_lcuBrcEnabled = true;
892 }
893 }
894
895 if (m_hevcSeqParams->RateControlMethod == RATECONTROL_VCM && m_lcuBrcEnabled)
896 {
897 m_lcuBrcEnabled = false; // when VCM is enabled, only frame-based BRC
898 }
899
900 if (m_hevcSeqParams->RateControlMethod == RATECONTROL_ICQ || m_hevcSeqParams->RateControlMethod == RATECONTROL_QVBR)
901 {
902 if (m_hevcSeqParams->ICQQualityFactor < CODECHAL_ENCODE_HEVC_MIN_ICQ_QUALITYFACTOR ||
903 m_hevcSeqParams->ICQQualityFactor > CODECHAL_ENCODE_HEVC_MAX_ICQ_QUALITYFACTOR)
904 {
905 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid ICQ Quality Factor input (%d)\n", m_hevcSeqParams->ICQQualityFactor);
906 eStatus = MOS_STATUS_INVALID_PARAMETER;
907 return eStatus;
908 }
909 }
910
911 m_usAvbrAccuracy = CODECHAL_ENCODE_HEVC_DEFAULT_AVBR_ACCURACY;
912 m_usAvbrConvergence = CODECHAL_ENCODE_HEVC_DEFAULT_AVBR_CONVERGENCE;
913
914 // Calculate 4x, 16x, 32x dimensions as applicable
915 CODECHAL_ENCODE_CHK_STATUS_RETURN(CalcScaledDimensions());
916
917 // It is assumed to be frame-mode always
918 m_frameFieldHeight = m_frameHeight;
919 m_frameFieldHeightInMb = m_picHeightInMb;
920 m_downscaledFrameFieldHeightInMb16x = m_downscaledHeightInMb16x;
921 m_downscaledFrameFieldHeightInMb4x = m_downscaledHeightInMb4x;
922 m_downscaledFrameFieldHeightInMb32x = m_downscaledHeightInMb32x;
923
924 m_brcReset = m_hevcSeqParams->bResetBRC;
925 m_roiValueInDeltaQp = m_hevcSeqParams->ROIValueInDeltaQP;
926
927 uint32_t lcuInRow = MOS_ALIGN_CEIL(m_frameWidth, (1 << (m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3))) >> (m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3);
928 uint32_t lcu2MbRatio = (1 << (m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3)) / CODECHAL_MACROBLOCK_WIDTH;
929 if (lcuInRow < 1 || lcu2MbRatio < 1)
930 {
931 eStatus = MOS_STATUS_INVALID_PARAMETER;
932 return eStatus;
933 }
934
935 if (m_brcReset &&
936 (!m_brcEnabled ||
937 m_hevcSeqParams->RateControlMethod == RATECONTROL_ICQ))
938 {
939 CODECHAL_ENCODE_ASSERTMESSAGE("BRC Reset cannot be trigerred in CQP/ICQ modes - invalid BRC parameters.");
940 m_brcReset = false;
941 }
942
943 if (m_hevcSeqParams->TargetUsage == 0x07 && !m_enable26WalkingPattern)
944 {
945 m_enable26WalkingPattern = true; // in the performance mode (TU=7), 26z walking pattern is not supported
946 }
947
948 if (!m_32xMeUserfeatureControl && m_32xMeSupported && m_hevcSeqParams->TargetUsage == 0x07)
949 {
950 m_32xMeSupported = false; // TU7 does not support ultra HME
951 }
952
953 m_encode4KSequence = ((m_frameWidth * m_frameHeight) >=
954 (ENCODE_HEVC_4K_PIC_WIDTH * ENCODE_HEVC_4K_PIC_HEIGHT))
955 ? true
956 : false;
957
958 m_encode16KSequence = ((m_frameWidth * m_frameHeight) >=
959 (ENCODE_HEVC_16K_PIC_WIDTH * ENCODE_HEVC_16K_PIC_HEIGHT))
960 ? true
961 : false;
962
963 // if GOP structure is I-frame only, we use 3 non-ref slots for tracked buffer
964 m_gopIsIdrFrameOnly = (m_hevcSeqParams->GopPicSize == 1);
965
966 // check output Chroma format
967 m_outputChromaFormat = m_hevcSeqParams->chroma_format_idc;
968
969 return eStatus;
970 }
971
SetPictureStructs()972 MOS_STATUS CodechalEncodeHevcBase::SetPictureStructs()
973 {
974 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
975
976 CODECHAL_ENCODE_FUNCTION_ENTER;
977
978 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
979 {
980 m_refIdxMapping[i] = -1;
981 m_currUsedRefPic[i] = false;
982 }
983
984 // To obtain current "used" reference frames. The number of current used reference frames cannot be greater than 8
985 auto slcParams = m_hevcSliceParams;
986 for (uint32_t s = 0; s < m_numSlices; s++, slcParams++)
987 {
988 for (auto ll = 0; ll < 2; ll++)
989 {
990 uint32_t numRef = (ll == 0) ? slcParams->num_ref_idx_l0_active_minus1 :
991 slcParams->num_ref_idx_l1_active_minus1;
992
993 if (numRef > CODEC_MAX_NUM_REF_FRAME_HEVC)
994 {
995 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid number of ref frames for l0 %d or l1 %d", slcParams->num_ref_idx_l0_active_minus1, slcParams->num_ref_idx_l1_active_minus1);
996 eStatus = MOS_STATUS_INVALID_PARAMETER;
997 return eStatus;
998 }
999 for (uint32_t i = 0; i <= numRef; i++)
1000 {
1001 if (i >= CODEC_MAX_NUM_REF_FRAME_HEVC)
1002 {
1003 return MOS_STATUS_INVALID_PARAMETER;
1004 }
1005 CODEC_PICTURE refPic = slcParams->RefPicList[ll][i];
1006 if (!CodecHal_PictureIsInvalid(refPic) &&
1007 !CodecHal_PictureIsInvalid(m_hevcPicParams->RefFrameList[refPic.FrameIdx]))
1008 {
1009 m_currUsedRefPic[refPic.FrameIdx] = true;
1010 }
1011 }
1012 }
1013 }
1014
1015 for (uint8_t i = 0, RefIdx = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
1016 {
1017 if (!m_currUsedRefPic[i])
1018 {
1019 continue;
1020 }
1021
1022 uint8_t index = m_hevcPicParams->RefFrameList[i].FrameIdx;
1023 bool duplicatedIdx = false;
1024 for (unsigned char ii = 0; ii < i; ii++)
1025 {
1026 if (m_currUsedRefPic[i] && index == m_hevcPicParams->RefFrameList[ii].FrameIdx)
1027 {
1028 // We find the same FrameIdx in the ref_frame_list. Multiple reference frames are the same.
1029 // In other words, RefFrameList[i] and RefFrameList[ii] have the same surface Id
1030 duplicatedIdx = true;
1031 m_refIdxMapping[i] = m_refIdxMapping[ii];
1032 break;
1033 }
1034 }
1035
1036 if (duplicatedIdx)
1037 {
1038 continue;
1039 }
1040
1041 if (RefIdx >= CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC)
1042 {
1043 // Total number of distingushing reference frames cannot be geater than 8.
1044 CODECHAL_ENCODE_ASSERT(false);
1045 eStatus = MOS_STATUS_INVALID_PARAMETER;
1046 return eStatus;
1047 }
1048
1049 // Map reference frame index [0-15] into a set of unique IDs within [0-7]
1050 m_refIdxMapping[i] = RefIdx;
1051 RefIdx++;
1052 }
1053
1054 if (m_hevcPicParams->CodingType != I_TYPE && m_hevcPicParams->CollocatedRefPicIndex != 0xFF && m_hevcPicParams->CollocatedRefPicIndex < CODEC_MAX_NUM_REF_FRAME_HEVC)
1055 {
1056 uint8_t frameStoreId = (uint8_t)m_refIdxMapping[m_hevcPicParams->CollocatedRefPicIndex];
1057
1058 if (frameStoreId >= CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC || !m_currUsedRefPic[m_hevcPicParams->CollocatedRefPicIndex])
1059 {
1060 // CollocatedRefPicIndex is wrong in this case for the reference frame is not used be used
1061 eStatus = MOS_STATUS_INVALID_PARAMETER;
1062 return eStatus;
1063 }
1064 }
1065
1066 if (m_hevcPicParams->QpY > CODECHAL_ENCODE_HEVC_MAX_SLICE_QP)
1067 {
1068 return MOS_STATUS_INVALID_PARAMETER;
1069 }
1070
1071 if (Mos_ResourceIsNull(&m_reconSurface.OsResource) &&
1072 (!m_hevcPicParams->bUseRawPicForRef || m_codecFunction != CODECHAL_FUNCTION_ENC))
1073 {
1074 return MOS_STATUS_INVALID_PARAMETER;
1075 }
1076
1077 if (m_hevcSeqParams->scaling_list_enable_flag && !m_hevcPicParams->scaling_list_data_present_flag)
1078 {
1079 CreateDefaultScalingList();
1080 }
1081 else if (!m_hevcSeqParams->scaling_list_enable_flag)
1082 {
1083 CreateFlatScalingList();
1084 }
1085
1086 unsigned char prevRefIdx = m_currReconstructedPic.FrameIdx;
1087 PCODEC_REF_LIST *refListFull = &m_refList[0];
1088
1089 // Sync initialize
1090 if ((m_firstFrame) ||
1091 (!m_brcEnabled && m_hevcPicParams->bUseRawPicForRef) ||
1092 (!m_brcEnabled && (m_hevcPicParams->CodingType == I_TYPE)) ||
1093 (!m_brcEnabled && !refListFull[prevRefIdx]->bUsedAsRef))
1094 {
1095 m_waitForPak = false;
1096 }
1097 else
1098 {
1099 m_waitForPak = true;
1100 }
1101
1102 if (m_brcEnabled || m_hevcPicParams->bUsedAsRef)
1103 {
1104 m_signalEnc = true;
1105 }
1106 else
1107 {
1108 m_signalEnc = false;
1109 }
1110
1111 m_currEncBbSet = MB_ENC_Frame_BB;
1112 m_lastPicInSeq = m_hevcPicParams->bLastPicInSeq;
1113 m_lastPicInStream = m_hevcPicParams->bLastPicInStream;
1114 m_statusReportFeedbackNumber = m_hevcPicParams->StatusReportFeedbackNumber;
1115 m_currOriginalPic = m_hevcPicParams->CurrOriginalPic;
1116 m_currReconstructedPic = m_hevcPicParams->CurrReconstructedPic;
1117
1118 unsigned char currRefIdx = m_hevcPicParams->CurrReconstructedPic.FrameIdx;
1119 refListFull[currRefIdx]->sRefReconBuffer = m_reconSurface;
1120 refListFull[currRefIdx]->sRefRawBuffer = m_rawSurface;
1121 refListFull[currRefIdx]->RefPic = m_hevcPicParams->CurrOriginalPic;
1122 refListFull[currRefIdx]->bUsedAsRef = m_hevcPicParams->bUsedAsRef;
1123 refListFull[currRefIdx]->resBitstreamBuffer = m_resBitstreamBuffer;
1124 refListFull[currRefIdx]->bFormatConversionDone = false;
1125
1126 // P/B frames with empty ref lists are internally encoded as I frames,
1127 // while picture header packing remains the original value
1128 m_pictureCodingType = m_hevcPicParams->CodingType;
1129
1130 bool emptyRefFrmList = true;
1131 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
1132 {
1133 if (m_hevcPicParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
1134 {
1135 emptyRefFrmList = false;
1136 break;
1137 }
1138 }
1139
1140 if (emptyRefFrmList && m_pictureCodingType != I_TYPE)
1141 {
1142 // If there is no reference frame in the list, just mark the current picture as the I type
1143 m_pictureCodingType = I_TYPE;
1144 }
1145
1146 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
1147 {
1148 m_picIdx[i].bValid = false;
1149 if (m_hevcPicParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
1150 {
1151 uint8_t index = m_hevcPicParams->RefFrameList[i].FrameIdx;
1152 bool duplicatedIdx = false;
1153 for (auto ii = 0; ii < i; ii++)
1154 {
1155 if (m_picIdx[ii].bValid && index == m_hevcPicParams->RefFrameList[ii].FrameIdx)
1156 {
1157 // We find the same FrameIdx in the ref_frame_list. Multiple reference frames are the same.
1158 // In other words, RefFrameList[i] and RefFrameList[ii] have the same surface Id
1159 duplicatedIdx = true;
1160 break;
1161 }
1162 }
1163
1164 if (duplicatedIdx)
1165 {
1166 continue;
1167 }
1168
1169 // this reference frame in unique. Save it into the full reference list with 127 items
1170 refListFull[index]->RefPic.PicFlags =
1171 CodecHal_CombinePictureFlags(refListFull[index]->RefPic, m_hevcPicParams->RefFrameList[i]);
1172 refListFull[index]->iFieldOrderCnt[0] = m_hevcPicParams->RefFramePOCList[i];
1173 refListFull[index]->iFieldOrderCnt[1] = m_hevcPicParams->RefFramePOCList[i];
1174 refListFull[index]->sRefBuffer = m_hevcPicParams->bUseRawPicForRef ? refListFull[index]->sRefRawBuffer : refListFull[index]->sRefReconBuffer;
1175
1176 m_picIdx[i].bValid = true;
1177 m_picIdx[i].ucPicIdx = index;
1178 }
1179 }
1180
1181 // Save the current RefList
1182 uint8_t ii = 0;
1183 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
1184 {
1185 if (m_picIdx[i].bValid)
1186 {
1187 refListFull[currRefIdx]->RefList[ii] = m_hevcPicParams->RefFrameList[i];
1188 ii++;
1189 }
1190 }
1191 refListFull[currRefIdx]->ucNumRef = ii;
1192 m_currRefList = refListFull[currRefIdx];
1193
1194 CodecEncodeHevcFeiPicParams *feiPicParams = (CodecEncodeHevcFeiPicParams *)m_encodeParams.pFeiPicParams;
1195 if ((m_codecFunction == CODECHAL_FUNCTION_ENC_PAK) ||
1196 ((m_codecFunction == CODECHAL_FUNCTION_FEI_ENC_PAK) && (feiPicParams->bCTBCmdCuRecordEnable == false)) ||
1197 (m_codecFunction == CODECHAL_FUNCTION_ENC_VDENC_PAK))
1198 {
1199 m_currMinus2MbCodeIndex = m_lastMbCodeIndex;
1200 m_lastMbCodeIndex = m_currMbCodeIdx;
1201 // the actual MbCode/MvData surface to be allocated later
1202 m_trackedBuf->SetAllocationFlag(true);
1203 }
1204 else if (m_codecFunction == CODECHAL_FUNCTION_ENC)
1205 {
1206 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encodeParams.presMbCodeSurface);
1207 m_resMbCodeSurface = *m_encodeParams.presMbCodeSurface;
1208 }
1209 else if(((m_codecFunction == CODECHAL_FUNCTION_FEI_ENC_PAK) && feiPicParams->bCTBCmdCuRecordEnable) ||
1210 (m_codecFunction == CODECHAL_FUNCTION_FEI_ENC) ||
1211 (m_codecFunction == CODECHAL_FUNCTION_FEI_PAK))
1212 {
1213 if(Mos_ResourceIsNull(&feiPicParams->resCURecord) || Mos_ResourceIsNull(&feiPicParams->resCTBCmd))
1214 {
1215 return MOS_STATUS_INVALID_PARAMETER;
1216 }
1217 }
1218
1219 refListFull[currRefIdx]->iFieldOrderCnt[0] = m_hevcPicParams->CurrPicOrderCnt;
1220 refListFull[currRefIdx]->iFieldOrderCnt[1] = m_hevcPicParams->CurrPicOrderCnt;
1221
1222 m_hmeEnabled = m_hmeSupported && m_pictureCodingType != I_TYPE;
1223 m_b16XMeEnabled = m_16xMeSupported && m_pictureCodingType != I_TYPE;
1224 m_b32XMeEnabled = m_32xMeSupported && m_pictureCodingType != I_TYPE;
1225
1226 CODECHAL_ENCODE_CHK_STATUS_RETURN(CalcLCUMaxCodingSize());
1227
1228 // Screen content flag will come in with PPS on Linux/Android, but in SPS on other platforms,
1229 // we will use screen content flag in PPS for kernel programming, and update
1230 // the PPS screen content flag based on the SPS screen content flag if enabled.
1231 m_hevcPicParams->bScreenContent |= m_hevcSeqParams->bScreenContent;
1232
1233 return eStatus;
1234 }
1235
CalcLCUMaxCodingSize()1236 MOS_STATUS CodechalEncodeHevcBase::CalcLCUMaxCodingSize()
1237 {
1238 CODECHAL_ENCODE_FUNCTION_ENTER;
1239
1240 uint16_t log2_max_coding_block_size = m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3;
1241 uint32_t rawCTUBits = (1 << (2 * log2_max_coding_block_size));
1242
1243 switch (m_hevcSeqParams->chroma_format_idc)
1244 {
1245 // 420
1246 case 1:
1247 rawCTUBits = rawCTUBits * 3 / 2;
1248 break;
1249 // 422
1250 case 2:
1251 rawCTUBits = rawCTUBits * 2;
1252 break;
1253 // 444
1254 case 3:
1255 rawCTUBits = rawCTUBits * 3;
1256 break;
1257 default:
1258 break;
1259 };
1260
1261 rawCTUBits = rawCTUBits * (m_hevcSeqParams->bit_depth_luma_minus8 + 8);
1262 rawCTUBits = (5 * rawCTUBits / 3);
1263
1264 if (m_hevcPicParams->LcuMaxBitsizeAllowed == 0 || m_hevcPicParams->LcuMaxBitsizeAllowed > rawCTUBits)
1265 {
1266 m_hevcPicParams->LcuMaxBitsizeAllowed = rawCTUBits;
1267 }
1268
1269 return MOS_STATUS_SUCCESS;
1270 }
1271
SetSliceStructs()1272 MOS_STATUS CodechalEncodeHevcBase::SetSliceStructs()
1273 {
1274 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1275
1276 CODECHAL_ENCODE_FUNCTION_ENTER;
1277
1278 if (m_numSlices > m_maxNumSlicesSupported)
1279 {
1280 CODECHAL_ENCODE_ASSERTMESSAGE("Number of slice exceeds limit!");
1281 return MOS_STATUS_INVALID_PARAMETER;
1282 }
1283
1284 // first slice must come with slice_segment_address = 0
1285 if (m_hevcSliceParams->slice_segment_address != 0)
1286 {
1287 CODECHAL_ENCODE_ASSERTMESSAGE("First slice segment_address != 0!");
1288 return MOS_STATUS_INVALID_PARAMETER;
1289 }
1290
1291 m_refList[m_currReconstructedPic.FrameIdx]->ucQPValue[0] = m_hevcPicParams->QpY + m_hevcSliceParams->slice_qp_delta;
1292
1293 m_lowDelay = true;
1294 m_sameRefList = true;
1295 m_arbitraryNumMbsInSlice = false;
1296
1297 uint32_t lcuInRow = MOS_ALIGN_CEIL(m_frameWidth, (1 << (m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3))) >> (m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3);
1298 auto slcParams = m_hevcSliceParams;
1299 for (uint32_t startLCU = 0, slcCount = 0; slcCount < m_numSlices; slcCount++, slcParams++)
1300 {
1301 CODECHAL_ENCODE_CHK_STATUS_RETURN(ValidateRefFrameData(slcParams));
1302
1303 if ((m_hevcPicParams->QpY + slcParams->slice_qp_delta) > CODECHAL_ENCODE_HEVC_MAX_SLICE_QP)
1304 {
1305 eStatus = MOS_STATUS_INVALID_PARAMETER;
1306 return eStatus;
1307 }
1308
1309 CODECHAL_ENCODE_CHK_STATUS_RETURN(ValidateLowDelayBFrame(slcParams));
1310
1311 CODECHAL_ENCODE_CHK_STATUS_RETURN(ValidateSameRefInL0L1(slcParams));
1312
1313 if (m_arbitraryNumMbsInSlice == false && (slcParams->NumLCUsInSlice % lcuInRow))
1314 {
1315 // Slice number must be multiple of LCU rows
1316 m_arbitraryNumMbsInSlice = true;
1317 }
1318
1319 if (!m_hevcPicParams->tiles_enabled_flag)
1320 {
1321 CODECHAL_ENCODE_ASSERT(slcParams->slice_segment_address == startLCU);
1322 startLCU += slcParams->NumLCUsInSlice;
1323 }
1324 }
1325
1326 if (m_lowDelay && !m_sameRefList)
1327 {
1328 CODECHAL_ENCODE_NORMALMESSAGE("Attention: LDB frame but with different L0/L1 list !");
1329 }
1330
1331 if (m_hevcSeqParams->RateControlMethod == RATECONTROL_VCM && m_pictureCodingType == B_TYPE && !m_lowDelay)
1332 {
1333 CODECHAL_ENCODE_ASSERTMESSAGE("VCM BRC mode does not support regular B-frames\n");
1334 return MOS_STATUS_INVALID_PARAMETER;
1335 }
1336
1337 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySliceSAOState());
1338
1339 #if (_DEBUG || _RELEASE_INTERNAL)
1340 if (!m_vdencEnabled)
1341 {
1342 m_forceSinglePakPass = false;
1343 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
1344 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1345 //read user feature key for pak pass number forcing.
1346 MOS_UserFeature_ReadValue_ID(
1347 nullptr,
1348 __MEDIA_USER_FEATURE_VALUE_FORCE_PAK_PASS_NUM_ID,
1349 &userFeatureData,
1350 m_osInterface->pOsContext);
1351 if (userFeatureData.u32Data > 0 && userFeatureData.u32Data <= m_numPasses)
1352 {
1353 m_numPasses = (uint8_t)userFeatureData.u32Data - 1;
1354 if (m_numPasses == 0)
1355 {
1356 m_forceSinglePakPass = true;
1357 CODECHAL_ENCODE_VERBOSEMESSAGE("Force to single PAK pass\n");
1358 }
1359 }
1360 }
1361 #endif
1362 return eStatus;
1363 }
1364
ValidateSameRefInL0L1(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams)1365 MOS_STATUS CodechalEncodeHevcBase::ValidateSameRefInL0L1(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams)
1366 {
1367 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1368
1369 CODECHAL_ENCODE_FUNCTION_ENTER;
1370
1371 CODECHAL_ENCODE_CHK_NULL_RETURN(slcParams);
1372
1373 if (m_sameRefList &&
1374 slcParams->num_ref_idx_l0_active_minus1 >= slcParams->num_ref_idx_l1_active_minus1)
1375 {
1376 for (int refIdx = 0; refIdx < slcParams->num_ref_idx_l1_active_minus1 + 1; refIdx++)
1377 {
1378 CODEC_PICTURE refPicL0 = slcParams->RefPicList[0][refIdx];
1379 CODEC_PICTURE refPicL1 = slcParams->RefPicList[1][refIdx];
1380
1381 if (!CodecHal_PictureIsInvalid(refPicL0) && !CodecHal_PictureIsInvalid(refPicL1) && refPicL0.FrameIdx != refPicL1.FrameIdx)
1382 {
1383 m_sameRefList = false;
1384 break;
1385 }
1386 }
1387 }
1388
1389 return eStatus;
1390 }
1391
ValidateLowDelayBFrame(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams)1392 MOS_STATUS CodechalEncodeHevcBase::ValidateLowDelayBFrame(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams)
1393 {
1394 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1395
1396 CODECHAL_ENCODE_FUNCTION_ENTER;
1397
1398 CODECHAL_ENCODE_CHK_NULL_RETURN(slcParams);
1399
1400 // Examine if now it is in the low delay mode
1401 if (slcParams->slice_type == CODECHAL_ENCODE_HEVC_B_SLICE && m_lowDelay)
1402 {
1403 // forward
1404 for (int refIdx = 0; (refIdx < slcParams->num_ref_idx_l0_active_minus1 + 1) && m_lowDelay; refIdx++)
1405 {
1406 if (refIdx >= CODEC_MAX_NUM_REF_FRAME_HEVC)
1407 {
1408 break;
1409 }
1410
1411 CODEC_PICTURE refPic = slcParams->RefPicList[0][refIdx];
1412 if (!CodecHal_PictureIsInvalid(refPic) && m_hevcPicParams->RefFramePOCList[refPic.FrameIdx] > m_hevcPicParams->CurrPicOrderCnt)
1413 {
1414 m_lowDelay = false;
1415 }
1416 }
1417
1418 // backward
1419 for (int refIdx = 0; (refIdx < slcParams->num_ref_idx_l1_active_minus1 + 1) && m_lowDelay; refIdx++)
1420 {
1421 if (refIdx >= CODEC_MAX_NUM_REF_FRAME_HEVC)
1422 {
1423 break;
1424 }
1425
1426 CODEC_PICTURE refPic = slcParams->RefPicList[1][refIdx];
1427 if (!CodecHal_PictureIsInvalid(refPic) && m_hevcPicParams->RefFramePOCList[refPic.FrameIdx] > m_hevcPicParams->CurrPicOrderCnt)
1428 {
1429 m_lowDelay = false;
1430 }
1431 }
1432 }
1433
1434 return eStatus;
1435 }
1436
VerifySliceSAOState()1437 MOS_STATUS CodechalEncodeHevcBase::VerifySliceSAOState()
1438 {
1439 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1440
1441 CODECHAL_ENCODE_FUNCTION_ENTER;
1442
1443 if (m_hevcSeqParams->SAO_enabled_flag)
1444 {
1445 auto slcParams = m_hevcSliceParams;
1446 uint32_t slcSaoLumaCount = 0, slcSaoChromaCount = 0;
1447
1448 for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++, slcParams++)
1449 {
1450 slcSaoLumaCount += slcParams->slice_sao_luma_flag;
1451 slcSaoChromaCount += slcParams->slice_sao_chroma_flag;
1452 }
1453
1454 // For HCP_SLICE_STATE command, slices must have the same SAO setting within a picture for encoder.
1455 if (((slcSaoLumaCount > 0) && (slcSaoLumaCount != m_numSlices)) ||
1456 ((slcSaoChromaCount > 0) && (slcSaoChromaCount != m_numSlices)))
1457 {
1458 m_hevcSeqParams->SAO_enabled_flag = false;
1459 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid SAO parameters in slice. All slices must have the same SAO setting within a picture.");
1460 }
1461 }
1462
1463 m_uc2NdSaoPass = 0; // Assume there is no 2nd SAO pass
1464
1465 if (m_hevcSeqParams->SAO_enabled_flag && m_b2NdSaoPassNeeded)
1466 {
1467 m_numPasses = m_numPasses + 1; // one more pass for the 2nd SAO, i.e., BRC0, BRC1, ..., BRCn, and SAOn+1
1468 m_uc2NdSaoPass = m_numPasses;
1469 }
1470
1471 return eStatus;
1472 }
1473
UpdateYUY2SurfaceInfo(PMOS_SURFACE surface,bool is10Bit)1474 MOS_STATUS CodechalEncodeHevcBase::UpdateYUY2SurfaceInfo(
1475 PMOS_SURFACE surface,
1476 bool is10Bit)
1477 {
1478 CODECHAL_ENCODE_FUNCTION_ENTER;
1479
1480 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1481
1482 CODECHAL_ENCODE_CHK_NULL_RETURN(surface);
1483
1484 if (Format_YUY2V == surface->Format ||
1485 Format_Y216V == surface->Format)
1486 {
1487 // surface has been updated
1488 return eStatus;
1489 }
1490
1491 surface->Format = is10Bit ? Format_Y216V : Format_YUY2V;
1492 surface->dwWidth = m_oriFrameWidth;
1493 surface->dwHeight = m_oriFrameHeight;
1494
1495 surface->YPlaneOffset.iXOffset = 0;
1496 surface->YPlaneOffset.iYOffset = 0;
1497
1498 surface->UPlaneOffset.iSurfaceOffset = surface->YPlaneOffset.iSurfaceOffset + surface->dwHeight * surface->dwPitch;
1499 surface->UPlaneOffset.iXOffset = 0;
1500 surface->UPlaneOffset.iYOffset = surface->dwHeight;
1501
1502 surface->VPlaneOffset.iSurfaceOffset = surface->UPlaneOffset.iSurfaceOffset;
1503 surface->VPlaneOffset.iXOffset = 0;
1504 surface->VPlaneOffset.iYOffset = surface->dwHeight;
1505
1506 return eStatus;
1507 }
1508
CreateFlatScalingList()1509 void CodechalEncodeHevcBase::CreateFlatScalingList()
1510 {
1511 CODECHAL_ENCODE_FUNCTION_ENTER;
1512
1513 for (auto i = 0; i < 6; i++)
1514 {
1515 memset(&(m_hevcIqMatrixParams->ucScalingLists0[i][0]),
1516 0x10,
1517 sizeof(m_hevcIqMatrixParams->ucScalingLists0[i]));
1518
1519 memset(&(m_hevcIqMatrixParams->ucScalingLists1[i][0]),
1520 0x10,
1521 sizeof(m_hevcIqMatrixParams->ucScalingLists1[i]));
1522
1523 memset(&(m_hevcIqMatrixParams->ucScalingLists2[i][0]),
1524 0x10,
1525 sizeof(m_hevcIqMatrixParams->ucScalingLists2[i]));
1526 }
1527
1528 memset(&(m_hevcIqMatrixParams->ucScalingLists3[0][0]),
1529 0x10,
1530 sizeof(m_hevcIqMatrixParams->ucScalingLists3[0]));
1531
1532 memset(&(m_hevcIqMatrixParams->ucScalingLists3[1][0]),
1533 0x10,
1534 sizeof(m_hevcIqMatrixParams->ucScalingLists3[1]));
1535
1536 memset(&(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID2[0]),
1537 0x10,
1538 sizeof(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID2));
1539
1540 memset(&(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID3[0]),
1541 0x10,
1542 sizeof(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID3));
1543 }
1544
CreateDefaultScalingList()1545 void CodechalEncodeHevcBase::CreateDefaultScalingList()
1546 {
1547 CODECHAL_ENCODE_FUNCTION_ENTER;
1548
1549 const uint8_t flatScalingList4x4[16] =
1550 {
1551 16,16,16,16,
1552 16,16,16,16,
1553 16,16,16,16,
1554 16,16,16,16
1555 };
1556
1557 const uint8_t defaultScalingList8x8[2][64] =
1558 {
1559 {
1560 16,16,16,16,17,18,21,24,
1561 16,16,16,16,17,19,22,25,
1562 16,16,17,18,20,22,25,29,
1563 16,16,18,21,24,27,31,36,
1564 17,17,20,24,30,35,41,47,
1565 18,19,22,27,35,44,54,65,
1566 21,22,25,31,41,54,70,88,
1567 24,25,29,36,47,65,88,115
1568 },
1569 {
1570 16,16,16,16,17,18,20,24,
1571 16,16,16,17,18,20,24,25,
1572 16,16,17,18,20,24,25,28,
1573 16,17,18,20,24,25,28,33,
1574 17,18,20,24,25,28,33,41,
1575 18,20,24,25,28,33,41,54,
1576 20,24,25,28,33,41,54,71,
1577 24,25,28,33,41,54,71,91
1578 }
1579 };
1580
1581 for (auto i = 0; i < 6; i++)
1582 {
1583 memcpy(&(m_hevcIqMatrixParams->ucScalingLists0[i][0]),
1584 flatScalingList4x4,
1585 sizeof(m_hevcIqMatrixParams->ucScalingLists0[i]));
1586 }
1587
1588 for (auto i = 0; i < 3; i++)
1589 {
1590 memcpy(&(m_hevcIqMatrixParams->ucScalingLists1[i][0]),
1591 defaultScalingList8x8[0],
1592 sizeof(m_hevcIqMatrixParams->ucScalingLists1[i]));
1593
1594 memcpy(&(m_hevcIqMatrixParams->ucScalingLists1[3 + i][0]),
1595 defaultScalingList8x8[1],
1596 sizeof(m_hevcIqMatrixParams->ucScalingLists1[3 + i]));
1597
1598 memcpy(&(m_hevcIqMatrixParams->ucScalingLists2[i][0]),
1599 defaultScalingList8x8[0],
1600 sizeof(m_hevcIqMatrixParams->ucScalingLists2[i]));
1601
1602 memcpy(&(m_hevcIqMatrixParams->ucScalingLists2[3 + i][0]),
1603 defaultScalingList8x8[1],
1604 sizeof(m_hevcIqMatrixParams->ucScalingLists2[3 + i]));
1605 }
1606
1607 memcpy(&(m_hevcIqMatrixParams->ucScalingLists3[0][0]),
1608 defaultScalingList8x8[0],
1609 sizeof(m_hevcIqMatrixParams->ucScalingLists3[0]));
1610
1611 memcpy(&(m_hevcIqMatrixParams->ucScalingLists3[1][0]),
1612 defaultScalingList8x8[1],
1613 sizeof(m_hevcIqMatrixParams->ucScalingLists3[1]));
1614
1615 memset(&(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID2[0]),
1616 0x10,
1617 sizeof(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID2));
1618
1619 memset(&(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID3[0]),
1620 0x10,
1621 sizeof(m_hevcIqMatrixParams->ucScalingListDCCoefSizeID3));
1622 }
1623
VerifyCommandBufferSize()1624 MOS_STATUS CodechalEncodeHevcBase::VerifyCommandBufferSize()
1625 {
1626 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1627
1628 CODECHAL_ENCODE_FUNCTION_ENTER;
1629
1630 // resize CommandBuffer Size for every BRC pass
1631 if (!m_singleTaskPhaseSupported)
1632 {
1633 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
1634 }
1635 return eStatus;
1636 }
1637
GetCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)1638 MOS_STATUS CodechalEncodeHevcBase::GetCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)
1639 {
1640 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1641
1642 CODECHAL_ENCODE_FUNCTION_ENTER;
1643
1644 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1645
1646 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, cmdBuffer, 0));
1647
1648 return eStatus;
1649
1650 }
1651
ReturnCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)1652 MOS_STATUS CodechalEncodeHevcBase::ReturnCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)
1653 {
1654 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1655
1656 CODECHAL_ENCODE_FUNCTION_ENTER;
1657
1658 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1659
1660 m_osInterface->pfnReturnCommandBuffer(m_osInterface, cmdBuffer, 0);
1661 return eStatus;
1662 }
1663
SubmitCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer,bool bNullRendering)1664 MOS_STATUS CodechalEncodeHevcBase::SubmitCommandBuffer(
1665 PMOS_COMMAND_BUFFER cmdBuffer,
1666 bool bNullRendering)
1667 {
1668 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1669
1670 CODECHAL_ENCODE_FUNCTION_ENTER;
1671
1672 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1673
1674 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, bNullRendering));
1675 return eStatus;
1676 }
1677
SendPrologWithFrameTracking(PMOS_COMMAND_BUFFER cmdBuffer,bool frameTrackingRequested,MHW_MI_MMIOREGISTERS * mmioRegister)1678 MOS_STATUS CodechalEncodeHevcBase::SendPrologWithFrameTracking(
1679 PMOS_COMMAND_BUFFER cmdBuffer,
1680 bool frameTrackingRequested,
1681 MHW_MI_MMIOREGISTERS *mmioRegister)
1682 {
1683 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1684
1685 CODECHAL_ENCODE_FUNCTION_ENTER;
1686
1687 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1688
1689 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::SendPrologWithFrameTracking(cmdBuffer, frameTrackingRequested, mmioRegister));
1690
1691 return eStatus;
1692 }
1693
GetMaxMBPS(uint32_t levelIdc,uint32_t * maxMBPS,uint64_t * maxBytePerPic)1694 MOS_STATUS CodechalEncodeHevcBase::GetMaxMBPS(uint32_t levelIdc, uint32_t* maxMBPS, uint64_t* maxBytePerPic)
1695 {
1696 CODECHAL_ENCODE_FUNCTION_ENTER;
1697
1698 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1699
1700 CODECHAL_ENCODE_CHK_NULL_RETURN(maxMBPS);
1701 CODECHAL_ENCODE_CHK_NULL_RETURN(maxBytePerPic);
1702
1703 switch (levelIdc)
1704 {
1705 case 30:
1706 *maxMBPS = 552960;
1707 *maxBytePerPic = 36864; break;
1708 case 60:
1709 *maxMBPS = 3686400;
1710 *maxBytePerPic = 122880; break;
1711 case 63:
1712 *maxMBPS = 7372800;
1713 *maxBytePerPic = 245760; break;
1714 case 90:
1715 *maxMBPS = 16588800;
1716 *maxBytePerPic = 552760; break;
1717 case 93:
1718 *maxMBPS = 33177600;
1719 *maxBytePerPic = 983040; break;
1720 case 120:
1721 *maxMBPS = 66846720;
1722 *maxBytePerPic = 2228224; break;
1723 case 123:
1724 *maxMBPS = 133693440;
1725 *maxBytePerPic = 2228224; break;
1726 case 150:
1727 *maxMBPS = 267386880;
1728 *maxBytePerPic = 8912896; break;
1729 case 153:
1730 *maxMBPS = 534773760;
1731 *maxBytePerPic = 8912896; break;
1732 case 156:
1733 *maxMBPS = 1069547520;
1734 *maxBytePerPic = 8912896; break;
1735 case 180:
1736 *maxMBPS = 1069547520;
1737 *maxBytePerPic = 35651584; break;
1738 case 183:
1739 *maxMBPS = 2139095040;
1740 *maxBytePerPic = 35651584; break;
1741 case 186:
1742 *maxMBPS = 4278190080;
1743 *maxBytePerPic = 35651584; break;
1744 default:
1745 *maxMBPS = 16588800;
1746 *maxBytePerPic = 552760; // CModel defaults to level 3.0 value if not found,
1747 // we can do the same, just output that the issue exists and continue
1748 CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported LevelIDC setting for HEVC");
1749 break;
1750 }
1751
1752 return eStatus;
1753 }
1754
GetProfileLevelMaxFrameSize()1755 uint32_t CodechalEncodeHevcBase::GetProfileLevelMaxFrameSize()
1756 {
1757 CODECHAL_ENCODE_FUNCTION_ENTER;
1758
1759 uint8_t minCR = 2;
1760 float_t formatFactor = 1.5;
1761 float_t fminCrScale = 1.0;
1762 uint32_t maxMBPS;
1763 uint64_t maxBytePerPic;
1764 int32_t levelIdc = m_hevcSeqParams->Level * 3;
1765
1766 if (levelIdc == 186 || levelIdc == 150)
1767 {
1768 minCR = 6;
1769 }
1770 else if (levelIdc >150)
1771 {
1772 minCR = 8;
1773 }
1774 else if (levelIdc >93)
1775 {
1776 minCR = 4;
1777 }
1778
1779 if (m_hevcSeqParams->chroma_format_idc == 0)
1780 {
1781 if (m_hevcSeqParams->bit_depth_luma_minus8 == 0)
1782 formatFactor = 1.0;
1783 else if (m_hevcSeqParams->bit_depth_luma_minus8 == 8)
1784 formatFactor = 2.0;
1785 }
1786 else if (m_hevcSeqParams->chroma_format_idc == 1)
1787 {
1788 if (m_hevcSeqParams->bit_depth_luma_minus8 == 2)
1789 {
1790 formatFactor = 1.875;
1791 }
1792 else if (m_hevcSeqParams->bit_depth_luma_minus8 == 4)
1793 {
1794 formatFactor = 2.25;
1795 }
1796 }
1797 else if (m_hevcSeqParams->chroma_format_idc == 2)
1798 {
1799 fminCrScale = 0.5;
1800 if (m_hevcSeqParams->bit_depth_luma_minus8 == 2)
1801 {
1802 formatFactor = 2.5;
1803 }
1804 else if (m_hevcSeqParams->bit_depth_luma_minus8 == 4)
1805 {
1806 formatFactor = 3.0;
1807 }
1808 }
1809 else
1810 {
1811 fminCrScale = 0.5;
1812 formatFactor = 3.0;
1813
1814 if (m_hevcSeqParams->bit_depth_luma_minus8 == 2)
1815 {
1816 formatFactor = 3.75;
1817 }
1818 else if (m_hevcSeqParams->bit_depth_luma_minus8 == 4)
1819 {
1820 formatFactor = 4.5;
1821 }
1822 }
1823
1824 fminCrScale *= minCR;
1825 formatFactor /= fminCrScale;
1826 GetMaxMBPS(levelIdc, &maxMBPS, &maxBytePerPic);
1827 auto maxBytePerPicNot0 = (uint64_t)((((float_t)maxMBPS * (float_t)m_hevcSeqParams->FrameRate.Denominator) / (float_t)m_hevcSeqParams->FrameRate.Numerator) * formatFactor);
1828 uint32_t profileLevelMaxFrame = 0;
1829
1830 uint32_t userMaxFrameSize = m_hevcSeqParams->UserMaxIFrameSize;
1831 if ((m_hevcPicParams->CodingType != I_TYPE) && (m_hevcSeqParams->UserMaxPBFrameSize > 0))
1832 {
1833 userMaxFrameSize = m_hevcSeqParams->UserMaxPBFrameSize;
1834 }
1835
1836 if (userMaxFrameSize != 0)
1837 {
1838 profileLevelMaxFrame = (uint32_t)MOS_MIN(userMaxFrameSize, maxBytePerPic);
1839 profileLevelMaxFrame = (uint32_t)MOS_MIN(maxBytePerPicNot0, profileLevelMaxFrame);
1840 }
1841 else {
1842 profileLevelMaxFrame = (uint32_t)MOS_MIN(maxBytePerPicNot0, maxBytePerPic);
1843 }
1844
1845 profileLevelMaxFrame = (uint32_t)MOS_MIN((m_frameHeight * m_frameWidth), profileLevelMaxFrame);
1846
1847 return profileLevelMaxFrame;
1848 }
1849
CalcTransformSkipParameters(MHW_VDBOX_ENCODE_HEVC_TRANSFORM_SKIP_PARAMS & params)1850 void CodechalEncodeHevcBase::CalcTransformSkipParameters(
1851 MHW_VDBOX_ENCODE_HEVC_TRANSFORM_SKIP_PARAMS& params)
1852 {
1853 CODECHAL_ENCODE_FUNCTION_ENTER;
1854
1855 if (!m_hevcPicParams->transform_skip_enabled_flag)
1856 {
1857 return;
1858 }
1859
1860 params.Transformskip_enabled = true;
1861 int sliceQP = CalSliceQp();
1862
1863 int qpIdx = 0;
1864 if (sliceQP <= 22)
1865 {
1866 qpIdx = 0;
1867 }
1868 else if (sliceQP <= 27)
1869 {
1870 qpIdx = 1;
1871 }
1872 else if (sliceQP <= 32)
1873 {
1874 qpIdx = 2;
1875 }
1876 else
1877 {
1878 qpIdx = 3;
1879 }
1880
1881 params.Transformskip_lambda = TransformSkipLambdaTable[sliceQP];
1882
1883 if (m_hevcPicParams->CodingType == I_TYPE)
1884 {
1885 params.Transformskip_Numzerocoeffs_Factor0 = TransformSkipCoeffsTable[qpIdx][0][0][0][0];
1886 params.Transformskip_Numzerocoeffs_Factor1 = TransformSkipCoeffsTable[qpIdx][0][0][1][0];
1887 params.Transformskip_Numnonzerocoeffs_Factor0 = TransformSkipCoeffsTable[qpIdx][0][0][0][1] + 32;
1888 params.Transformskip_Numnonzerocoeffs_Factor1 = TransformSkipCoeffsTable[qpIdx][0][0][1][1] + 32;
1889 }
1890 else
1891 {
1892 params.Transformskip_Numzerocoeffs_Factor0 = TransformSkipCoeffsTable[qpIdx][1][0][0][0];
1893 params.Transformskip_Numzerocoeffs_Factor1 = TransformSkipCoeffsTable[qpIdx][1][0][1][0];
1894 params.Transformskip_Numnonzerocoeffs_Factor0 = TransformSkipCoeffsTable[qpIdx][1][0][0][1] + 32;
1895 params.Transformskip_Numnonzerocoeffs_Factor1 = TransformSkipCoeffsTable[qpIdx][1][0][1][1] + 32;
1896 }
1897 }
1898
SetSemaphoreMem(PMOS_RESOURCE semaphoreMem,PMOS_COMMAND_BUFFER cmdBuffer,uint32_t value)1899 MOS_STATUS CodechalEncodeHevcBase::SetSemaphoreMem(
1900 PMOS_RESOURCE semaphoreMem,
1901 PMOS_COMMAND_BUFFER cmdBuffer,
1902 uint32_t value)
1903 {
1904 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1905
1906 CODECHAL_ENCODE_FUNCTION_ENTER;
1907
1908 CODECHAL_ENCODE_CHK_NULL_RETURN(semaphoreMem);
1909 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1910
1911 MHW_MI_STORE_DATA_PARAMS storeDataParams;
1912 MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
1913 storeDataParams.pOsResource = semaphoreMem;
1914 storeDataParams.dwResourceOffset = 0;
1915 storeDataParams.dwValue = value;
1916
1917 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(
1918 cmdBuffer,
1919 &storeDataParams));
1920
1921 return eStatus;
1922 }
1923
SendHWWaitCommand(PMOS_RESOURCE semaphoreMem,PMOS_COMMAND_BUFFER cmdBuffer,uint32_t semValue)1924 MOS_STATUS CodechalEncodeHevcBase::SendHWWaitCommand(
1925 PMOS_RESOURCE semaphoreMem,
1926 PMOS_COMMAND_BUFFER cmdBuffer,
1927 uint32_t semValue)
1928 {
1929 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1930
1931 CODECHAL_ENCODE_FUNCTION_ENTER;
1932
1933 CODECHAL_ENCODE_CHK_NULL_RETURN(semaphoreMem);
1934 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1935
1936 MHW_MI_SEMAPHORE_WAIT_PARAMS miSemaphoreWaitParams;
1937 MOS_ZeroMemory(&miSemaphoreWaitParams, sizeof(miSemaphoreWaitParams));
1938 miSemaphoreWaitParams.presSemaphoreMem = semaphoreMem;
1939 miSemaphoreWaitParams.bPollingWaitMode = true;
1940 miSemaphoreWaitParams.dwSemaphoreData = semValue;
1941 miSemaphoreWaitParams.CompareOperation = MHW_MI_SAD_EQUAL_SDD;
1942
1943 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiSemaphoreWaitCmd(cmdBuffer, &miSemaphoreWaitParams));
1944
1945 return eStatus;
1946 }
1947
SendMIAtomicCmd(PMOS_RESOURCE semaMem,uint32_t immData,MHW_COMMON_MI_ATOMIC_OPCODE opCode,PMOS_COMMAND_BUFFER cmdBuffer)1948 MOS_STATUS CodechalEncodeHevcBase::SendMIAtomicCmd(
1949 PMOS_RESOURCE semaMem,
1950 uint32_t immData,
1951 MHW_COMMON_MI_ATOMIC_OPCODE opCode,
1952 PMOS_COMMAND_BUFFER cmdBuffer
1953 )
1954 {
1955 MHW_MI_ATOMIC_PARAMS atomicParams;
1956 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1957
1958 CODECHAL_ENCODE_FUNCTION_ENTER;
1959
1960 MOS_ZeroMemory((&atomicParams), sizeof(atomicParams));
1961 atomicParams.pOsResource = semaMem;
1962 atomicParams.dwDataSize = sizeof(uint32_t);
1963 atomicParams.Operation = opCode;
1964 atomicParams.bInlineData = true;
1965 atomicParams.dwOperand1Data[0] = immData;
1966 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiAtomicCmd(cmdBuffer, &atomicParams));
1967
1968 return eStatus;
1969 }
1970
WaitForVDBOX(PMOS_COMMAND_BUFFER cmdBuffer)1971 MOS_STATUS CodechalEncodeHevcBase::WaitForVDBOX(PMOS_COMMAND_BUFFER cmdBuffer)
1972 {
1973 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1974
1975 CODECHAL_ENCODE_FUNCTION_ENTER;
1976
1977 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1978
1979 if (!m_firstFrame &&
1980 !Mos_ResourceIsNull(&m_refSync[m_lastMbCodeIndex].resSemaphoreMem.sResource))
1981 {
1982 CODECHAL_ENCODE_CHK_STATUS_RETURN(
1983 SendHWWaitCommand(
1984 &m_refSync[m_lastMbCodeIndex].resSemaphoreMem.sResource,
1985 cmdBuffer,
1986 1));
1987 }
1988
1989 //keep these codes here, in case later we need support parallel frame PAK (need more than one set of internal buffers used by PAK HW).
1990 #if 0
1991 if (m_pictureCodingType == I_TYPE)
1992 {
1993 return eStatus;
1994 }
1995
1996 bool refHasBeenWaited[CODEC_NUM_TRACKED_BUFFERS] = { false };
1997
1998 // check all reference frames. If one of them has not be waited, then it needs to be wait and ensure it has been encoded completely.
1999 PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams = pHevcSliceParams;
2000 for (uint32_t s = 0; s < m_numSlices; s++, slcParams++)
2001 {
2002 for (auto ll = 0; ll < 2; ll++)
2003 {
2004 uint32_t numRef = (ll == 0) ? slcParams->num_ref_idx_l0_active_minus1 :
2005 slcParams->num_ref_idx_l1_active_minus1;
2006
2007 for (uint32_t i = 0; i <= numRef; i++)
2008 {
2009 CODEC_PICTURE refPic = slcParams->RefPicList[ll][i];
2010 if (!CodecHal_PictureIsInvalid(refPic) &&
2011 !CodecHal_PictureIsInvalid(pHevcPicParams->RefFrameList[refPic.FrameIdx]))
2012 {
2013 uint32_t idx = pHevcPicParams->RefFrameList[refPic.FrameIdx].FrameIdx;
2014 uint8_t ucMbCodeIdx = pRefList[idx]->ucMbCodeIdx;
2015
2016 if (ucMbCodeIdx >= CODEC_NUM_TRACKED_BUFFERS)
2017 {
2018 // MB code index is wrong
2019 eStatus = MOS_STATUS_INVALID_PARAMETER;
2020 return eStatus;
2021 }
2022
2023 if (refHasBeenWaited[ucMbCodeIdx] || Mos_ResourceIsNull(&RefSync[ucMbCodeIdx].resSemaphoreMem.sResource))
2024 {
2025 continue;
2026 }
2027
2028 // Use HW wait command
2029 CODECHAL_ENCODE_CHK_STATUS_RETURN(
2030 SendHWWaitCommand(
2031 &RefSync[ucMbCodeIdx].resSemaphoreMem.sResource,
2032 cmdBuffer, 1));
2033
2034 refHasBeenWaited[ucMbCodeIdx] = true;
2035 }
2036 }
2037 }
2038 }
2039 #endif
2040 return eStatus;
2041 }
2042
ReadBrcPakStatistics(PMOS_COMMAND_BUFFER cmdBuffer,EncodeReadBrcPakStatsParams * params)2043 MOS_STATUS CodechalEncodeHevcBase::ReadBrcPakStatistics(
2044 PMOS_COMMAND_BUFFER cmdBuffer,
2045 EncodeReadBrcPakStatsParams* params)
2046 {
2047 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2048
2049 CODECHAL_ENCODE_FUNCTION_ENTER;
2050
2051 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
2052 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2053 CODECHAL_ENCODE_CHK_NULL_RETURN(params->presBrcPakStatisticBuffer);
2054 CODECHAL_ENCODE_CHK_NULL_RETURN(params->presStatusBuffer);
2055
2056 if (m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex()) \
2057 {
2058 CODECHAL_ENCODE_ASSERTMESSAGE("ERROR - vdbox index exceed the maximum");
2059 eStatus = MOS_STATUS_INVALID_PARAMETER;
2060 return eStatus;
2061 }
2062
2063 auto mmioRegisters = m_hcpInterface->GetMmioRegisters(m_vdboxIndex);
2064 CODECHAL_ENCODE_CHK_NULL_RETURN(mmioRegisters);
2065 MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParams;
2066 MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
2067 miStoreRegMemParams.presStoreBuffer = params->presBrcPakStatisticBuffer;
2068 miStoreRegMemParams.dwOffset = CODECHAL_OFFSETOF(CODECHAL_ENCODE_HEVC_PAK_STATS_BUFFER, HCP_BITSTREAM_BYTECOUNT_FRAME);
2069 miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncBitstreamBytecountFrameRegOffset;
2070 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
2071
2072 MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
2073 miStoreRegMemParams.presStoreBuffer = params->presBrcPakStatisticBuffer;
2074 miStoreRegMemParams.dwOffset = CODECHAL_OFFSETOF(CODECHAL_ENCODE_HEVC_PAK_STATS_BUFFER, HCP_BITSTREAM_BYTECOUNT_FRAME_NOHEADER);
2075 miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncBitstreamBytecountFrameNoHeaderRegOffset;
2076 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
2077
2078 MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
2079 miStoreRegMemParams.presStoreBuffer = params->presBrcPakStatisticBuffer;
2080 miStoreRegMemParams.dwOffset = CODECHAL_OFFSETOF(CODECHAL_ENCODE_HEVC_PAK_STATS_BUFFER, HCP_IMAGE_STATUS_CONTROL);
2081 miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncImageStatusCtrlRegOffset;
2082 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
2083
2084 MHW_MI_STORE_DATA_PARAMS storeDataParams;
2085 storeDataParams.pOsResource = params->presStatusBuffer;
2086 storeDataParams.dwResourceOffset = params->dwStatusBufNumPassesOffset;
2087 storeDataParams.dwValue = params->ucPass;
2088 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
2089
2090 return eStatus;
2091 }
2092
ReadHcpStatus(PMOS_COMMAND_BUFFER cmdBuffer)2093 MOS_STATUS CodechalEncodeHevcBase::ReadHcpStatus(PMOS_COMMAND_BUFFER cmdBuffer)
2094 {
2095 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2096
2097 CODECHAL_ENCODE_FUNCTION_ENTER;
2098
2099 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
2100
2101 EncodeStatusBuffer *encodeStatusBuf = &m_encodeStatusBuf;
2102
2103 uint32_t baseOffset =
2104 (encodeStatusBuf->wCurrIndex * encodeStatusBuf->dwReportSize) +
2105 sizeof(uint32_t) * 2; // pEncodeStatus is offset by 2 DWs in the resource
2106
2107 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
2108 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
2109 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
2110
2111 auto mmioRegisters = m_hcpInterface->GetMmioRegisters(m_vdboxIndex);
2112 CODECHAL_ENCODE_CHK_NULL_RETURN(mmioRegisters);
2113 MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParams;
2114 MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
2115 miStoreRegMemParams.presStoreBuffer = &encodeStatusBuf->resStatusBuffer;
2116 miStoreRegMemParams.dwOffset = baseOffset + encodeStatusBuf->dwBSByteCountOffset;
2117 miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncBitstreamBytecountFrameRegOffset;
2118 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
2119
2120 MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
2121 miStoreRegMemParams.presStoreBuffer = &encodeStatusBuf->resStatusBuffer;
2122 miStoreRegMemParams.dwOffset = baseOffset + encodeStatusBuf->dwBSSEBitCountOffset;
2123 miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncBitstreamSeBitcountFrameRegOffset;
2124 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
2125
2126 MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
2127 miStoreRegMemParams.presStoreBuffer = &encodeStatusBuf->resStatusBuffer;
2128 miStoreRegMemParams.dwOffset = baseOffset + encodeStatusBuf->dwQpStatusCountOffset;
2129 miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncQpStatusCountRegOffset;
2130 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
2131
2132 return eStatus;
2133 }
2134
ReadImageStatus(PMOS_COMMAND_BUFFER cmdBuffer)2135 MOS_STATUS CodechalEncodeHevcBase::ReadImageStatus(PMOS_COMMAND_BUFFER cmdBuffer)
2136 {
2137 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2138
2139 CODECHAL_ENCODE_FUNCTION_ENTER;
2140
2141 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
2142
2143 EncodeStatusBuffer *encodeStatusBuf = &m_encodeStatusBuf;
2144
2145 uint32_t baseOffset =
2146 (encodeStatusBuf->wCurrIndex * encodeStatusBuf->dwReportSize) +
2147 sizeof(uint32_t) * 2; // pEncodeStatus is offset by 2 DWs in the resource
2148
2149 auto mmioRegisters = m_hcpInterface->GetMmioRegisters(m_vdboxIndex);
2150 CODECHAL_ENCODE_CHK_NULL_RETURN(mmioRegisters);
2151 MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParams;
2152 MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
2153 miStoreRegMemParams.presStoreBuffer = &encodeStatusBuf->resStatusBuffer;
2154 miStoreRegMemParams.dwOffset = baseOffset + encodeStatusBuf->dwImageStatusMaskOffset;
2155 miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncImageStatusMaskRegOffset;
2156 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
2157
2158 MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
2159 miStoreRegMemParams.presStoreBuffer = &encodeStatusBuf->resStatusBuffer;
2160 miStoreRegMemParams.dwOffset = baseOffset + encodeStatusBuf->dwImageStatusCtrlOffset;
2161 miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncImageStatusCtrlRegOffset;
2162 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
2163
2164 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
2165 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
2166 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
2167
2168 return eStatus;
2169 }
2170
UserFeatureKeyReport()2171 MOS_STATUS CodechalEncodeHevcBase::UserFeatureKeyReport()
2172 {
2173 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2174 MediaUserSettingSharedPtr userSettingPtr = nullptr;
2175
2176 CODECHAL_ENCODE_FUNCTION_ENTER;
2177
2178 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::UserFeatureKeyReport())
2179
2180 CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_HEVC_ENCODE_MODE_ID, m_codecFunction, m_osInterface->pOsContext);
2181 CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_HEVC_ENCODE_ME_ENABLE_ID, m_hmeSupported, m_osInterface->pOsContext);
2182 CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_HEVC_ENCODE_16xME_ENABLE_ID, m_16xMeSupported, m_osInterface->pOsContext);
2183 CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_HEVC_ENCODE_32xME_ENABLE_ID, m_32xMeSupported, m_osInterface->pOsContext);
2184 CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_HEVC_ENCODE_26Z_ENABLE_ID, (!m_enable26WalkingPattern), m_osInterface->pOsContext);
2185 CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_RATECONTROL_METHOD_ID, m_hevcSeqParams->RateControlMethod, m_osInterface->pOsContext);
2186
2187 #if (_DEBUG || _RELEASE_INTERNAL)
2188 userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
2189 ReportUserSettingForDebug(
2190 userSettingPtr,
2191 __MEDIA_USER_FEATURE_VALUE_SIM_IN_USE,
2192 m_osInterface->bSimIsActive,
2193 MediaUserSetting::Group::Device);
2194 CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_HEVC_ENCODE_RDOQ_ENABLE_ID, m_hevcRdoqEnabled, m_osInterface->pOsContext);
2195 #endif
2196
2197 return eStatus;
2198 }
2199
GetStatusReport(EncodeStatus * encodeStatus,EncodeStatusReport * encodeStatusReport)2200 MOS_STATUS CodechalEncodeHevcBase::GetStatusReport(
2201 EncodeStatus *encodeStatus,
2202 EncodeStatusReport *encodeStatusReport)
2203 {
2204 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2205
2206 CODECHAL_ENCODE_FUNCTION_ENTER;
2207
2208 CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatus);
2209 CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatusReport);
2210
2211 // The last pass of BRC may have a zero value of hcpCumulativeFrameDeltaQp
2212 if (encodeStatus->ImageStatusCtrl.hcpTotalPass && encodeStatus->ImageStatusCtrl.hcpCumulativeFrameDeltaQp == 0)
2213 {
2214 encodeStatus->ImageStatusCtrl.hcpCumulativeFrameDeltaQp = encodeStatus->ImageStatusCtrlOfLastBRCPass.hcpCumulativeFrameDeltaQp;
2215 }
2216 encodeStatus->ImageStatusCtrlOfLastBRCPass.hcpCumulativeFrameDeltaQp = 0;
2217
2218 encodeStatusReport->CodecStatus = CODECHAL_STATUS_SUCCESSFUL;
2219 encodeStatusReport->bitstreamSize = encodeStatus->dwMFCBitstreamByteCountPerFrame + encodeStatus->dwHeaderBytesInserted;
2220
2221 encodeStatusReport->PanicMode = encodeStatus->ImageStatusCtrl.Panic;
2222 encodeStatusReport->AverageQp = 0;
2223 encodeStatusReport->QpY = 0;
2224 encodeStatusReport->SuggestedQpYDelta = encodeStatus->ImageStatusCtrl.hcpCumulativeFrameDeltaQp;
2225 encodeStatusReport->NumberPasses = (unsigned char)encodeStatus->ImageStatusCtrl.hcpTotalPass + 1; //initial pass is considered to be 0,hence +1 to report;
2226 CODECHAL_ENCODE_VERBOSEMESSAGE("Single Pipe Mode Exectued PAK Pass number: %d\n", encodeStatusReport->NumberPasses);
2227
2228 if (m_frameWidth != 0 && m_frameHeight != 0)
2229 {
2230 uint32_t log2LcuSize = 2;
2231
2232 //The CumulativeQp from the PAK has accumulation unit of LCU, so we align and divide height, width by LCU size
2233 if ((m_codecFunction == CODECHAL_FUNCTION_FEI_ENC_PAK) ||
2234 (m_codecFunction == (CODECHAL_FUNCTION_FEI_ENC | CODECHAL_FUNCTION_FEI_ENC_PAK)))
2235 {
2236 log2LcuSize = m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3;
2237 }
2238
2239 // Based on HW team:
2240 // The CumulativeQp from the PAK accumulated at TU level and normalized to TU4x4
2241 // qp(for TU 8x8) = qp*4
2242 // qp(for TU 16x16) = qp *16
2243 // qp(for TU 32x32) = qp*64
2244 // all these qp are accumulated for entire frame.
2245 // the HW will ceil the CumulativeQp number to max (24 bit)
2246
2247 encodeStatusReport->QpY = encodeStatusReport->AverageQp =
2248 (uint8_t)(((uint32_t)encodeStatus->QpStatusCount.hcpCumulativeQP)
2249 / ((MOS_ALIGN_CEIL(m_frameWidth, (1 << log2LcuSize)) >> log2LcuSize) *
2250 (MOS_ALIGN_CEIL(m_frameHeight, (1 << log2LcuSize)) >> log2LcuSize)));
2251 }
2252
2253 if (!Mos_ResourceIsNull(&m_resFrameStatStreamOutBuffer))
2254 {
2255 CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculatePSNR(encodeStatus, encodeStatusReport));
2256 }
2257 return eStatus;
2258 }
2259
InitializePicture(const EncoderParams & params)2260 MOS_STATUS CodechalEncodeHevcBase::InitializePicture(const EncoderParams& params)
2261 {
2262 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2263
2264 CODECHAL_ENCODE_FUNCTION_ENTER;
2265
2266 m_hevcSeqParams = (PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS)(params.pSeqParams);
2267 m_hevcPicParams = (PCODEC_HEVC_ENCODE_PICTURE_PARAMS)(params.pPicParams);
2268 m_hevcSliceParams = (PCODEC_HEVC_ENCODE_SLICE_PARAMS)params.pSliceParams;
2269 m_hevcFeiPicParams = (CodecEncodeHevcFeiPicParams *)params.pFeiPicParams;
2270 m_hevcIqMatrixParams = (PCODECHAL_HEVC_IQ_MATRIX_PARAMS)params.pIQMatrixBuffer;
2271 m_nalUnitParams = params.ppNALUnitParams;
2272
2273 CODECHAL_ENCODE_CHK_NULL_RETURN(m_hevcSeqParams);
2274 CODECHAL_ENCODE_CHK_NULL_RETURN(m_hevcPicParams);
2275 CODECHAL_ENCODE_CHK_NULL_RETURN(m_hevcSliceParams);
2276 CODECHAL_ENCODE_CHK_NULL_RETURN(m_hevcIqMatrixParams);
2277 CODECHAL_ENCODE_CHK_NULL_RETURN(m_nalUnitParams);
2278
2279 CODECHAL_ENCODE_CHK_STATUS_RETURN(PlatformCapabilityCheck());
2280
2281 if (CodecHalIsFeiEncode(m_codecFunction))
2282 {
2283 CODECHAL_ENCODE_CHK_NULL_RETURN(m_hevcFeiPicParams);
2284 m_hevcSeqParams->TargetUsage = 0x04;
2285 }
2286
2287 if (m_newSeq)
2288 {
2289 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
2290
2291 if (m_hevcSeqParams->log2_min_coding_block_size_minus3)
2292 {
2293 m_cscDsState->SetHcpReconAlignment(1 << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3));
2294 }
2295 }
2296
2297 if (const_cast<EncoderParams *>(¶ms)->bAcceleratorHeaderPackingCaps)
2298 {
2299 HevcHeaderPacker Packer;
2300 Packer.SliceHeaderPacker(const_cast<EncoderParams *>(¶ms));
2301 }
2302
2303 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPictureStructs());
2304 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSliceStructs());
2305
2306 // Scaling occurs when either HME or BRC is enabled
2307 m_scalingEnabled = m_hmeSupported || m_brcEnabled;
2308 m_useRawForRef = m_hevcPicParams->bUseRawPicForRef;
2309
2310 if (m_hevcPicParams->SkipFrameFlag == FRAME_SKIP_NORMAL)
2311 {
2312 m_skipFrameFlag = m_hevcPicParams->SkipFrameFlag;
2313 m_numSkipFrames = m_hevcPicParams->NumSkipFrames;
2314 m_sizeSkipFrames = m_hevcPicParams->SizeSkipFrames;
2315 }
2316
2317 m_pictureStatesSize = m_defaultPictureStatesSize;
2318 m_picturePatchListSize = m_defaultPicturePatchListSize;
2319
2320 m_sliceStatesSize = m_defaultSliceStatesSize;
2321 m_slicePatchListSize = m_defaultSlicePatchListSize;
2322
2323 // Mb Qp data
2324 m_mbQpDataEnabled = params.bMbQpDataEnabled;
2325 if (m_mbQpDataEnabled)
2326 {
2327 m_mbQpDataSurface = *(params.psMbQpDataSurface);
2328 }
2329
2330 CODECHAL_DEBUG_TOOL(
2331 m_debugInterface->m_currPic = m_hevcPicParams->CurrOriginalPic;
2332 m_debugInterface->m_bufferDumpFrameNum = m_storeData;
2333 m_debugInterface->m_frameType = m_pictureCodingType;
2334
2335 if (m_newSeq) {
2336 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParams(
2337 m_hevcSeqParams));
2338 }
2339
2340 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpPicParams(
2341 m_hevcPicParams));
2342
2343 if (CodecHalIsFeiEncode(m_codecFunction)) {
2344 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpFeiPicParams(
2345 m_hevcFeiPicParams));
2346 }
2347
2348 for (uint32_t i = 0; i < m_numSlices; i++) {
2349 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSliceParams(
2350 &m_hevcSliceParams[i],
2351 m_hevcPicParams));
2352 })
2353
2354 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetStatusReportParams(
2355 m_refList[m_currReconstructedPic.FrameIdx]));
2356
2357 m_bitstreamUpperBound = m_encodeParams.dwBitstreamSize;
2358
2359 return eStatus;
2360 }
2361
SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS & pipeModeSelectParams)2362 void CodechalEncodeHevcBase::SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS& pipeModeSelectParams)
2363 {
2364 pipeModeSelectParams = {};
2365 pipeModeSelectParams.Mode = m_mode;
2366 pipeModeSelectParams.bStreamOutEnabled = m_vdencEnabled;
2367 pipeModeSelectParams.bVdencEnabled = m_vdencEnabled;
2368 pipeModeSelectParams.bRdoqEnable = m_hevcRdoqEnabled ? (m_pictureCodingType == I_TYPE ? m_hevcIFrameRdoqEnabled : 1) : 0;
2369 pipeModeSelectParams.bAdvancedRateControlEnable = m_vdencBrcEnabled;
2370
2371 if (m_hevcSeqParams->SAO_enabled_flag)
2372 {
2373 // uses pipe mode select command to tell if this is the first or second pass of SAO
2374 pipeModeSelectParams.bSaoFirstPass = !IsLastPass();
2375
2376 if (m_singleTaskPhaseSupportedInPak &&
2377 m_b2NdSaoPassNeeded &&
2378 m_brcEnabled)
2379 {
2380 if (GetCurrentPass() == m_uc2NdSaoPass - 1) // the last BRC pass. This separates BRC passes and the 2nd pass SAO into different DMA buffer submissions
2381 {
2382 m_lastTaskInPhase = true;
2383 }
2384 else if (GetCurrentPass() == m_uc2NdSaoPass) // the 2nd SAO pass
2385 {
2386 m_firstTaskInPhase = true;
2387 m_lastTaskInPhase = true;
2388 }
2389 }
2390 }
2391 }
2392
SetHcpSrcSurfaceParams(MHW_VDBOX_SURFACE_PARAMS & srcSurfaceParams)2393 void CodechalEncodeHevcBase::SetHcpSrcSurfaceParams(MHW_VDBOX_SURFACE_PARAMS& srcSurfaceParams)
2394 {
2395 MOS_ZeroMemory(&srcSurfaceParams, sizeof(srcSurfaceParams));
2396 srcSurfaceParams.Mode = m_mode;
2397 srcSurfaceParams.psSurface = m_rawSurfaceToPak;
2398 srcSurfaceParams.ucSurfaceStateId = CODECHAL_HCP_SRC_SURFACE_ID;
2399 srcSurfaceParams.ucBitDepthLumaMinus8 = m_hevcSeqParams->bit_depth_luma_minus8;
2400 srcSurfaceParams.ucBitDepthChromaMinus8 = m_hevcSeqParams->bit_depth_chroma_minus8;
2401 srcSurfaceParams.bDisplayFormatSwizzle = m_hevcPicParams->bDisplayFormatSwizzle;
2402 srcSurfaceParams.ChromaType = m_outputChromaFormat;
2403 srcSurfaceParams.bSrc8Pak10Mode = false; //No usage for 8->10 bit encode
2404 srcSurfaceParams.dwActualHeight = ((m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3));
2405 #ifdef _MMC_SUPPORTED
2406 m_mmcState->SetSurfaceState(&srcSurfaceParams);
2407 #endif
2408 }
2409
SetHcpReconSurfaceParams(MHW_VDBOX_SURFACE_PARAMS & reconSurfaceParams)2410 void CodechalEncodeHevcBase::SetHcpReconSurfaceParams(MHW_VDBOX_SURFACE_PARAMS& reconSurfaceParams)
2411 {
2412 MOS_ZeroMemory(&reconSurfaceParams, sizeof(reconSurfaceParams));
2413 reconSurfaceParams.Mode = m_mode;
2414 reconSurfaceParams.psSurface = &m_reconSurface;
2415 reconSurfaceParams.ucSurfaceStateId = CODECHAL_HCP_DECODED_SURFACE_ID;
2416 reconSurfaceParams.ucBitDepthLumaMinus8 = m_hevcSeqParams->bit_depth_luma_minus8;
2417 reconSurfaceParams.ucBitDepthChromaMinus8 = m_hevcSeqParams->bit_depth_chroma_minus8;
2418 reconSurfaceParams.ChromaType = m_outputChromaFormat;
2419 reconSurfaceParams.dwActualHeight = ((m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3));
2420 reconSurfaceParams.dwReconSurfHeight = m_rawSurfaceToPak->dwHeight;
2421 #ifdef _MMC_SUPPORTED
2422 m_mmcState->SetSurfaceState(&reconSurfaceParams);
2423 #endif
2424 }
2425
SetHcpRefSurfaceParams(MHW_VDBOX_SURFACE_PARAMS & refSurfaceParams)2426 void CodechalEncodeHevcBase::SetHcpRefSurfaceParams(MHW_VDBOX_SURFACE_PARAMS &refSurfaceParams)
2427 {
2428 MOS_ZeroMemory(&refSurfaceParams, sizeof(refSurfaceParams));
2429 refSurfaceParams.Mode = m_mode;
2430 refSurfaceParams.psSurface = &m_reconSurface;
2431 refSurfaceParams.ucSurfaceStateId = CODECHAL_HCP_REF_SURFACE_ID;
2432 refSurfaceParams.ucBitDepthLumaMinus8 = m_hevcSeqParams->bit_depth_luma_minus8;
2433 refSurfaceParams.ucBitDepthChromaMinus8 = m_hevcSeqParams->bit_depth_chroma_minus8;
2434 refSurfaceParams.ChromaType = m_outputChromaFormat;
2435 refSurfaceParams.dwActualHeight = ((m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3));
2436 refSurfaceParams.dwReconSurfHeight = m_rawSurfaceToPak->dwHeight;
2437 #ifdef _MMC_SUPPORTED
2438 m_mmcState->SetSurfaceState(&refSurfaceParams);
2439 #endif
2440 }
2441
SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)2442 void CodechalEncodeHevcBase::SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
2443 {
2444 CODECHAL_ENCODE_FUNCTION_ENTER;
2445
2446 pipeBufAddrParams = {};
2447 pipeBufAddrParams.Mode = m_mode;
2448 pipeBufAddrParams.psPreDeblockSurface = &m_reconSurface;
2449 pipeBufAddrParams.psPostDeblockSurface = &m_reconSurface;
2450 pipeBufAddrParams.psRawSurface = m_rawSurfaceToPak;
2451 pipeBufAddrParams.presStreamOutBuffer = m_vdencEnabled ? &m_resStreamOutBuffer[0] : nullptr;
2452 pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resDeblockingFilterRowStoreScratchBuffer;
2453 pipeBufAddrParams.presDeblockingFilterTileRowStoreScratchBuffer = &m_resDeblockingFilterTileRowStoreScratchBuffer;
2454 pipeBufAddrParams.presDeblockingFilterColumnRowStoreScratchBuffer = &m_resDeblockingFilterColumnRowStoreScratchBuffer;
2455
2456 pipeBufAddrParams.presMetadataLineBuffer = &m_resMetadataLineBuffer;
2457 pipeBufAddrParams.presMetadataTileLineBuffer = &m_resMetadataTileLineBuffer;
2458 pipeBufAddrParams.presMetadataTileColumnBuffer = &m_resMetadataTileColumnBuffer;
2459 pipeBufAddrParams.presSaoLineBuffer = &m_resSaoLineBuffer;
2460 pipeBufAddrParams.presSaoTileLineBuffer = &m_resSaoTileLineBuffer;
2461 pipeBufAddrParams.presSaoTileColumnBuffer = &m_resSaoTileColumnBuffer;
2462 pipeBufAddrParams.presCurMvTempBuffer = m_trackedBuf->GetMvTemporalBuffer(CODEC_CURR_TRACKED_BUFFER);
2463 pipeBufAddrParams.presLcuBaseAddressBuffer = &m_resLcuBaseAddressBuffer;
2464 pipeBufAddrParams.dwLcuStreamOutOffset = 0;
2465 pipeBufAddrParams.presLcuILDBStreamOutBuffer = &m_resLcuIldbStreamOutBuffer;
2466 pipeBufAddrParams.presSaoStreamOutBuffer = &m_resSaoStreamOutBuffer;
2467 pipeBufAddrParams.presFrameStatStreamOutBuffer = &m_resFrameStatStreamOutBuffer;
2468 pipeBufAddrParams.dwFrameStatStreamOutOffset = 0;
2469 pipeBufAddrParams.presSseSrcPixelRowStoreBuffer = &m_resSseSrcPixelRowStoreBuffer;
2470 pipeBufAddrParams.presPakCuLevelStreamoutBuffer =
2471 Mos_ResourceIsNull(&m_resPakcuLevelStreamoutData.sResource) ? nullptr : &m_resPakcuLevelStreamoutData.sResource;
2472 pipeBufAddrParams.bRawIs10Bit = m_is10BitHevc;
2473
2474 //add for B frame support
2475 if (m_pictureCodingType != I_TYPE)
2476 {
2477 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
2478 {
2479 if (!m_picIdx[i].bValid || !m_currUsedRefPic[i])
2480 {
2481 continue;
2482 }
2483
2484 uint8_t idx = m_picIdx[i].ucPicIdx;
2485 CodecHalGetResourceInfo(m_osInterface, &(m_refList[idx]->sRefReconBuffer));
2486
2487 uint8_t frameStoreId = (uint8_t)m_refIdxMapping[i];
2488 pipeBufAddrParams.presReferences[frameStoreId] = &(m_refList[idx]->sRefReconBuffer.OsResource);
2489
2490 uint8_t refMbCodeIdx = m_refList[idx]->ucScalingIdx;
2491 pipeBufAddrParams.presColMvTempBuffer[frameStoreId] = m_trackedBuf->GetMvTemporalBuffer(refMbCodeIdx);
2492 }
2493 }
2494 }
2495
SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS & indObjBaseAddrParams)2496 void CodechalEncodeHevcBase::SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS& indObjBaseAddrParams)
2497 {
2498 MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
2499 indObjBaseAddrParams.Mode = CODECHAL_ENCODE_MODE_HEVC;
2500 indObjBaseAddrParams.presMvObjectBuffer = &m_resMbCodeSurface;
2501 indObjBaseAddrParams.dwMvObjectOffset = m_mvOffset;
2502 indObjBaseAddrParams.dwMvObjectSize = m_mbCodeSize - m_mvOffset;
2503 indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer;
2504 indObjBaseAddrParams.dwPakBaseObjectSize =m_bitstreamUpperBound;
2505 indObjBaseAddrParams.presPakTileSizeStasBuffer = nullptr;
2506 indObjBaseAddrParams.dwPakTileSizeStasBufferSize = 0;
2507 indObjBaseAddrParams.dwPakTileSizeRecordOffset = 0;
2508 }
2509
SetHcpQmStateParams(MHW_VDBOX_QM_PARAMS & fqmParams,MHW_VDBOX_QM_PARAMS & qmParams)2510 void CodechalEncodeHevcBase::SetHcpQmStateParams(MHW_VDBOX_QM_PARAMS& fqmParams, MHW_VDBOX_QM_PARAMS& qmParams)
2511 {
2512 MOS_ZeroMemory(&fqmParams, sizeof(fqmParams));
2513 fqmParams.Standard = CODECHAL_HEVC;
2514 fqmParams.pHevcIqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams;
2515
2516 MOS_ZeroMemory(&qmParams, sizeof(qmParams));
2517 qmParams.Standard = CODECHAL_HEVC;
2518 qmParams.pHevcIqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams;
2519 }
2520
SetHcpPicStateParams(MHW_VDBOX_HEVC_PIC_STATE & picStateParams)2521 void CodechalEncodeHevcBase::SetHcpPicStateParams(MHW_VDBOX_HEVC_PIC_STATE& picStateParams)
2522 {
2523 CODECHAL_ENCODE_FUNCTION_ENTER;
2524
2525 picStateParams = {};
2526 picStateParams.pHevcEncSeqParams = m_hevcSeqParams;
2527 picStateParams.pHevcEncPicParams = m_hevcPicParams;
2528 picStateParams.bSAOEnable = m_hevcSeqParams->SAO_enabled_flag ? (m_hevcSliceParams->slice_sao_luma_flag || m_hevcSliceParams->slice_sao_chroma_flag) : 0;
2529 picStateParams.bUseVDEnc = m_vdencEnabled;
2530 picStateParams.bNotFirstPass = m_vdencEnabled && !IsFirstPass() ;
2531 picStateParams.bHevcRdoqEnabled = m_hevcRdoqEnabled ? (m_pictureCodingType == I_TYPE ? m_hevcIFrameRdoqEnabled : 1) : 0;
2532 picStateParams.bRDOQIntraTUDisable = m_hevcRdoqEnabled && (1 != m_hevcSeqParams->TargetUsage);
2533 picStateParams.wRDOQIntraTUThreshold = (uint16_t)m_rdoqIntraTuThreshold;
2534 picStateParams.bTransformSkipEnable = m_hevcPicParams->transform_skip_enabled_flag;
2535
2536 #if (_DEBUG || _RELEASE_INTERNAL)
2537 if (m_rdoqIntraTuOverride)
2538 {
2539 int32_t RDOQIntraTUThreshold = 0;
2540
2541 if (m_rdoqIntraTuThresholdOverride >= 100)
2542 {
2543 RDOQIntraTUThreshold = 65535;
2544 }
2545 else if (m_rdoqIntraTuThresholdOverride > 0)
2546 {
2547 uint32_t frameWidth = (m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3);
2548 uint32_t frameHeight = (m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3);
2549 int32_t frameSize = frameWidth * frameHeight;
2550 RDOQIntraTUThreshold = (((frameSize * m_rdoqIntraTuThreshold) / 100) >> 8);
2551
2552 uint16_t numPipe = m_numVdbox;
2553 if ((m_hevcPicParams->num_tile_columns_minus1 + 1) > m_numVdbox)
2554 {
2555 numPipe = 1;
2556 }
2557 if ((m_hevcPicParams->tiles_enabled_flag) && (numPipe > 1))
2558 {
2559 RDOQIntraTUThreshold /= numPipe;
2560 }
2561 if (RDOQIntraTUThreshold > 65535)
2562 {
2563 RDOQIntraTUThreshold = 65535;
2564 }
2565 }
2566
2567 picStateParams.bRDOQIntraTUDisable = m_rdoqIntraTuDisableOverride;
2568 picStateParams.wRDOQIntraTUThreshold = (uint16_t)RDOQIntraTUThreshold;
2569 }
2570 #endif
2571
2572 picStateParams.currPass = m_currPass;
2573 if (CodecHalIsFeiEncode(m_codecFunction) && m_hevcFeiPicParams && m_hevcFeiPicParams->dwMaxFrameSize)
2574 {
2575 picStateParams.deltaQp = m_hevcFeiPicParams->pDeltaQp;
2576 picStateParams.maxFrameSize = m_hevcFeiPicParams->dwMaxFrameSize;
2577 }
2578 }
2579
SetBatchBufferForPakSlices()2580 MOS_STATUS CodechalEncodeHevcBase::SetBatchBufferForPakSlices()
2581 {
2582 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2583
2584 CODECHAL_ENCODE_FUNCTION_ENTER;
2585
2586 m_useBatchBufferForPakSlices = m_singleTaskPhaseSupported && m_singleTaskPhaseSupportedInPak;
2587 m_batchBufferForPakSlicesStartOffset = 0;
2588
2589 if (m_useBatchBufferForPakSlices)
2590 {
2591 if (IsFirstPass())
2592 {
2593 // The same buffer is used for all slices for all passes
2594 uint32_t batchBufferForPakSlicesSize =
2595 (m_numPasses + 1) * m_numSlices * m_sliceStatesSize;
2596
2597 CODECHAL_ENCODE_ASSERT(batchBufferForPakSlicesSize);
2598
2599 if (batchBufferForPakSlicesSize >
2600 (uint32_t)m_batchBufferForPakSlices[m_currPakSliceIdx].iSize)
2601 {
2602 if (m_batchBufferForPakSlices[m_currPakSliceIdx].iSize)
2603 {
2604 CODECHAL_ENCODE_CHK_STATUS_RETURN(ReleaseBatchBufferForPakSlices(m_currPakSliceIdx));
2605 }
2606
2607 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBatchBufferForPakSlices(
2608 m_numSlices,
2609 m_numPasses));
2610 }
2611 }
2612
2613 CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_LockBb(
2614 m_osInterface,
2615 &m_batchBufferForPakSlices[m_currPakSliceIdx]));
2616 m_batchBufferForPakSlicesStartOffset = IsFirstPass() ? 0 : (uint32_t)m_batchBufferForPakSlices[m_currPakSliceIdx].iCurrent;
2617 }
2618
2619 return eStatus;
2620 }
2621
CreateMhwParams()2622 void CodechalEncodeHevcBase::CreateMhwParams()
2623 {
2624 m_sliceStateParams = MOS_New(MHW_VDBOX_HEVC_SLICE_STATE);
2625 m_pipeModeSelectParams = MOS_New(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS);
2626 m_pipeBufAddrParams = MOS_New(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS);
2627 }
2628
SetHcpSliceStateCommonParams(MHW_VDBOX_HEVC_SLICE_STATE & sliceStateParams)2629 void CodechalEncodeHevcBase::SetHcpSliceStateCommonParams(MHW_VDBOX_HEVC_SLICE_STATE& sliceStateParams)
2630 {
2631 CODECHAL_ENCODE_FUNCTION_ENTER;
2632
2633 sliceStateParams = {};
2634 sliceStateParams.presDataBuffer = &m_resMbCodeSurface;
2635 sliceStateParams.pHevcPicIdx = &(m_picIdx[0]);
2636 sliceStateParams.pEncodeHevcSeqParams = m_hevcSeqParams;
2637 sliceStateParams.pEncodeHevcPicParams = m_hevcPicParams;
2638 sliceStateParams.pBsBuffer = &m_bsBuffer;
2639 sliceStateParams.ppNalUnitParams = m_nalUnitParams;
2640 sliceStateParams.bBrcEnabled = m_brcEnabled;
2641 sliceStateParams.dwHeaderBytesInserted = 0;
2642 sliceStateParams.dwHeaderDummyBytes = 0;
2643 sliceStateParams.pRefIdxMapping = m_refIdxMapping;
2644 sliceStateParams.bIsLowDelay = m_lowDelay;
2645 sliceStateParams.RoundingIntra = m_roundingIntra;
2646 sliceStateParams.RoundingInter = m_roundingInter;
2647 }
2648
SetHcpSliceStateParams(MHW_VDBOX_HEVC_SLICE_STATE & sliceStateParams,PCODEC_ENCODER_SLCDATA slcData,uint32_t currSlcIdx)2649 void CodechalEncodeHevcBase::SetHcpSliceStateParams(
2650 MHW_VDBOX_HEVC_SLICE_STATE& sliceStateParams,
2651 PCODEC_ENCODER_SLCDATA slcData,
2652 uint32_t currSlcIdx)
2653 {
2654 CODECHAL_ENCODE_FUNCTION_ENTER;
2655
2656 sliceStateParams.pEncodeHevcSliceParams = &m_hevcSliceParams[currSlcIdx];
2657 sliceStateParams.dwDataBufferOffset = slcData[currSlcIdx].CmdOffset;
2658 sliceStateParams.dwOffset = slcData[currSlcIdx].SliceOffset;
2659 sliceStateParams.dwLength = slcData[currSlcIdx].BitSize;
2660 sliceStateParams.uiSkipEmulationCheckCount = slcData[currSlcIdx].SkipEmulationByteCount;
2661 sliceStateParams.dwSliceIndex = currSlcIdx;
2662 sliceStateParams.bLastSlice = (currSlcIdx == m_numSlices - 1);
2663 sliceStateParams.bFirstPass = IsFirstPass();
2664 sliceStateParams.bLastPass = IsLastPass();
2665 sliceStateParams.bInsertBeforeSliceHeaders = (currSlcIdx == 0);
2666 sliceStateParams.bSaoLumaFlag = (m_hevcSeqParams->SAO_enabled_flag) ? m_hevcSliceParams[currSlcIdx].slice_sao_luma_flag : 0;
2667 sliceStateParams.bSaoChromaFlag = (m_hevcSeqParams->SAO_enabled_flag) ? m_hevcSliceParams[currSlcIdx].slice_sao_chroma_flag : 0;
2668 sliceStateParams.DeblockingFilterDisable = m_hevcSliceParams[currSlcIdx].slice_deblocking_filter_disable_flag;
2669 sliceStateParams.TcOffsetDiv2 = m_hevcSliceParams[currSlcIdx].tc_offset_div2;
2670 sliceStateParams.BetaOffsetDiv2 = m_hevcSliceParams[currSlcIdx].beta_offset_div2;
2671
2672
2673 if (m_useBatchBufferForPakSlices)
2674 {
2675 sliceStateParams.pBatchBufferForPakSlices =
2676 &m_batchBufferForPakSlices[m_currPakSliceIdx];
2677 sliceStateParams.bSingleTaskPhaseSupported = true;
2678 sliceStateParams.dwBatchBufferForPakSlicesStartOffset = m_batchBufferForPakSlicesStartOffset;
2679 }
2680
2681 if (m_hevcPicParams->transform_skip_enabled_flag)
2682 {
2683 CalcTransformSkipParameters(sliceStateParams.EncodeHevcTransformSkipParams);
2684 }
2685 }
2686
AddHcpRefIdxCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_HEVC_SLICE_STATE params)2687 MOS_STATUS CodechalEncodeHevcBase::AddHcpRefIdxCmd(
2688 PMOS_COMMAND_BUFFER cmdBuffer,
2689 PMHW_BATCH_BUFFER batchBuffer,
2690 PMHW_VDBOX_HEVC_SLICE_STATE params)
2691 {
2692 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2693
2694 CODECHAL_ENCODE_FUNCTION_ENTER;
2695
2696 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2697 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pEncodeHevcSliceParams);
2698 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pEncodeHevcPicParams);
2699
2700 if (cmdBuffer == nullptr && batchBuffer == nullptr)
2701 {
2702 CODECHAL_ENCODE_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
2703 return MOS_STATUS_NULL_POINTER;
2704 }
2705
2706 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams = params->pEncodeHevcPicParams;
2707 PCODEC_HEVC_ENCODE_SLICE_PARAMS hevcSlcParams = params->pEncodeHevcSliceParams;
2708
2709 if (hevcSlcParams->slice_type != CODECHAL_ENCODE_HEVC_I_SLICE)
2710 {
2711 MHW_VDBOX_HEVC_REF_IDX_PARAMS refIdxParams;
2712
2713 refIdxParams.CurrPic = hevcPicParams->CurrReconstructedPic;
2714 refIdxParams.isEncode = true;
2715 refIdxParams.ucList = LIST_0;
2716 refIdxParams.ucNumRefForList = hevcSlcParams->num_ref_idx_l0_active_minus1 + 1;
2717 eStatus = MOS_SecureMemcpy(&refIdxParams.RefPicList, sizeof(refIdxParams.RefPicList),
2718 &hevcSlcParams->RefPicList, sizeof(hevcSlcParams->RefPicList));
2719 if (eStatus != MOS_STATUS_SUCCESS)
2720 {
2721 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2722 return eStatus;
2723 }
2724
2725 refIdxParams.hevcRefList = (void**)m_refList;
2726 refIdxParams.poc_curr_pic = hevcPicParams->CurrPicOrderCnt;
2727 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
2728 {
2729 refIdxParams.poc_list[i] = hevcPicParams->RefFramePOCList[i];
2730 }
2731
2732 refIdxParams.pRefIdxMapping = params->pRefIdxMapping;
2733 refIdxParams.RefFieldPicFlag = 0; // there is no interlaced support in encoder
2734 refIdxParams.RefBottomFieldFlag = 0; // there is no interlaced support in encoder
2735
2736 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpRefIdxStateCmd(cmdBuffer, batchBuffer, &refIdxParams));
2737
2738 if (hevcSlcParams->slice_type == CODECHAL_ENCODE_HEVC_B_SLICE)
2739 {
2740 refIdxParams.ucList = LIST_1;
2741 refIdxParams.ucNumRefForList = hevcSlcParams->num_ref_idx_l1_active_minus1 + 1;
2742 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpRefIdxStateCmd(cmdBuffer, batchBuffer, &refIdxParams));
2743 }
2744 }
2745
2746 return eStatus;
2747 }
2748
AddHcpPakInsertNALUs(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_HEVC_SLICE_STATE params)2749 MOS_STATUS CodechalEncodeHevcBase::AddHcpPakInsertNALUs(
2750 PMOS_COMMAND_BUFFER cmdBuffer,
2751 PMHW_BATCH_BUFFER batchBuffer,
2752 PMHW_VDBOX_HEVC_SLICE_STATE params)
2753 {
2754 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2755
2756 CODECHAL_ENCODE_FUNCTION_ENTER;
2757
2758 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2759 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
2760 CODECHAL_ENCODE_CHK_NULL_RETURN(params->ppNalUnitParams);
2761
2762 if (cmdBuffer == nullptr && batchBuffer == nullptr)
2763 {
2764 CODECHAL_ENCODE_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
2765 return MOS_STATUS_NULL_POINTER;
2766 }
2767
2768 //insert AU, SPS, PSP headers before first slice header
2769 if (params->bInsertBeforeSliceHeaders)
2770 {
2771 uint32_t maxBytesInPakInsertObjCmd = ((2 << 11) - 1) * 4; // 12 bits for Length field in PAK_INSERT_OBJ cmd
2772
2773 for (auto i = 0; i < HEVC_MAX_NAL_UNIT_TYPE; i++)
2774 {
2775 uint32_t nalunitPosiSize = params->ppNalUnitParams[i]->uiSize;
2776 uint32_t nalunitPosiOffset = params->ppNalUnitParams[i]->uiOffset;
2777
2778 while (nalunitPosiSize > 0)
2779 {
2780 uint32_t bitSize = MOS_MIN(maxBytesInPakInsertObjCmd * 8, nalunitPosiSize * 8);
2781 uint32_t offSet = nalunitPosiOffset;
2782
2783 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
2784 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
2785 pakInsertObjectParams.bEmulationByteBitsInsert = params->ppNalUnitParams[i]->bInsertEmulationBytes;
2786 pakInsertObjectParams.uiSkipEmulationCheckCount = params->ppNalUnitParams[i]->uiSkipEmulationCheckCount;
2787 pakInsertObjectParams.pBsBuffer = params->pBsBuffer;
2788 pakInsertObjectParams.dwBitSize = bitSize;
2789 pakInsertObjectParams.dwOffset = offSet;
2790 pakInsertObjectParams.pBatchBufferForPakSlices = batchBuffer;
2791 pakInsertObjectParams.bVdencInUse = params->bVdencInUse;
2792
2793 if (nalunitPosiSize > maxBytesInPakInsertObjCmd)
2794 {
2795 nalunitPosiSize -= maxBytesInPakInsertObjCmd;
2796 nalunitPosiOffset += maxBytesInPakInsertObjCmd;
2797 }
2798 else
2799 {
2800 nalunitPosiSize = 0;
2801 }
2802
2803 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPakInsertObject(cmdBuffer, &pakInsertObjectParams));
2804 }
2805 }
2806 }
2807
2808 return eStatus;
2809 }
2810
AddHcpPakInsertSliceHeader(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_HEVC_SLICE_STATE params)2811 MOS_STATUS CodechalEncodeHevcBase::AddHcpPakInsertSliceHeader(
2812 PMOS_COMMAND_BUFFER cmdBuffer,
2813 PMHW_BATCH_BUFFER batchBuffer,
2814 PMHW_VDBOX_HEVC_SLICE_STATE params)
2815 {
2816 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2817
2818 CODECHAL_ENCODE_FUNCTION_ENTER;
2819
2820 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2821 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
2822
2823 if (cmdBuffer == nullptr && batchBuffer == nullptr)
2824 {
2825 CODECHAL_ENCODE_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
2826 return MOS_STATUS_NULL_POINTER;
2827 }
2828
2829 // Insert slice header
2830 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
2831 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
2832 pakInsertObjectParams.bLastHeader = true;
2833 pakInsertObjectParams.bEmulationByteBitsInsert = true;
2834 pakInsertObjectParams.pBatchBufferForPakSlices = batchBuffer;
2835
2836 // App does the slice header packing, set the skip count passed by the app
2837 pakInsertObjectParams.uiSkipEmulationCheckCount = params->uiSkipEmulationCheckCount;
2838 pakInsertObjectParams.pBsBuffer = params->pBsBuffer;
2839 pakInsertObjectParams.dwBitSize = params->dwLength;
2840 pakInsertObjectParams.dwOffset = params->dwOffset;
2841 pakInsertObjectParams.bVdencInUse = params->bVdencInUse;
2842
2843 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPakInsertObject(
2844 cmdBuffer,
2845 &pakInsertObjectParams));
2846
2847 return eStatus;
2848 }
2849
CodechalEncodeHevcBase(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)2850 CodechalEncodeHevcBase::CodechalEncodeHevcBase(
2851 CodechalHwInterface* hwInterface,
2852 CodechalDebugInterface* debugInterface,
2853 PCODECHAL_STANDARD_INFO standardInfo)
2854 :CodechalEncoderState(hwInterface, debugInterface, standardInfo)
2855 {
2856 // initialze class members
2857 MOS_ZeroMemory(&m_resDeblockingFilterRowStoreScratchBuffer, sizeof(m_resDeblockingFilterRowStoreScratchBuffer));
2858 MOS_ZeroMemory(&m_resDeblockingFilterTileRowStoreScratchBuffer, sizeof(m_resDeblockingFilterTileRowStoreScratchBuffer));
2859 MOS_ZeroMemory(&m_resDeblockingFilterColumnRowStoreScratchBuffer, sizeof(m_resDeblockingFilterColumnRowStoreScratchBuffer));
2860 MOS_ZeroMemory(&m_resMetadataLineBuffer, sizeof(m_resMetadataLineBuffer));
2861 MOS_ZeroMemory(&m_resMetadataTileLineBuffer, sizeof(m_resMetadataTileLineBuffer));
2862 MOS_ZeroMemory(&m_resMetadataTileColumnBuffer, sizeof(m_resMetadataTileColumnBuffer));
2863 MOS_ZeroMemory(&m_resSaoLineBuffer, sizeof(m_resSaoLineBuffer));
2864 MOS_ZeroMemory(&m_resSaoTileLineBuffer, sizeof(m_resSaoTileLineBuffer));
2865 MOS_ZeroMemory(&m_resSaoTileColumnBuffer, sizeof(m_resSaoTileColumnBuffer));
2866 MOS_ZeroMemory(&m_resLcuBaseAddressBuffer, sizeof(m_resLcuBaseAddressBuffer));
2867 MOS_ZeroMemory(&m_resLcuIldbStreamOutBuffer, sizeof(m_resLcuIldbStreamOutBuffer));
2868 MOS_ZeroMemory(&m_resSaoStreamOutBuffer, sizeof(m_resSaoStreamOutBuffer));
2869 MOS_ZeroMemory(&m_resFrameStatStreamOutBuffer, sizeof(m_resFrameStatStreamOutBuffer));
2870 MOS_ZeroMemory(&m_resSseSrcPixelRowStoreBuffer, sizeof(m_resSseSrcPixelRowStoreBuffer));
2871 MOS_ZeroMemory(m_batchBufferForPakSlices, sizeof(m_batchBufferForPakSlices));
2872
2873 MOS_ZeroMemory(m_refSync, sizeof(m_refSync));
2874 MOS_ZeroMemory(m_refIdxMapping, sizeof(m_refIdxMapping));
2875
2876 MOS_ZeroMemory(m_currUsedRefPic, sizeof(m_currUsedRefPic));
2877 ;
2878 MOS_ZeroMemory(m_picIdx, sizeof(m_picIdx));
2879 MOS_ZeroMemory(m_refList, sizeof(m_refList));
2880
2881 MOS_ZeroMemory(&m_s4XMeMvDataBuffer, sizeof(m_s4XMeMvDataBuffer));
2882 MOS_ZeroMemory(&m_s16XMeMvDataBuffer, sizeof(m_s16XMeMvDataBuffer));
2883 MOS_ZeroMemory(&m_s32XMeMvDataBuffer, sizeof(m_s32XMeMvDataBuffer));
2884 MOS_ZeroMemory(&m_s4XMeDistortionBuffer, sizeof(m_s4XMeDistortionBuffer));
2885 MOS_ZeroMemory(&m_mbQpDataSurface, sizeof(m_mbQpDataSurface));
2886 MOS_ZeroMemory(&m_resPakcuLevelStreamoutData, sizeof(m_resPakcuLevelStreamoutData));
2887
2888 m_fieldScalingOutputInterleaved = false;
2889 m_interlacedFieldDisabled = true;
2890 m_firstField = true; // Each frame is treated as the first field
2891
2892 m_userFeatureKeyReport = true;
2893 m_useCmScalingKernel = true;
2894 m_codecGetStatusReportDefined = true; // Codec specific GetStatusReport is implemented.
2895
2896 m_vdboxOneDefaultUsed = true;
2897 }
2898
CalculatePictureStateCommandSize()2899 MOS_STATUS CodechalEncodeHevcBase::CalculatePictureStateCommandSize()
2900 {
2901 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2902
2903 CODECHAL_ENCODE_FUNCTION_ENTER;
2904
2905 MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
2906 CODECHAL_ENCODE_CHK_STATUS_RETURN(
2907 m_hwInterface->GetHxxStateCommandSize(
2908 CODECHAL_ENCODE_MODE_HEVC,
2909 &m_defaultPictureStatesSize,
2910 &m_defaultPicturePatchListSize,
2911 &stateCmdSizeParams));
2912
2913 return eStatus;
2914 }
2915
AddHcpPipeBufAddrCmd(PMOS_COMMAND_BUFFER cmdBuffer)2916 MOS_STATUS CodechalEncodeHevcBase::AddHcpPipeBufAddrCmd(
2917 PMOS_COMMAND_BUFFER cmdBuffer)
2918 {
2919 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2920
2921 CODECHAL_ENCODE_FUNCTION_ENTER;
2922
2923 *m_pipeBufAddrParams = {};
2924 SetHcpPipeBufAddrParams(*m_pipeBufAddrParams);
2925 #ifdef _MMC_SUPPORTED
2926 m_mmcState->SetPipeBufAddr(m_pipeBufAddrParams);
2927 #endif
2928 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeBufAddrCmd(cmdBuffer, m_pipeBufAddrParams));
2929
2930 return eStatus;
2931 }
2932
ComputeTemporalDifferent(CODEC_PICTURE refPic)2933 short CodechalEncodeHevcBase::ComputeTemporalDifferent(CODEC_PICTURE refPic)
2934 {
2935 short diff_poc = 0;
2936
2937 if (!CodecHal_PictureIsInvalid(refPic))
2938 {
2939 diff_poc = m_hevcPicParams->CurrPicOrderCnt - m_hevcPicParams->RefFramePOCList[refPic.FrameIdx];
2940
2941 if (diff_poc < -16)
2942 {
2943 CODECHAL_ENCODE_ASSERTMESSAGE("POC out of range, it will be clipped.");
2944 diff_poc = -16;
2945 }
2946 else
2947 if (diff_poc > 16)
2948 {
2949 CODECHAL_ENCODE_ASSERTMESSAGE("POC out of range, it will be clipped.");
2950 diff_poc = 16;
2951 }
2952 }
2953
2954 return diff_poc;
2955 }
2956
InitSurfaceCodecParams1D(PCODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams,PMOS_RESOURCE buffer,uint32_t size,uint32_t offset,uint32_t cacheabilityControl,uint32_t bindingTableOffset,bool isWritable)2957 MOS_STATUS CodechalEncodeHevcBase::InitSurfaceCodecParams1D(
2958 PCODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams,
2959 PMOS_RESOURCE buffer,
2960 uint32_t size,
2961 uint32_t offset,
2962 uint32_t cacheabilityControl,
2963 uint32_t bindingTableOffset,
2964 bool isWritable)
2965 {
2966 if (surfaceCodecParams == nullptr)
2967 {
2968 return MOS_STATUS_NULL_POINTER;
2969 }
2970
2971 MOS_ZeroMemory(surfaceCodecParams, sizeof(*surfaceCodecParams));
2972 surfaceCodecParams->presBuffer = buffer;
2973 surfaceCodecParams->dwSize = size;
2974 surfaceCodecParams->dwOffset = offset;
2975 surfaceCodecParams->dwCacheabilityControl = cacheabilityControl;
2976 surfaceCodecParams->dwBindingTableOffset = bindingTableOffset;
2977 surfaceCodecParams->bIsWritable =
2978 surfaceCodecParams->bRenderTarget = isWritable;
2979
2980 return MOS_STATUS_SUCCESS;
2981 }
2982
InitSurfaceCodecParams2D(PCODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams,PMOS_SURFACE surface,uint32_t cacheabilityControl,uint32_t bindingTableOffset,uint32_t verticalLineStride,bool isWritable)2983 MOS_STATUS CodechalEncodeHevcBase::InitSurfaceCodecParams2D(
2984 PCODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams,
2985 PMOS_SURFACE surface,
2986 uint32_t cacheabilityControl,
2987 uint32_t bindingTableOffset,
2988 uint32_t verticalLineStride,
2989 bool isWritable)
2990 {
2991 if (surfaceCodecParams == nullptr)
2992 {
2993 return MOS_STATUS_NULL_POINTER;
2994 }
2995
2996 MOS_ZeroMemory(surfaceCodecParams, sizeof(*surfaceCodecParams));
2997 surfaceCodecParams->bIs2DSurface = true;
2998 surfaceCodecParams->bMediaBlockRW = true; // Use media block RW for DP 2D surface access
2999 surfaceCodecParams->psSurface = surface;
3000 surfaceCodecParams->dwCacheabilityControl = cacheabilityControl;
3001 surfaceCodecParams->dwBindingTableOffset = bindingTableOffset;
3002 surfaceCodecParams->dwVerticalLineStride = verticalLineStride;
3003 surfaceCodecParams->bIsWritable =
3004 surfaceCodecParams->bRenderTarget = isWritable;
3005
3006 return MOS_STATUS_SUCCESS;
3007 }
3008
AllocateResources4xME(HmeParams * param)3009 MOS_STATUS CodechalEncodeHevcBase::AllocateResources4xME(
3010 HmeParams *param)
3011 {
3012 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3013
3014 CODECHAL_ENCODE_FUNCTION_ENTER;
3015
3016 CODECHAL_ENCODE_CHK_NULL_RETURN(param);
3017
3018 if (!m_encEnabled || !m_hmeSupported)
3019 {
3020 return eStatus;
3021 }
3022
3023 MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
3024 MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
3025 allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
3026 allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
3027 allocParamsForBuffer2D.Format = Format_Buffer_2D;
3028
3029 MOS_ZeroMemory(param->ps4xMeMvDataBuffer, sizeof(MOS_SURFACE));
3030 param->ps4xMeMvDataBuffer->TileType = MOS_TILE_LINEAR;
3031 param->ps4xMeMvDataBuffer->bArraySpacing = true;
3032 param->ps4xMeMvDataBuffer->Format = Format_Buffer_2D;
3033 param->ps4xMeMvDataBuffer->dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64); // MediaBlockRW requires pitch multiple of 64 bytes when linear.
3034 param->ps4xMeMvDataBuffer->dwHeight = (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
3035 param->ps4xMeMvDataBuffer->dwPitch = param->ps4xMeMvDataBuffer->dwWidth;
3036
3037 allocParamsForBuffer2D.dwWidth = param->ps4xMeMvDataBuffer->dwWidth;
3038 allocParamsForBuffer2D.dwHeight = param->ps4xMeMvDataBuffer->dwHeight;
3039 allocParamsForBuffer2D.pBufName = "4xME MV Data Buffer";
3040
3041 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
3042 m_osInterface,
3043 &allocParamsForBuffer2D,
3044 ¶m->ps4xMeMvDataBuffer->OsResource);
3045
3046 if (eStatus != MOS_STATUS_SUCCESS)
3047 {
3048 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate 4xME MV Data Buffer.");
3049 return eStatus;
3050 }
3051
3052 CleanUpResource(¶m->ps4xMeMvDataBuffer->OsResource, &allocParamsForBuffer2D);
3053
3054 if (param->b4xMeDistortionBufferSupported)
3055 {
3056 uint32_t ajustedHeight =
3057 m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT * SCALE_FACTOR_4x;
3058 uint32_t downscaledFieldHeightInMB4x =
3059 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(((ajustedHeight + 1) >> 1) / 4);
3060
3061 MOS_ZeroMemory(param->ps4xMeDistortionBuffer, sizeof(MOS_SURFACE));
3062 param->ps4xMeDistortionBuffer->TileType = MOS_TILE_LINEAR;
3063 param->ps4xMeDistortionBuffer->bArraySpacing = true;
3064 param->ps4xMeDistortionBuffer->Format = Format_Buffer_2D;
3065 param->ps4xMeDistortionBuffer->dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
3066 param->ps4xMeDistortionBuffer->dwHeight = 2 * MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x * 4 * 10), 8);
3067 param->ps4xMeDistortionBuffer->dwPitch = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
3068
3069 allocParamsForBuffer2D.dwWidth = param->ps4xMeDistortionBuffer->dwWidth;
3070 allocParamsForBuffer2D.dwHeight = param->ps4xMeDistortionBuffer->dwHeight;
3071 allocParamsForBuffer2D.pBufName = "4xME Distortion Buffer";
3072
3073 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
3074 m_osInterface,
3075 &allocParamsForBuffer2D,
3076 ¶m->ps4xMeDistortionBuffer->OsResource);
3077
3078 if (eStatus != MOS_STATUS_SUCCESS)
3079 {
3080 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate 4xME Distortion Buffer.");
3081 return eStatus;
3082 }
3083 CleanUpResource(¶m->ps4xMeDistortionBuffer->OsResource, &allocParamsForBuffer2D);
3084 }
3085
3086 return eStatus;
3087 }
3088
AllocateResources16xME(HmeParams * param)3089 MOS_STATUS CodechalEncodeHevcBase::AllocateResources16xME(
3090 HmeParams *param)
3091 {
3092 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3093
3094 CODECHAL_ENCODE_FUNCTION_ENTER;
3095
3096 CODECHAL_ENCODE_CHK_NULL_RETURN(param);
3097
3098 if (!m_encEnabled || !m_hmeSupported)
3099 {
3100 return eStatus;
3101 }
3102
3103 MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
3104 MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
3105 allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
3106 allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
3107 allocParamsForBuffer2D.Format = Format_Buffer_2D;
3108
3109 if (m_16xMeSupported)
3110 {
3111 MOS_ZeroMemory(param->ps16xMeMvDataBuffer, sizeof(MOS_SURFACE));
3112 param->ps16xMeMvDataBuffer->TileType = MOS_TILE_LINEAR;
3113 param->ps16xMeMvDataBuffer->bArraySpacing = true;
3114 param->ps16xMeMvDataBuffer->Format = Format_Buffer_2D;
3115 param->ps16xMeMvDataBuffer->dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64); // MediaBlockRW requires pitch multiple of 64 bytes when linear
3116 param->ps16xMeMvDataBuffer->dwHeight = (m_downscaledHeightInMb16x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
3117 param->ps16xMeMvDataBuffer->dwPitch = param->ps16xMeMvDataBuffer->dwWidth;
3118
3119 allocParamsForBuffer2D.dwWidth = param->ps16xMeMvDataBuffer->dwWidth;
3120 allocParamsForBuffer2D.dwHeight = param->ps16xMeMvDataBuffer->dwHeight;
3121 allocParamsForBuffer2D.pBufName = "16xME MV Data Buffer";
3122
3123 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
3124 m_osInterface,
3125 &allocParamsForBuffer2D,
3126 ¶m->ps16xMeMvDataBuffer->OsResource);
3127
3128 if (eStatus != MOS_STATUS_SUCCESS)
3129 {
3130 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate 16xME MV Data Buffer.");
3131 return eStatus;
3132 }
3133 CleanUpResource(¶m->ps16xMeMvDataBuffer->OsResource, &allocParamsForBuffer2D);
3134 }
3135
3136 return eStatus;
3137 }
3138
AllocateResources32xME(HmeParams * param)3139 MOS_STATUS CodechalEncodeHevcBase::AllocateResources32xME(
3140 HmeParams *param)
3141 {
3142 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3143
3144 CODECHAL_ENCODE_FUNCTION_ENTER;
3145
3146 CODECHAL_ENCODE_CHK_NULL_RETURN(param);
3147
3148 if (!m_encEnabled || !m_hmeSupported)
3149 {
3150 return eStatus;
3151 }
3152
3153 MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
3154 MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
3155 allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
3156 allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
3157 allocParamsForBuffer2D.Format = Format_Buffer_2D;
3158
3159 if (m_32xMeSupported)
3160 {
3161 MOS_ZeroMemory(param->ps32xMeMvDataBuffer, sizeof(MOS_SURFACE));
3162 param->ps32xMeMvDataBuffer->TileType = MOS_TILE_LINEAR;
3163 param->ps32xMeMvDataBuffer->bArraySpacing = true;
3164 param->ps32xMeMvDataBuffer->Format = Format_Buffer_2D;
3165 param->ps32xMeMvDataBuffer->dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64); // MediaBlockRW requires pitch multiple of 64 bytes when linear
3166 param->ps32xMeMvDataBuffer->dwHeight = (m_downscaledHeightInMb32x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
3167 param->ps32xMeMvDataBuffer->dwPitch = param->ps32xMeMvDataBuffer->dwWidth;
3168
3169 allocParamsForBuffer2D.dwWidth = param->ps32xMeMvDataBuffer->dwWidth;
3170 allocParamsForBuffer2D.dwHeight = param->ps32xMeMvDataBuffer->dwHeight;
3171 allocParamsForBuffer2D.pBufName = "32xME MV Data Buffer";
3172
3173 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
3174 m_osInterface,
3175 &allocParamsForBuffer2D,
3176 ¶m->ps32xMeMvDataBuffer->OsResource);
3177
3178 if (eStatus != MOS_STATUS_SUCCESS)
3179 {
3180 CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate 32xME MV Data Buffer\n", __FUNCTION__);
3181 return eStatus;
3182 }
3183 CleanUpResource(¶m->ps32xMeMvDataBuffer->OsResource, &allocParamsForBuffer2D);
3184 }
3185
3186 return eStatus;
3187 }
3188
DestroyMEResources(HmeParams * param)3189 MOS_STATUS CodechalEncodeHevcBase::DestroyMEResources(
3190 HmeParams *param)
3191 {
3192 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3193
3194 CODECHAL_ENCODE_FUNCTION_ENTER;
3195
3196 CODECHAL_ENCODE_CHK_NULL_RETURN(param);
3197
3198 if (nullptr != param->ps16xMeMvDataBuffer)
3199 {
3200 m_osInterface->pfnFreeResource(
3201 m_osInterface,
3202 ¶m->ps16xMeMvDataBuffer->OsResource);
3203 }
3204
3205 if (nullptr != param->ps32xMeMvDataBuffer)
3206 {
3207 m_osInterface->pfnFreeResource(
3208 m_osInterface,
3209 ¶m->ps32xMeMvDataBuffer->OsResource);
3210 }
3211
3212 if (nullptr != param->ps4xMeDistortionBuffer)
3213 {
3214 m_osInterface->pfnFreeResource(
3215 m_osInterface,
3216 ¶m->ps4xMeDistortionBuffer->OsResource);
3217 }
3218
3219 if (nullptr != param->ps4xMeMvDataBuffer)
3220 {
3221 m_osInterface->pfnFreeResource(
3222 m_osInterface,
3223 ¶m->ps4xMeMvDataBuffer->OsResource);
3224 }
3225
3226 if (nullptr != param->presMvAndDistortionSumSurface)
3227 {
3228 m_osInterface->pfnFreeResource(
3229 m_osInterface,
3230 param->presMvAndDistortionSumSurface);
3231 }
3232
3233 return eStatus;
3234 }
3235
MotionEstimationDisableCheck()3236 void CodechalEncodeHevcBase::MotionEstimationDisableCheck()
3237 {
3238 CODECHAL_ENCODE_FUNCTION_ENTER;
3239
3240 if (m_downscaledWidth4x < m_minScaledDimension || m_downscaledWidthInMb4x < m_minScaledDimensionInMb ||
3241 m_downscaledHeight4x < m_minScaledDimension || m_downscaledHeightInMb4x < m_minScaledDimensionInMb)
3242 {
3243 if (m_downscaledWidth4x < m_minScaledDimension || m_downscaledWidthInMb4x < m_minScaledDimensionInMb)
3244 {
3245 m_downscaledWidth4x = m_minScaledDimension;
3246 m_downscaledWidthInMb4x = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_downscaledWidth4x);
3247 }
3248 if (m_downscaledHeight4x < m_minScaledDimension || m_downscaledHeightInMb4x < m_minScaledDimensionInMb)
3249 {
3250 m_downscaledHeight4x = m_minScaledDimension;
3251 m_downscaledHeightInMb4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_downscaledHeight4x);
3252 }
3253 }
3254
3255 if (m_downscaledWidth16x < m_minScaledDimension || m_downscaledWidthInMb16x < m_minScaledDimensionInMb ||
3256 m_downscaledHeight16x < m_minScaledDimension || m_downscaledHeightInMb16x < m_minScaledDimensionInMb)
3257 {
3258 if (m_downscaledWidth16x < m_minScaledDimension || m_downscaledWidthInMb16x < m_minScaledDimensionInMb)
3259 {
3260 m_downscaledWidth16x = m_minScaledDimension;
3261 m_downscaledWidthInMb16x = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_downscaledWidth16x);
3262 }
3263 if (m_downscaledHeight16x < m_minScaledDimension || m_downscaledHeightInMb16x < m_minScaledDimensionInMb)
3264 {
3265 m_downscaledHeight16x = m_minScaledDimension;
3266 m_downscaledHeightInMb16x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_downscaledHeight16x);
3267 }
3268 }
3269
3270 if (m_downscaledWidth32x < m_minScaledDimension || m_downscaledWidthInMb32x < m_minScaledDimensionInMb)
3271 {
3272 m_downscaledWidth32x = m_minScaledDimension;
3273 m_downscaledWidthInMb32x = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_downscaledWidth32x);
3274 }
3275 if (m_downscaledHeight32x < m_minScaledDimension || m_downscaledHeightInMb32x < m_minScaledDimensionInMb)
3276 {
3277 m_downscaledHeight32x = m_minScaledDimension;
3278 m_downscaledHeightInMb32x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_downscaledHeight32x);
3279 }
3280
3281 }
3282
ExecuteKernelFunctions()3283 MOS_STATUS CodechalEncodeHevcBase::ExecuteKernelFunctions()
3284 {
3285 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3286
3287 CODECHAL_ENCODE_FUNCTION_ENTER;
3288
3289 CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeKernelFunctions());
3290
3291 return eStatus;
3292 }
3293
3294 #if USE_CODECHAL_DEBUG_TOOL
DumpSeqParams(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams)3295 MOS_STATUS CodechalEncodeHevcBase::DumpSeqParams(
3296 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams)
3297 {
3298 CODECHAL_DEBUG_FUNCTION_ENTER;
3299
3300 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSeqParams))
3301 {
3302 return MOS_STATUS_SUCCESS;
3303 }
3304
3305 CODECHAL_DEBUG_CHK_NULL(seqParams);
3306
3307 std::ostringstream oss;
3308 oss.setf(std::ios::showbase | std::ios::uppercase);
3309
3310 oss << "# DDI Parameters:" << std::endl;
3311 oss << "wFrameWidthInMinCbMinus1 = " << +seqParams->wFrameWidthInMinCbMinus1 << std::endl;
3312 oss << "wFrameHeightInMinCbMinus1 = " << +seqParams->wFrameHeightInMinCbMinus1 << std::endl;
3313 oss << "general_profile_idc = " << +seqParams->general_profile_idc << std::endl;
3314 oss << "Level = " << +seqParams->Level << std::endl;
3315 oss << "general_tier_flag = " << +seqParams->general_tier_flag << std::endl;
3316 oss << "GopPicSize = " << +seqParams->GopPicSize << std::endl;
3317 oss << "GopRefDist = " << +seqParams->GopRefDist << std::endl;
3318 oss << "GopOptFlag = " << +seqParams->GopOptFlag << std::endl;
3319 oss << "TargetUsage = " << +seqParams->TargetUsage << std::endl;
3320 oss << "RateControlMethod = " << +seqParams->RateControlMethod << std::endl;
3321 oss << "TargetBitRate = " << +seqParams->TargetBitRate << std::endl;
3322 oss << "MaxBitRate = " << +seqParams->MaxBitRate << std::endl;
3323 oss << "MinBitRate = " << +seqParams->MinBitRate << std::endl;
3324 oss << "FramesRate.Numerator = " << +seqParams->FrameRate.Numerator << std::endl;
3325 oss << "FramesRate.Denominator = " << +seqParams->FrameRate.Denominator << std::endl;
3326 oss << "InitVBVBufferFullnessInBit = " << +seqParams->InitVBVBufferFullnessInBit << std::endl;
3327 oss << "VBVBufferSizeInBit = " << +seqParams->VBVBufferSizeInBit << std::endl;
3328 oss << "bResetBRC = " << +seqParams->bResetBRC << std::endl;
3329 oss << "GlobalSearch = " << +seqParams->GlobalSearch << std::endl;
3330 oss << "LocalSearch = " << +seqParams->LocalSearch << std::endl;
3331 oss << "EarlySkip = " << +seqParams->EarlySkip << std::endl;
3332 oss << "MBBRC = " << +seqParams->MBBRC << std::endl;
3333 oss << "ParallelBRC = " << +seqParams->ParallelBRC << std::endl;
3334 oss << "SliceSizeControl = " << +seqParams->SliceSizeControl << std::endl;
3335 oss << "SourceFormat = " << +seqParams->SourceFormat << std::endl;
3336 oss << "SourceBitDepth = " << +seqParams->SourceBitDepth << std::endl;
3337 oss << "QpAdjustment = " << +seqParams->QpAdjustment << std::endl;
3338 oss << "ROIValueInDeltaQP = " << +seqParams->ROIValueInDeltaQP << std::endl;
3339 oss << "BlockQPforNonRectROI = " << +seqParams->BlockQPforNonRectROI << std::endl;
3340 oss << "EnableTileBasedEncode = " << +seqParams->EnableTileBasedEncode << std::endl;
3341 oss << "bAutoMaxPBFrameSizeForSceneChange = " << +seqParams->bAutoMaxPBFrameSizeForSceneChange << std::endl;
3342 oss << "EnableStreamingBufferLLC = " << +seqParams->EnableStreamingBufferLLC << std::endl;
3343 oss << "EnableStreamingBufferDDR = " << +seqParams->EnableStreamingBufferDDR << std::endl;
3344 oss << "LowDelayMode = " << +seqParams->LowDelayMode << std::endl;
3345 oss << "DisableHRDConformance = " << +seqParams->DisableHRDConformance << std::endl;
3346 oss << "HierarchicalFlag = " << +seqParams->HierarchicalFlag << std::endl;
3347 oss << "UserMaxIFrameSize = " << +seqParams->UserMaxIFrameSize << std::endl;
3348 oss << "UserMaxPBFrameSize = " << +seqParams->UserMaxPBFrameSize << std::endl;
3349 oss << "ICQQualityFactor = " << +seqParams->ICQQualityFactor << std::endl;
3350 oss << "NumB = " << +seqParams->NumOfBInGop[0] << std::endl;
3351 oss << "NumB1 = " << +seqParams->NumOfBInGop[1] << std::endl;
3352 oss << "NumB2 = " << +seqParams->NumOfBInGop[2] << std::endl;
3353 oss << "UserMaxIFrameSize = " << +seqParams->UserMaxIFrameSize << std::endl;
3354 oss << "UserMaxPBFrameSize = " << +seqParams->UserMaxPBFrameSize << std::endl;
3355 oss << "ICQQualityFactor = " << +seqParams->ICQQualityFactor << std::endl;
3356 oss << "scaling_list_enable_flag = " << +seqParams->scaling_list_enable_flag << std::endl;
3357 oss << "sps_temporal_mvp_enable_flag = " << +seqParams->sps_temporal_mvp_enable_flag << std::endl;
3358 oss << "strong_intra_smoothing_enable_flag = " << +seqParams->strong_intra_smoothing_enable_flag << std::endl;
3359 oss << "amp_enabled_flag = " << +seqParams->amp_enabled_flag << std::endl;
3360 oss << "SAO_enabled_flag = " << +seqParams->SAO_enabled_flag << std::endl;
3361 oss << "pcm_enabled_flag = " << +seqParams->pcm_enabled_flag << std::endl;
3362 oss << "pcm_loop_filter_disable_flag = " << +seqParams->pcm_loop_filter_disable_flag << std::endl;
3363 oss << "chroma_format_idc = " << +seqParams->chroma_format_idc << std::endl;
3364 oss << "separate_colour_plane_flag = " << +seqParams->separate_colour_plane_flag << std::endl;
3365 oss << "palette_mode_enabled_flag = " << +seqParams->palette_mode_enabled_flag << std::endl;
3366 oss << "RGBEncodingEnable = " << +seqParams->RGBEncodingEnable << std::endl;
3367 oss << "PrimaryChannelForRGBEncoding = " << +seqParams->PrimaryChannelForRGBEncoding << std::endl;
3368 oss << "SecondaryChannelForRGBEncoding = " << +seqParams->SecondaryChannelForRGBEncoding << std::endl;
3369
3370 oss << "log2_max_coding_block_size_minus3 = " << +seqParams->log2_max_coding_block_size_minus3 << std::endl;
3371 oss << "log2_min_coding_block_size_minus3 = " << +seqParams->log2_min_coding_block_size_minus3 << std::endl;
3372 oss << "log2_max_transform_block_size_minus2 = " << +seqParams->log2_max_transform_block_size_minus2 << std::endl;
3373 oss << "log2_min_transform_block_size_minus2 = " << +seqParams->log2_min_transform_block_size_minus2 << std::endl;
3374 oss << "max_transform_hierarchy_depth_intra = " << +seqParams->max_transform_hierarchy_depth_intra << std::endl;
3375 oss << "max_transform_hierarchy_depth_inter = " << +seqParams->max_transform_hierarchy_depth_inter << std::endl;
3376 oss << "log2_min_PCM_cb_size_minus3 = " << +seqParams->log2_min_PCM_cb_size_minus3 << std::endl;
3377 oss << "log2_max_PCM_cb_size_minus3 = " << +seqParams->log2_max_PCM_cb_size_minus3 << std::endl;
3378 oss << "bit_depth_luma_minus8 = " << +seqParams->bit_depth_luma_minus8 << std::endl;
3379 oss << "bit_depth_chroma_minus8 = " << +seqParams->bit_depth_chroma_minus8 << std::endl;
3380 oss << "pcm_sample_bit_depth_luma_minus1 = " << +seqParams->pcm_sample_bit_depth_luma_minus1 << std::endl;
3381 oss << "pcm_sample_bit_depth_chroma_minus1 = " << +seqParams->pcm_sample_bit_depth_chroma_minus1 << std::endl;
3382 oss << "Video Surveillance Mode = " << +seqParams->bVideoSurveillance << std::endl;
3383 oss << "Frame Size Tolerance = " << +seqParams->FrameSizeTolerance << std::endl;
3384 oss << "Look Ahead Depth = " << +seqParams->LookaheadDepth << std::endl;
3385
3386 const char *fileName = m_debugInterface->CreateFileName(
3387 "_DDIEnc",
3388 CodechalDbgBufferType::bufSeqParams,
3389 CodechalDbgExtType::txt);
3390
3391 std::ofstream ofs(fileName, std::ios::out);
3392 ofs << oss.str();
3393 ofs.close();
3394
3395 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
3396 {
3397 if (!m_debugInterface->m_ddiFileName.empty())
3398 {
3399 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
3400 ofs << "SeqParamFile"
3401 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
3402 ofs.close();
3403 }
3404 }
3405
3406 return MOS_STATUS_SUCCESS;
3407 }
3408
DumpPicParams(PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams)3409 MOS_STATUS CodechalEncodeHevcBase::DumpPicParams(
3410 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams)
3411 {
3412 CODECHAL_DEBUG_FUNCTION_ENTER;
3413
3414 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
3415 {
3416 return MOS_STATUS_SUCCESS;
3417 }
3418
3419 CODECHAL_DEBUG_CHK_NULL(picParams);
3420
3421 std::ostringstream oss;
3422 oss.setf(std::ios::showbase | std::ios::uppercase);
3423
3424 oss << "# DDI Parameters:" << std::endl;
3425 oss << "CurrOriginalPic = " << +picParams->CurrOriginalPic.FrameIdx << std::endl;
3426 oss << "CurrReconstructedPic = " << +picParams->CurrReconstructedPic.FrameIdx << std::endl;
3427 oss << "CollocatedRefPicIndex = " << +picParams->CollocatedRefPicIndex << std::endl;
3428
3429 for (uint16_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; ++i)
3430 {
3431 oss << "RefFrameList[" << +i << "] = " << +picParams->RefFrameList[i].FrameIdx << std::endl;
3432 }
3433
3434 oss << "CurrPicOrderCnt = " << +picParams->CurrPicOrderCnt << std::endl;
3435
3436 for (uint16_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; ++i)
3437 {
3438 oss << "RefFramePOCList[" << +i << "] = " << +picParams->RefFramePOCList[i] << std::endl;
3439 }
3440
3441 oss << "CodingType = " << +picParams->CodingType << std::endl;
3442 oss << "HierarchLevelPlus1 = " << +picParams->HierarchLevelPlus1 << std::endl;
3443 oss << "NumSlices = " << +picParams->NumSlices << std::endl;
3444 oss << "tiles_enabled_flag = " << +picParams->tiles_enabled_flag << std::endl;
3445
3446 if (picParams->tiles_enabled_flag)
3447 {
3448 oss << "num_tile_columns = " << +picParams->num_tile_columns_minus1 + 1 << std::endl;
3449 for (uint32_t i = 0; i <= picParams->num_tile_columns_minus1; i++)
3450 {
3451 oss << "tile_column_width[" << +i << "] = " << +picParams->tile_column_width[i] << std::endl;
3452 }
3453 oss << "num_tile_rows = " << +picParams->num_tile_rows_minus1 + 1 << std::endl;
3454 for (uint32_t i = 0; i <= picParams->num_tile_rows_minus1; i++)
3455 {
3456 oss << "tile_row_height[" << +i << "] = " << +picParams->tile_row_height[i] << std::endl;
3457 }
3458 }
3459
3460 oss << "entropy_coding_sync_enabled_flag = " << +picParams->entropy_coding_sync_enabled_flag << std::endl;
3461 oss << "sign_data_hiding_flag = " << +picParams->sign_data_hiding_flag << std::endl;
3462 oss << "constrained_intra_pred_flag = " << +picParams->constrained_intra_pred_flag << std::endl;
3463 oss << "transform_skip_enabled_flag = " << +picParams->transform_skip_enabled_flag << std::endl;
3464 oss << "transquant_bypass_enabled_flag = " << +picParams->transquant_bypass_enabled_flag << std::endl;
3465 oss << "cu_qp_delta_enabled_flag = " << +picParams->cu_qp_delta_enabled_flag << std::endl;
3466 oss << "weighted_pred_flag = " << +picParams->weighted_pred_flag << std::endl;
3467 oss << "weighted_bipred_flag = " << +picParams->weighted_bipred_flag << std::endl;
3468 oss << "bEnableGPUWeightedPrediction = " << +picParams->bEnableGPUWeightedPrediction << std::endl;
3469 oss << "loop_filter_across_slices_flag = " << +picParams->loop_filter_across_slices_flag << std::endl;
3470 oss << "loop_filter_across_tiles_flag = " << +picParams->loop_filter_across_tiles_flag << std::endl;
3471 oss << "scaling_list_data_present_flag = " << +picParams->scaling_list_data_present_flag << std::endl;
3472 oss << "dependent_slice_segments_enabled_flag = " << +picParams->dependent_slice_segments_enabled_flag << std::endl;
3473 oss << "bLastPicInSeq = " << +picParams->bLastPicInSeq << std::endl;
3474 oss << "bLastPicInStream = " << +picParams->bLastPicInStream << std::endl;
3475 oss << "bUseRawPicForRef = " << +picParams->bUseRawPicForRef << std::endl;
3476 oss << "bEmulationByteInsertion = " << +picParams->bEmulationByteInsertion << std::endl;
3477 oss << "bEnableRollingIntraRefresh = " << +picParams->bEnableRollingIntraRefresh << std::endl;
3478 oss << "BRCPrecision = " << +picParams->BRCPrecision << std::endl;
3479 oss << "bScreenContent = " << +picParams->bScreenContent << std::endl;
3480 oss << "QpY = " << +picParams->QpY << std::endl;
3481 oss << "diff_cu_qp_delta_depth = " << +picParams->diff_cu_qp_delta_depth << std::endl;
3482 oss << "pps_cb_qp_offset = " << +picParams->pps_cb_qp_offset << std::endl;
3483 oss << "pps_cr_qp_offset = " << +picParams->pps_cr_qp_offset << std::endl;
3484 oss << "num_tile_columns_minus1 = " << +picParams->num_tile_columns_minus1 << std::endl;
3485 oss << "num_tile_rows_minus1 = " << +picParams->num_tile_rows_minus1 << std::endl;
3486 oss << "log2_parallel_merge_level_minus2 = " << +picParams->log2_parallel_merge_level_minus2 << std::endl;
3487 oss << "num_ref_idx_l0_default_active_minus1 = " << +picParams->num_ref_idx_l0_default_active_minus1 << std::endl;
3488 oss << "num_ref_idx_l1_default_active_minus1 = " << +picParams->num_ref_idx_l1_default_active_minus1 << std::endl;
3489 oss << "LcuMaxBitsizeAllowed = " << +picParams->LcuMaxBitsizeAllowed << std::endl;
3490 oss << "IntraInsertionLocation = " << +picParams->IntraInsertionLocation << std::endl;
3491 oss << "IntraInsertionSize = " << +picParams->IntraInsertionSize << std::endl;
3492 oss << "QpDeltaForInsertedIntra = " << +picParams->QpDeltaForInsertedIntra << std::endl;
3493 oss << "StatusReportFeedbackNumber = " << +picParams->StatusReportFeedbackNumber << std::endl;
3494 oss << "slice_pic_parameter_set_id = " << +picParams->slice_pic_parameter_set_id << std::endl;
3495 oss << "nal_unit_type = " << +picParams->nal_unit_type << std::endl;
3496 oss << "MaxSliceSizeInBytes = " << +picParams->MaxSliceSizeInBytes << std::endl;
3497 oss << "NumROI = " << +picParams->NumROI << std::endl;
3498
3499 for (uint8_t i = 0; i < 16; ++i)
3500 {
3501 oss << "ROI[" << +i << "] = ";
3502 oss << picParams->ROI[i].Top << " ";
3503 oss << picParams->ROI[i].Bottom << " ";
3504 oss << picParams->ROI[i].Left << " ";
3505 oss << picParams->ROI[i].Right << " ";
3506 oss << picParams->ROI[i].PriorityLevelOrDQp << std::endl;
3507 }
3508 oss << "MaxDeltaQp = " << +picParams->MaxDeltaQp << std::endl;
3509 oss << "MinDeltaQp = " << +picParams->MinDeltaQp << std::endl;
3510 oss << "NumDirtyRects = " << +picParams->NumDirtyRects << std::endl;
3511
3512 if ((picParams->NumDirtyRects > 0) && picParams->pDirtyRect)
3513 {
3514 for (uint16_t i = 0; i < picParams->NumDirtyRects; i++)
3515 {
3516 oss << "pDirtyRect[" << +i << "].Bottom = " << +picParams->pDirtyRect[i].Bottom << std::endl;
3517 oss << "pDirtyRect[" << +i << "].Top = " << +picParams->pDirtyRect[i].Top << std::endl;
3518 oss << "pDirtyRect[" << +i << "].Left = " << +picParams->pDirtyRect[i].Left << std::endl;
3519 oss << "pDirtyRect[" << +i << "].Right = " << +picParams->pDirtyRect[i].Right << std::endl;
3520 }
3521 }
3522
3523 oss << "TargetFrameSize = " << +picParams->TargetFrameSize << std::endl;
3524
3525 const char *fileName = m_debugInterface->CreateFileName(
3526 "_DDIEnc",
3527 CodechalDbgBufferType::bufPicParams,
3528 CodechalDbgExtType::txt);
3529
3530 std::ofstream ofs(fileName, std::ios::out);
3531 ofs << oss.str();
3532 ofs.close();
3533
3534 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
3535 {
3536 if (!m_debugInterface->m_ddiFileName.empty())
3537 {
3538 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
3539 ofs << "PicNum"
3540 << " = \"" << m_debugInterface->m_bufferDumpFrameNum << "\"" << std::endl;
3541 ofs << "PicParamFile"
3542 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
3543 ofs.close();
3544 }
3545 }
3546
3547 return MOS_STATUS_SUCCESS;
3548 }
3549
DumpFeiPicParams(CodecEncodeHevcFeiPicParams * feiPicParams)3550 MOS_STATUS CodechalEncodeHevcBase::DumpFeiPicParams(
3551 CodecEncodeHevcFeiPicParams *feiPicParams)
3552 {
3553 CODECHAL_DEBUG_FUNCTION_ENTER;
3554
3555 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrFeiPicParams))
3556 {
3557 return MOS_STATUS_SUCCESS;
3558 }
3559
3560 CODECHAL_DEBUG_CHK_NULL(feiPicParams);
3561
3562 std::ostringstream oss;
3563 oss.setf(std::ios::showbase | std::ios::uppercase);
3564
3565 oss << "# DDI Parameters:" << std::endl;
3566 oss << "NumMVPredictorsL0 = " << +feiPicParams->NumMVPredictorsL0 << std::endl;
3567 oss << "NumMVPredictorsL1 = " << +feiPicParams->NumMVPredictorsL1 << std::endl;
3568 oss << "bCTBCmdCuRecordEnable = " << +feiPicParams->bCTBCmdCuRecordEnable << std::endl;
3569 oss << "bDistortionEnable = " << +feiPicParams->bDistortionEnable << std::endl;
3570 oss << "SearchPath = " << +feiPicParams->SearchPath << std::endl;
3571 oss << "LenSP = " << +feiPicParams->LenSP << std::endl;
3572 oss << "MultiPredL0 = " << +feiPicParams->MultiPredL0 << std::endl;
3573 oss << "MultiPredL1 = " << +feiPicParams->MultiPredL1 << std::endl;
3574 oss << "SubPelMode = " << +feiPicParams->SubPelMode << std::endl;
3575 oss << "AdaptiveSearch = " << +feiPicParams->AdaptiveSearch << std::endl;
3576 oss << "MVPredictorInput = " << +feiPicParams->MVPredictorInput << std::endl;
3577 oss << "bPerBlockQP = " << +feiPicParams->bPerBlockQP << std::endl;
3578 oss << "bPerCTBInput = " << +feiPicParams->bPerCTBInput << std::endl;
3579 oss << "bColocatedCTBDistortion = " << +feiPicParams->bColocatedCTBDistortion << std::endl;
3580 oss << "bForceLCUSplit = " << +feiPicParams->bForceLCUSplit << std::endl;
3581 oss << "bEnableCU64Check = " << +feiPicParams->bEnableCU64Check << std::endl;
3582 oss << "bEnableCU64AmpCheck = " << +feiPicParams->bEnableCU64AmpCheck << std::endl;
3583 oss << "bCU64SkipCheckOnly = " << +feiPicParams->bCU64SkipCheckOnly << std::endl;
3584 oss << "RefWidth = " << +feiPicParams->RefWidth << std::endl;
3585 oss << "RefHeight = " << +feiPicParams->RefHeight << std::endl;
3586 oss << "SearchWindow = " << +feiPicParams->SearchWindow << std::endl;
3587 oss << "MaxNumIMESearchCenter = " << +feiPicParams->MaxNumIMESearchCenter << std::endl;
3588 oss << "NumConcurrentEncFramePartition = " << +feiPicParams->NumConcurrentEncFramePartition << std::endl;
3589
3590 const char *fileName = m_debugInterface->CreateFileName(
3591 "_DDIEnc",
3592 CodechalDbgBufferType::bufFeiPicParams,
3593 CodechalDbgExtType::txt);
3594
3595 std::ofstream ofs(fileName, std::ios::out);
3596 ofs << oss.str();
3597 ofs.close();
3598
3599 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
3600 {
3601 if (!m_debugInterface->m_ddiFileName.empty())
3602 {
3603 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
3604 ofs << "PicNum"
3605 << " = \"" << m_debugInterface->m_bufferDumpFrameNum << "\"" << std::endl;
3606 ofs << "FeiPicParamFile"
3607 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
3608 ofs.close();
3609 }
3610 }
3611
3612 return MOS_STATUS_SUCCESS;
3613 }
3614
DumpSliceParams(PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams)3615 MOS_STATUS CodechalEncodeHevcBase::DumpSliceParams(
3616 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,
3617 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams)
3618 {
3619 CODECHAL_DEBUG_FUNCTION_ENTER;
3620 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
3621 {
3622 return MOS_STATUS_SUCCESS;
3623 }
3624
3625 CODECHAL_DEBUG_CHK_NULL(sliceParams);
3626
3627 m_debugInterface->m_sliceId = sliceParams->slice_id; // set here for constructing debug file name
3628
3629 std::ostringstream oss;
3630 oss.setf(std::ios::showbase | std::ios::uppercase);
3631
3632 oss << "# DDI Parameters:" << std::endl;
3633 oss << "slice_segment_address = " << +sliceParams->slice_segment_address << std::endl;
3634 oss << "NumLCUsInSlice = " << +sliceParams->NumLCUsInSlice << std::endl;
3635
3636 // RefPicList (2 x CODEC_MAX_NUM_REF_FRAME_HEVC)
3637 for (uint8_t i = 0; i < 2; ++i)
3638 {
3639 for (uint8_t j = 0; j < CODEC_MAX_NUM_REF_FRAME_HEVC; ++j)
3640 {
3641 oss << "RefPicList[" << +i << "][" << +j << "] = " << +sliceParams->RefPicList[i][j].PicEntry << std::endl;
3642 }
3643 }
3644
3645 oss << "num_ref_idx_l0_active_minus1 = " << +sliceParams->num_ref_idx_l0_active_minus1 << std::endl;
3646 oss << "num_ref_idx_l1_active_minus1 = " << +sliceParams->num_ref_idx_l1_active_minus1 << std::endl;
3647 oss << "bLastSliceOfPic = " << +sliceParams->bLastSliceOfPic << std::endl;
3648 oss << "dependent_slice_segment_flag = " << +sliceParams->dependent_slice_segment_flag << std::endl;
3649 oss << "slice_temporal_mvp_enable_flag = " << +sliceParams->slice_temporal_mvp_enable_flag << std::endl;
3650 oss << "slice_type = " << +sliceParams->slice_type << std::endl;
3651 oss << "slice_sao_luma_flag = " << +sliceParams->slice_sao_luma_flag << std::endl;
3652 oss << "slice_sao_chroma_flag = " << +sliceParams->slice_sao_chroma_flag << std::endl;
3653 oss << "mvd_l1_zero_flag = " << +sliceParams->mvd_l1_zero_flag << std::endl;
3654 oss << "cabac_init_flag = " << +sliceParams->cabac_init_flag << std::endl;
3655 oss << "slice_deblocking_filter_disable_flag = " << +sliceParams->slice_deblocking_filter_disable_flag << std::endl;
3656 oss << "collocated_from_l0_flag = " << +sliceParams->collocated_from_l0_flag << std::endl;
3657 oss << "slice_qp_delta = " << +sliceParams->slice_qp_delta << std::endl;
3658 oss << "slice_cb_qp_offset = " << +sliceParams->slice_cb_qp_offset << std::endl;
3659 oss << "slice_cr_qp_offset = " << +sliceParams->slice_cr_qp_offset << std::endl;
3660 oss << "beta_offset_div2 = " << +sliceParams->beta_offset_div2 << std::endl;
3661 oss << "tc_offset_div2 = " << +sliceParams->tc_offset_div2 << std::endl;
3662 oss << "luma_log2_weight_denom = " << +sliceParams->luma_log2_weight_denom << std::endl;
3663 oss << "delta_chroma_log2_weight_denom = " << +sliceParams->delta_chroma_log2_weight_denom << std::endl;
3664
3665 for (uint8_t i = 0; i < 2; ++i)
3666 {
3667 for (uint8_t j = 0; j < CODEC_MAX_NUM_REF_FRAME_HEVC; ++j)
3668 {
3669 oss << "luma_offset[" << +i << "][" << +j << "] = " << +sliceParams->luma_offset[i][j] << std::endl;
3670
3671 oss << "delta_luma_weight[" << +i << "][" << +j << "] = " << +sliceParams->delta_luma_weight[i][j] << std::endl;
3672 }
3673 }
3674
3675 for (uint8_t i = 0; i < 2; ++i)
3676 {
3677 for (uint8_t j = 0; j < CODEC_MAX_NUM_REF_FRAME_HEVC; ++j)
3678 {
3679 for (uint8_t k = 0; k < 2; ++k)
3680 {
3681 oss << "chroma_offset[" << +i << "][" << +j << "][" << +k << "] = " << +sliceParams->chroma_offset[i][j][k] << std::endl;
3682 oss << "delta_chroma_weight[" << +i << "][" << +j << "][" << +k << "] = " << +sliceParams->delta_chroma_weight[i][j][k] << std::endl;
3683 }
3684 }
3685 }
3686
3687 oss << "PredWeightTableBitOffset = " << +sliceParams->PredWeightTableBitOffset << std::endl;
3688 oss << "PredWeightTableBitLength = " << +sliceParams->PredWeightTableBitLength << std::endl;
3689 oss << "MaxNumMergeCand = " << +sliceParams->MaxNumMergeCand << std::endl;
3690 oss << "slice_id = " << +sliceParams->slice_id << std::endl;
3691 oss << "SliceHeaderByteOffset = " << +sliceParams->SliceHeaderByteOffset << std::endl;
3692 oss << "BitLengthSliceHeaderStartingPortion = " << +sliceParams->BitLengthSliceHeaderStartingPortion << std::endl;
3693 oss << "SliceSAOFlagBitOffset = " << +sliceParams->SliceSAOFlagBitOffset << std::endl;
3694
3695 const char *fileName = m_debugInterface->CreateFileName(
3696 "_DDIEnc",
3697 CodechalDbgBufferType::bufSlcParams,
3698 CodechalDbgExtType::txt);
3699
3700 std::ofstream ofs(fileName, std::ios::out);
3701 ofs << oss.str();
3702 ofs.close();
3703
3704 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
3705 {
3706 if (!m_debugInterface->m_ddiFileName.empty())
3707 {
3708 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
3709 ofs << "SlcParamFile"
3710 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
3711 ofs.close();
3712 }
3713 }
3714
3715 return MOS_STATUS_SUCCESS;
3716 }
3717
DumpMbEncPakOutput(PCODEC_REF_LIST currRefList,CodechalDebugInterface * debugInterface)3718 MOS_STATUS CodechalEncodeHevcBase::DumpMbEncPakOutput(PCODEC_REF_LIST currRefList, CodechalDebugInterface* debugInterface)
3719 {
3720 CODECHAL_ENCODE_FUNCTION_ENTER;
3721 CODECHAL_ENCODE_CHK_NULL_RETURN(currRefList);
3722 CODECHAL_ENCODE_CHK_NULL_RETURN(debugInterface);
3723
3724 CODECHAL_ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
3725 &currRefList->resRefMbCodeBuffer,
3726 CodechalDbgAttr::attrOutput,
3727 "PakObj",
3728 m_mvOffset,
3729 0,
3730 CODECHAL_MEDIA_STATE_ENC_NORMAL));
3731
3732 CODECHAL_ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
3733 &currRefList->resRefMbCodeBuffer,
3734 CodechalDbgAttr::attrOutput,
3735 "CuRecord",
3736 m_mbCodeSize - m_mvOffset,
3737 m_mvOffset,
3738 CODECHAL_MEDIA_STATE_ENC_NORMAL));
3739
3740 return MOS_STATUS_SUCCESS;
3741 }
3742
DumpFrameStatsBuffer(CodechalDebugInterface * debugInterface)3743 MOS_STATUS CodechalEncodeHevcBase::DumpFrameStatsBuffer(CodechalDebugInterface* debugInterface)
3744 {
3745 CODECHAL_ENCODE_FUNCTION_ENTER;
3746 CODECHAL_ENCODE_CHK_NULL_RETURN(debugInterface);
3747
3748 CODECHAL_ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
3749 &m_resFrameStatStreamOutBuffer,
3750 CodechalDbgAttr::attrFrameState,
3751 "FrameStatus",
3752 m_sizeOfHcpPakFrameStats,
3753 0,
3754 CODECHAL_NUM_MEDIA_STATES));
3755
3756 return MOS_STATUS_SUCCESS;
3757 }
3758 #endif
3759