1 /*
2 * Copyright (c) 2018-2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file encode_hevc_vdenc_roi.cpp
24 //! \brief implementation of ROI feature of HEVC VDENC
25
26 #include "mos_defs.h"
27 #include "encode_hevc_vdenc_roi.h"
28 #include "encode_hevc_vdenc_feature_manager.h"
29
30 namespace encode
31 {
32
HevcVdencRoi(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)33 HevcVdencRoi::HevcVdencRoi(
34 MediaFeatureManager *featureManager,
35 EncodeAllocator *allocator,
36 CodechalHwInterfaceNext *hwInterface,
37 void *constSettings) :
38 MediaFeature(constSettings, hwInterface ? hwInterface->GetOsInterface() : nullptr),
39 m_allocator(allocator),
40 m_hwInterface(hwInterface)
41 {
42 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hwInterface);
43 m_osInterface = m_hwInterface->GetOsInterface();
44 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
45
46 m_featureManager = featureManager;
47 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_featureManager);
48
49 m_basicFeature = dynamic_cast<EncodeBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
50 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
51 }
ClearStreaminBuffer(uint32_t lucNumber)52 MOS_STATUS HevcVdencRoi::ClearStreaminBuffer(uint32_t lucNumber)
53 {
54 // Clear streamin
55 ENCODE_CHK_NULL_RETURN(m_streamInTemp);
56
57 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(m_streamIn);
58 ENCODE_CHK_NULL_RETURN(data);
59
60 MOS_ZeroMemory(m_streamInTemp, lucNumber * 64);
61 MOS_SecureMemcpy(data, m_streamInSize, m_streamInTemp, m_streamInSize);
62
63 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(m_streamIn));
64
65 return MOS_STATUS_SUCCESS;
66 }
67
Init(void * setting)68 MOS_STATUS HevcVdencRoi::Init(void *setting)
69 {
70 ENCODE_FUNC_CALL();
71 ENCODE_CHK_NULL_RETURN(setting);
72 ENCODE_CHK_NULL_RETURN(m_basicFeature);
73 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf);
74
75 #if (_DEBUG || _RELEASE_INTERNAL)
76 MediaUserSetting::Value outValue;
77 ReadUserSetting(
78 m_userSettingPtr,
79 outValue,
80 "Disable TCBRC ARB for HEVC VDEnc",
81 MediaUserSetting::Group::Sequence);
82 m_isArbRoiSupported = !outValue.Get<bool>();
83 #endif
84
85 MOS_ALLOC_GFXRES_PARAMS allocParams;
86 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
87 allocParams.Type = MOS_GFXRES_BUFFER;
88 allocParams.TileType = MOS_TILE_LINEAR;
89 allocParams.Format = Format_Buffer;
90
91 //reuse 1 streamIn buffer to save latency so enlarge 8-rows buffer w/ different offset for each frame in arb cycle
92 allocParams.dwBytes = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) *
93 ((MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 64) / 32) + 8) * CODECHAL_CACHELINE_SIZE;
94 m_streamInSize = allocParams.dwBytes;
95
96 allocParams.pBufName = "VDEnc StreamIn Data Buffer";
97 allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
98 m_basicFeature->m_recycleBuf->RegisterResource(RecycleResId::StreamInBuffer, allocParams);
99
100 return MOS_STATUS_SUCCESS;
101 }
102
Update(void * params)103 MOS_STATUS HevcVdencRoi::Update(void *params)
104 {
105 ENCODE_FUNC_CALL();
106 ENCODE_CHK_NULL_RETURN(params);
107 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf);
108
109 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams = nullptr;
110 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams = nullptr;
111 PCODEC_HEVC_ENCODE_SLICE_PARAMS hevcSlcParams = nullptr;
112
113 EncoderParams *encodeParams = (EncoderParams *)params;
114
115 hevcSeqParams = static_cast<PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
116 hevcPicParams = static_cast<PCODEC_HEVC_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams);
117 hevcSlcParams = static_cast<PCODEC_HEVC_ENCODE_SLICE_PARAMS>(encodeParams->pSliceParams);
118 ENCODE_CHK_NULL_RETURN(hevcSeqParams);
119 ENCODE_CHK_NULL_RETURN(hevcPicParams);
120 ENCODE_CHK_NULL_RETURN(hevcSlcParams);
121
122 bool pririotyDirtyROI = true;
123
124 m_dirtyRoiEnabled = hevcPicParams->NumDirtyRects && (B_TYPE == hevcPicParams->CodingType);
125 m_mbQpDataEnabled = m_basicFeature->m_mbQpDataEnabled;
126 // Adaptive region boost is enabled for TCBRC only
127 m_isArbRoi = hevcPicParams->TargetFrameSize != 0 && (hevcSeqParams->LookaheadDepth == 0) && m_isArbRoiSupported;
128 m_roiEnabled = hevcPicParams->NumROI > 0 || m_mbQpDataEnabled || m_isArbRoi;
129
130 m_enabled = (m_roiEnabled || m_dirtyRoiEnabled) ? true : false;
131
132 if (!m_enabled)
133 {
134 return MOS_STATUS_SUCCESS;
135 }
136
137 if (!m_isArbRoi)
138 {
139 m_streamIn = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::StreamInBuffer, m_basicFeature->m_frameNum);
140 }
141 else
142 {
143 uint32_t streamInBufferIdx = hevcPicParams->CodingType == I_TYPE ? 0 : 1;
144 m_streamIn = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::StreamInBuffer, streamInBufferIdx);
145
146 uint16_t ArbBoostRow[8] = {0, 3, 5, 2, 7, 4, 1, 6};
147 uint16_t factor = 8 - ArbBoostRow[m_basicFeature->m_frameNum % 8];
148
149 if (factor % 2 == 0)
150 {
151 m_streamIn->dwResourceOffset = factor * (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) * CODECHAL_CACHELINE_SIZE;
152 }
153 else
154 {
155 m_streamIn->dwResourceOffset = ((factor + 1) * (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) - 2) * CODECHAL_CACHELINE_SIZE;
156 }
157 }
158 ENCODE_CHK_NULL_RETURN(m_streamIn);
159
160 if (!m_isArbRoi || (hevcPicParams->CodingType == I_TYPE && !IFrameIsSet) || ((hevcPicParams->CodingType == P_TYPE || hevcPicParams->CodingType == B_TYPE) && !PBFrameIsSet))
161 {
162 m_streamInTemp = (uint8_t *)MOS_AllocMemory(m_streamInSize);
163 ENCODE_CHK_NULL_RETURN(m_streamInTemp);
164
165 uint32_t lcuNumber = GetLCUNumber();
166
167 ENCODE_CHK_STATUS_RETURN(ClearStreaminBuffer(lcuNumber));
168
169 m_roiOverlap.Update(lcuNumber);
170
171 ENCODE_CHK_STATUS_RETURN(ExecuteDirtyRoi(hevcSeqParams, hevcPicParams, hevcSlcParams));
172
173 MEDIA_WA_TABLE *waTable = m_basicFeature->GetWaTable();
174 ENCODE_CHK_NULL_RETURN(waTable);
175
176 if (MEDIA_IS_WA(waTable, WaHEVCVDEncForceDeltaQpRoiNotSupported) || m_isArbRoi || m_mbQpDataEnabled)
177 {
178 m_roiMode = false;
179 ENCODE_CHK_STATUS_RETURN(ExecuteRoi(hevcSeqParams, hevcPicParams, hevcSlcParams));
180 }
181 else
182 {
183 m_roiMode = true;
184 ENCODE_CHK_STATUS_RETURN(ExecuteRoiExt(hevcSeqParams, hevcPicParams, hevcSlcParams));
185 }
186
187 ENCODE_CHK_STATUS_RETURN(WriteStreaminData());
188
189 MOS_SafeFreeMemory(m_streamInTemp);
190
191 #if (_DEBUG || _RELEASE_INTERNAL)
192 ENCODE_CHK_NULL_RETURN(m_hwInterface);
193 ENCODE_CHK_NULL_RETURN(m_hwInterface->GetOsInterface());
194 ReportUserSettingForDebug(
195 m_userSettingPtr ,
196 "HEVC VDEnc Force Delta QP Enable",
197 m_roiMode,
198 MediaUserSetting::Group::Sequence);
199 #endif
200
201 if (hevcPicParams->CodingType == I_TYPE)
202 {
203 IFrameIsSet = true;
204 }
205 else
206 {
207 PBFrameIsSet = true;
208 }
209 }
210
211 return MOS_STATUS_SUCCESS;
212 }
213
WriteStreaminData()214 MOS_STATUS HevcVdencRoi::WriteStreaminData()
215 {
216 ENCODE_CHK_NULL_RETURN(m_streamIn);
217 ENCODE_CHK_NULL_RETURN(m_streamInTemp);
218
219 uint8_t *streaminBuffer = (uint8_t *)m_allocator->LockResourceForWrite(m_streamIn);
220 ENCODE_CHK_NULL_RETURN(streaminBuffer);
221
222 m_roiOverlap.WriteStreaminData(
223 m_strategyFactory.GetRoi(),
224 m_strategyFactory.GetDirtyRoi(),
225 m_streamInTemp);
226
227 MOS_SecureMemcpy(streaminBuffer, m_streamInSize, m_streamInTemp, m_streamInSize);
228
229 m_allocator->UnLock(m_streamIn);
230 return MOS_STATUS_SUCCESS;
231 }
232
ExecuteRoi(SeqParams * hevcSeqParams,PicParams * hevcPicParams,SlcParams * hevcSlcParams)233 MOS_STATUS HevcVdencRoi::ExecuteRoi(
234 SeqParams *hevcSeqParams,
235 PicParams *hevcPicParams,
236 SlcParams *hevcSlcParams)
237 {
238 if (!m_roiEnabled)
239 {
240 return MOS_STATUS_SUCCESS;
241 }
242
243 ENCODE_CHK_NULL_RETURN(m_featureManager);
244
245 if (!m_mbQpDataEnabled)
246 {
247 uint8_t numDistinctDeltaQp = sizeof(hevcPicParams->ROIDistinctDeltaQp) / sizeof(int8_t);
248 m_isNativeRoi = ProcessRoiDeltaQp(
249 hevcPicParams->NumROI,
250 hevcPicParams->ROI,
251 numDistinctDeltaQp,
252 hevcPicParams->ROIDistinctDeltaQp);
253
254 if (m_isArbRoi)
255 {
256 m_isNativeRoi = false;
257 }
258 }
259
260 RoiStrategy *strategy = m_strategyFactory.CreateStrategy(
261 m_allocator, m_featureManager, m_osInterface, m_isArbRoi, false, m_isNativeRoi, m_mbQpDataEnabled);
262 ENCODE_CHK_NULL_RETURN(strategy);
263 strategy->SetFeatureSetting(static_cast<HevcVdencFeatureSettings *>(m_constSettings));
264 ENCODE_CHK_STATUS_RETURN(
265 strategy->PrepareParams(hevcSeqParams, hevcPicParams, hevcSlcParams));
266
267 ENCODE_CHK_STATUS_RETURN(strategy->SetupRoi(m_roiOverlap));
268 return MOS_STATUS_SUCCESS;
269 }
270
ExecuteRoiExt(SeqParams * hevcSeqParams,PicParams * hevcPicParams,SlcParams * hevcSlcParams)271 MOS_STATUS HevcVdencRoi::ExecuteRoiExt(
272 SeqParams *hevcSeqParams,
273 PicParams *hevcPicParams,
274 SlcParams *hevcSlcParams)
275 {
276 if (!m_roiEnabled)
277 {
278 return MOS_STATUS_SUCCESS;
279 }
280
281 ENCODE_CHK_NULL_RETURN(m_featureManager);
282
283
284 RoiStrategy* strategy = m_strategyFactory.CreateStrategyForceDeltaQP(
285 m_allocator, m_featureManager, m_osInterface);
286
287 ENCODE_CHK_NULL_RETURN(strategy);
288 strategy->SetFeatureSetting(static_cast<HevcVdencFeatureSettings *>(m_constSettings));
289 ENCODE_CHK_STATUS_RETURN(
290 strategy->PrepareParams(hevcSeqParams, hevcPicParams, hevcSlcParams));
291
292 ENCODE_CHK_STATUS_RETURN(strategy->SetupRoi(m_roiOverlap));
293 return MOS_STATUS_SUCCESS;
294 }
295
ExecuteDirtyRoi(SeqParams * hevcSeqParams,PicParams * hevcPicParams,SlcParams * hevcSlcParams)296 MOS_STATUS HevcVdencRoi::ExecuteDirtyRoi(
297 SeqParams *hevcSeqParams,
298 PicParams *hevcPicParams,
299 SlcParams *hevcSlcParams)
300 {
301 if (!m_dirtyRoiEnabled)
302 {
303 return MOS_STATUS_SUCCESS;
304 }
305
306 ENCODE_CHK_NULL_RETURN(m_featureManager);
307
308 RoiStrategy *strategy = m_strategyFactory.CreateStrategy(
309 m_allocator, m_featureManager, m_osInterface, false, true, false);
310 ENCODE_CHK_NULL_RETURN(strategy);
311 strategy->SetFeatureSetting(static_cast<HevcVdencFeatureSettings *>(m_constSettings));
312 ENCODE_CHK_STATUS_RETURN(
313 strategy->PrepareParams(hevcSeqParams, hevcPicParams, hevcSlcParams));
314
315 ENCODE_CHK_STATUS_RETURN(strategy->SetupRoi(m_roiOverlap));
316
317 return MOS_STATUS_SUCCESS;
318 }
319
ProcessRoiDeltaQp(uint8_t numROI,CODEC_ROI * roiRegions,uint8_t numDistinctDeltaQp,int8_t * roiDistinctDeltaQp)320 bool HevcVdencRoi::ProcessRoiDeltaQp(
321 uint8_t numROI,
322 CODEC_ROI *roiRegions,
323 uint8_t numDistinctDeltaQp,
324 int8_t *roiDistinctDeltaQp)
325 {
326 ENCODE_FUNC_CALL();
327
328 // Intialize ROIDistinctDeltaQp to be min expected delta qp, setting to -128
329 // Check if forceQp is needed or not
330 // forceQp is enabled if there are greater than 3 distinct delta qps or if the deltaqp is beyond range (-8, 7)
331 for (auto k = 0; k < numDistinctDeltaQp; k++)
332 {
333 roiDistinctDeltaQp[k] = -128;
334 }
335
336 int32_t numQp = 0;
337 for (int32_t i = 0; i < numROI; i++)
338 {
339 bool dqpNew = true;
340
341 //Get distinct delta Qps among all ROI regions, index 0 having the lowest delta qp
342 int32_t k = numQp - 1;
343 for (; k >= 0; k--)
344 {
345 if (roiRegions[i].PriorityLevelOrDQp == roiDistinctDeltaQp[k] ||
346 roiRegions[i].PriorityLevelOrDQp == 0)
347 {
348 dqpNew = false;
349 break;
350 }
351 else if (roiRegions[i].PriorityLevelOrDQp < roiDistinctDeltaQp[k])
352 {
353 continue;
354 }
355 else
356 {
357 break;
358 }
359 }
360
361 if (dqpNew)
362 {
363 for (int32_t j = numQp - 1; j >= k + 1; j--)
364 {
365 roiDistinctDeltaQp[j + 1] = roiDistinctDeltaQp[j];
366 }
367 roiDistinctDeltaQp[k + 1] = roiRegions[i].PriorityLevelOrDQp;
368 numQp++;
369 }
370 }
371
372 //Set the ROI DeltaQp to zero for remaining array elements
373 for (auto k = numQp; k < m_maxNumRoi; k++)
374 {
375 roiDistinctDeltaQp[k] = 0;
376 }
377
378 // return whether is native ROI or not
379 return (!(numQp > m_maxNumNativeRoi || roiDistinctDeltaQp[0] < -8 || roiDistinctDeltaQp[numQp - 1] > 7));
380 }
381
SetVdencPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)382 MOS_STATUS HevcVdencRoi::SetVdencPipeBufAddrParams(
383 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
384 {
385 if (!m_enabled)
386 {
387 return MOS_STATUS_SUCCESS;
388 }
389
390 RoiStrategy *strategy = GetStrategyForParamsSetting();
391 ENCODE_CHK_NULL_RETURN(strategy);
392
393 strategy->SetVdencPipeBufAddrParams(m_streamIn, pipeBufAddrParams);
394 return MOS_STATUS_SUCCESS;
395 }
396
SetDmemHuCBrcInitReset(VdencHevcHucBrcInitDmem * hucVdencBrcInitDmem)397 MOS_STATUS HevcVdencRoi::SetDmemHuCBrcInitReset(
398 VdencHevcHucBrcInitDmem *hucVdencBrcInitDmem)
399 {
400 if (!m_enabled)
401 {
402 return MOS_STATUS_SUCCESS;
403 }
404
405 RoiStrategy *strategy = GetStrategyForParamsSetting();
406 ENCODE_CHK_NULL_RETURN(strategy);
407
408 return strategy->SetDmemHuCBrcInitReset(hucVdencBrcInitDmem);
409 }
410
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,HevcVdencRoi)411 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, HevcVdencRoi)
412 {
413 if (!m_enabled)
414 {
415 return MOS_STATUS_SUCCESS;
416 }
417
418 RoiStrategy *strategy = GetStrategyForParamsSetting();
419 ENCODE_CHK_NULL_RETURN(strategy);
420
421 auto buf = strategy->GetStreamInBuf();
422 params.streamInBuffer = (buf == nullptr) ? m_streamIn : buf;
423
424 return MOS_STATUS_SUCCESS;
425 }
426
MHW_SETPAR_DECL_SRC(VDENC_CMD2,HevcVdencRoi)427 MHW_SETPAR_DECL_SRC(VDENC_CMD2, HevcVdencRoi)
428 {
429 if (!m_enabled)
430 {
431 return MOS_STATUS_SUCCESS;
432 }
433
434 auto hevcFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature);
435 ENCODE_CHK_NULL_RETURN(hevcFeature);
436
437 params.vdencStreamIn = m_enabled;
438 params.roiStreamIn = m_isNativeRoi || m_isArbRoi;
439
440 if (m_isNativeRoi)
441 {
442 int8_t roiTable[ENCODE_VDENC_HEVC_MAX_STREAMINROI_G10] = {0};
443
444 for (uint8_t i = 0; i < ENCODE_VDENC_HEVC_MAX_STREAMINROI_G10; i++)
445 {
446 roiTable[i] = (int8_t)CodecHal_Clip3(
447 ENCODE_VDENC_HEVC_MIN_ROI_DELTA_QP_G10, ENCODE_VDENC_HEVC_MAX_ROI_DELTA_QP_G10, hevcFeature->m_hevcPicParams->ROIDistinctDeltaQp[i]);
448 }
449
450 #if !(_MEDIA_RESERVED)
451 params.extSettings.emplace_back(
452 [&roiTable](uint32_t *data) {
453 data[13] |= (roiTable[0] << 4);
454 data[13] |= (roiTable[1] << 8);
455 data[13] |= (roiTable[2] << 12);
456 return MOS_STATUS_SUCCESS;
457 });
458 #else
459 params.vdencCmd2Par43[1] = roiTable[0];
460 params.vdencCmd2Par43[2] = roiTable[1];
461 params.vdencCmd2Par43[3] = roiTable[2];
462 #endif // !(_MEDIA_RESERVED)
463 }
464
465 bool flag0 = false;
466 bool flag1 = false;
467 if (m_roiMode)
468 {
469 flag0 = 1;
470 flag1 = 1;
471 }
472 else if (!m_roiMode && !m_isNativeRoi && !m_dirtyRoiEnabled && !m_isArbRoi)
473 {
474 flag0 = 0;
475 flag1 = 1;
476 }
477
478 #if !(_MEDIA_RESERVED)
479 params.extSettings.emplace_back(
480 [flag0, flag1](uint32_t *data) {
481 data[20] |= (flag0 << 17);
482 data[20] |= (flag1 << 19);
483 return MOS_STATUS_SUCCESS;
484 });
485 #else
486 params.vdencCmd2Par60 = flag0;
487 params.vdencCmd2Par61 = flag1;
488 #endif // !(_MEDIA_RESERVED)
489
490 return MOS_STATUS_SUCCESS;
491 }
492 }
493