1 /*
2 * Copyright (c) 2021-2024, 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_aqm_feature.cpp
24 //! \brief Defines the common interface for aqm feature
25 //!
26
27 #include <iomanip>
28
29 #include "encode_aqm_feature.h"
30 #include "encode_feature_manager.h"
31 #include "encode_utils.h"
32 #include "media_perf_profiler.h"
33
34 namespace encode
35 {
EncodeAqmFeature(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)36 EncodeAqmFeature::EncodeAqmFeature(
37 MediaFeatureManager *featureManager,
38 EncodeAllocator * allocator,
39 CodechalHwInterfaceNext *hwInterface,
40 void * constSettings) : MediaFeature(constSettings),
41 m_hwInterface(hwInterface),
42 m_allocator(allocator)
43 {
44 ENCODE_FUNC_CALL();
45
46 m_featureManager = featureManager;
47
48 auto encFeatureManager = dynamic_cast<EncodeFeatureManager *>(featureManager);
49 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
50
51 if (hwInterface)
52 {
53 m_mosCtx = hwInterface->GetOsInterface()->pOsContext;
54 m_userSettingPtr = hwInterface->GetOsInterface()->pfnGetUserSettingInstance(hwInterface->GetOsInterface());
55 }
56
57 m_basicFeature = dynamic_cast<EncodeBasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature));
58 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
59
60 #if (_DEBUG || _RELEASE_INTERNAL)
61 MediaUserSetting::Value outValue;
62 ReadUserSetting(
63 m_userSettingPtr,
64 outValue,
65 "VDAQM Enable",
66 MediaUserSetting::Group::Sequence);
67
68 m_metricsDumpMode = outValue.Get<uint8_t>();
69
70 #endif
71
72 if (m_metricsDumpMode > 0)
73 {
74 m_enabled = true;
75 }
76 #if _MEDIA_RESERVED
77 #if USE_CODECHAL_DEBUG_TOOL
78 MetricsDump();
79 #endif
80 #endif
81 }
82
~EncodeAqmFeature()83 EncodeAqmFeature::~EncodeAqmFeature()
84 {
85 if (m_enabled)
86 {
87 FreeResources();
88 #if _MEDIA_RESERVED
89 #if USE_CODECHAL_DEBUG_TOOL
90 CloseDumpFiles();
91 #endif
92 #endif
93 }
94 }
95
EncodeAqmFeatureFunction0(uint32_t frameWidth,uint32_t frameHeight,uint8_t index)96 uint32_t EncodeAqmFeature::EncodeAqmFeatureFunction0(uint32_t frameWidth, uint32_t frameHeight, uint8_t index)
97 {
98 uint32_t width = (frameWidth + (1 << index) - 1) >> index;
99 uint32_t height = (frameHeight + (1 << index) - 1) >> index;
100 return (MOS_ALIGN_CEIL(MOS_ALIGN_CEIL(width, 4) / 4, CL_SIZE_BYTES) * (MOS_ALIGN_CEIL(height, 4) / 4));
101 }
102
Update(void * params)103 MOS_STATUS EncodeAqmFeature::Update(void *params)
104 {
105 if (m_enabled)
106 {
107 ENCODE_CHK_STATUS_RETURN(AllocateResources());
108 }
109
110 return MOS_STATUS_SUCCESS;
111 }
112
AllocateResources()113 MOS_STATUS EncodeAqmFeature::AllocateResources()
114 {
115 ENCODE_FUNC_CALL();
116
117 if (m_AllocatedResources)
118 {
119 return MOS_STATUS_SUCCESS;
120 }
121
122 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
123 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
124
125 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
126 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
127 allocParamsForBufferLinear.Format = Format_Buffer;
128 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
129
130 uint32_t rowstoreBufferSize[5] = {(m_basicFeature->m_oriFrameWidth / 4 + 1), 3391, 1665, 833, 417};
131 for (int i = 0; i < 5; i++)
132 {
133 std::string bufName = "Index" + std::to_string(i) + "LineRowstoreBuffer";
134 allocParamsForBufferLinear.dwBytes = rowstoreBufferSize[i] * CL_SIZE_BYTES * m_numRowStore;
135 allocParamsForBufferLinear.pBufName = &*bufName.begin();
136 EncodeAqmFeatureMember0[i] = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
137 EncodeAqmFeatureMember1[i] = rowstoreBufferSize[i] * CL_SIZE_BYTES;
138 }
139
140 EncodeAqmFeatureMember2 = ((sizeof(AQM_Ouput_Format) + CL_SIZE_BYTES - 1) / CL_SIZE_BYTES) * CL_SIZE_BYTES * m_numTiles;
141 EncodeAqmFeatureMember3[0] = 0;
142 EncodeAqmFeatureMember3[1] = EncodeAqmFeatureFunction0(m_basicFeature->m_oriFrameWidth, m_basicFeature->m_oriFrameHeight, 1);
143 EncodeAqmFeatureMember3[2] = EncodeAqmFeatureFunction0(m_basicFeature->m_oriFrameWidth, m_basicFeature->m_oriFrameHeight, 2);
144 EncodeAqmFeatureMember3[3] = EncodeAqmFeatureFunction0(m_basicFeature->m_oriFrameWidth, m_basicFeature->m_oriFrameHeight, 3);
145 EncodeAqmFeatureMember3[4] = EncodeAqmFeatureFunction0(m_basicFeature->m_oriFrameWidth, m_basicFeature->m_oriFrameHeight, 4);
146
147 // allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
148
149 allocParamsForBufferLinear.dwBytes = EncodeAqmFeatureMember2;
150 allocParamsForBufferLinear.pBufName = "VdaqmBuffer0";
151 m_basicFeature->m_recycleBuf->RegisterResource(RecycleResId::VdaqmBuffer0, allocParamsForBufferLinear, EncodeBasicFeature::m_uncompressedSurfaceNum);
152
153 allocParamsForBufferLinear.dwBytes = EncodeAqmFeatureMember3[1];
154 allocParamsForBufferLinear.pBufName = "VdaqmBuffer1";
155 m_basicFeature->m_recycleBuf->RegisterResource(RecycleResId::VdaqmBuffer1, allocParamsForBufferLinear, EncodeBasicFeature::m_uncompressedSurfaceNum);
156
157 allocParamsForBufferLinear.dwBytes = EncodeAqmFeatureMember3[2];
158 allocParamsForBufferLinear.pBufName = "VdaqmBuffer2";
159 m_basicFeature->m_recycleBuf->RegisterResource(RecycleResId::VdaqmBuffer2, allocParamsForBufferLinear, EncodeBasicFeature::m_uncompressedSurfaceNum);
160
161 allocParamsForBufferLinear.dwBytes = EncodeAqmFeatureMember3[3];
162 allocParamsForBufferLinear.pBufName = "VdaqmBuffer3";
163 m_basicFeature->m_recycleBuf->RegisterResource(RecycleResId::VdaqmBuffer3, allocParamsForBufferLinear, EncodeBasicFeature::m_uncompressedSurfaceNum);
164
165 allocParamsForBufferLinear.dwBytes = EncodeAqmFeatureMember3[4];
166 allocParamsForBufferLinear.pBufName = "VdaqmBuffer4";
167 m_basicFeature->m_recycleBuf->RegisterResource(RecycleResId::VdaqmBuffer4, allocParamsForBufferLinear, EncodeBasicFeature::m_uncompressedSurfaceNum);
168
169 m_AllocatedResources = true;
170
171 return MOS_STATUS_SUCCESS;
172 }
173
FreeResources()174 MOS_STATUS EncodeAqmFeature::FreeResources()
175 {
176 ENCODE_FUNC_CALL();
177
178 if (m_AllocatedResources)
179 {
180 for (uint8_t index = 0; index < AQM_INDEX; index++)
181 m_allocator->DestroyResource(EncodeAqmFeatureMember0[index]);
182 }
183
184 m_AllocatedResources = false;
185
186 return MOS_STATUS_SUCCESS;
187 }
188
MHW_SETPAR_DECL_SRC(AQM_FRAME_START,EncodeAqmFeature)189 MHW_SETPAR_DECL_SRC(AQM_FRAME_START, EncodeAqmFeature)
190 {
191 if (m_enabled)
192 {
193 params.aqmFrameStart = 1;
194 }
195
196 return MOS_STATUS_SUCCESS;
197 }
198
MHW_SETPAR_DECL_SRC(AQM_PIC_STATE,EncodeAqmFeature)199 MHW_SETPAR_DECL_SRC(AQM_PIC_STATE, EncodeAqmFeature)
200 {
201 if (m_enabled)
202 {
203 params.frameWidthInPixelMinus1 = MOS_ALIGN_CEIL(m_basicFeature->m_oriFrameWidth, 8) - 1;
204 params.FrameHeightInPixelMinus1 = MOS_ALIGN_CEIL(m_basicFeature->m_oriFrameHeight, 8) - 1;
205 params.vdaqmEnable = m_enabled;
206 params.tileBasedEngine = m_tileBasedEngine;
207 params.chromasubsampling = m_basicFeature->m_chromaFormat - 1;
208 params.aqmMode = m_aqmMode;
209 params.sseEnable = true;
210 #if _MEDIA_RESERVED
211 #define AQM_PIC_STATE_SETPAR_EXT
212 #include "encode_aqm_feature_ext.h"
213 #undef AQM_PIC_STATE_SETPAR_EXT
214 #else
215 params.extSettings.emplace_back(
216 [this](uint32_t *data) {
217 data[2] |= 0x1e;
218 data[3] |= 0x1a334d66;
219 data[4] |= 0x809ab3cd;
220 data[5] |= 0xe6000000;
221 data[6] |= 0x80001;
222 data[7] |= 0x700025;
223 data[8] |= 0x11000da;
224 data[9] |= 0x80001;
225 data[10] |= 0x700025;
226 data[11] |= 0x11000da;
227
228 return MOS_STATUS_SUCCESS;
229 });
230 #endif
231 if (m_basicFeature->m_bitDepth == 8)
232 {
233 params.pixelbitdepth = 0;
234 }
235 else if (m_basicFeature->m_bitDepth == 10)
236 {
237 params.pixelbitdepth = 1;
238 }
239 else if (m_basicFeature->m_bitDepth == 12)
240 {
241 params.pixelbitdepth = 2;
242 }
243 }
244
245 return MOS_STATUS_SUCCESS;
246 }
247
MHW_SETPAR_DECL_SRC(AQM_PIPE_BUF_ADDR_STATE,EncodeAqmFeature)248 MHW_SETPAR_DECL_SRC(AQM_PIPE_BUF_ADDR_STATE, EncodeAqmFeature)
249 {
250 if (m_enabled)
251 {
252 auto bIdx = m_basicFeature->m_currOriginalPic.FrameIdx;
253
254 for (uint8_t index = 0; index < AQM_INDEX; index++)
255 {
256 params.AqmPipeBufAddrStatePar0[index] = EncodeAqmFeatureMember0[index];
257 params.AqmPipeBufAddrStatePar1[index] = EncodeAqmFeatureMember1[index] * m_currPipeNum;
258 }
259
260 params.AqmPipeBufAddrStatePar4[0] = nullptr;
261 params.AqmPipeBufAddrStatePar4[1] = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::VdaqmBuffer1, bIdx);
262 params.AqmPipeBufAddrStatePar4[2] = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::VdaqmBuffer2, bIdx);
263 params.AqmPipeBufAddrStatePar4[3] = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::VdaqmBuffer3, bIdx);
264 params.AqmPipeBufAddrStatePar4[4] = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::VdaqmBuffer4, bIdx);
265 params.AqmPipeBufAddrStatePar2 = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::VdaqmBuffer0, bIdx);
266 }
267
268 return MOS_STATUS_SUCCESS;
269 }
270
271 #if USE_CODECHAL_DEBUG_TOOL
UpdateFrameDisplayOrder(const uint16_t pictureCodingType,const uint32_t framePOC,const uint32_t gopPicSize)272 MOS_STATUS EncodeAqmFeature::UpdateFrameDisplayOrder(const uint16_t pictureCodingType, const uint32_t framePOC, const uint32_t gopPicSize)
273 {
274 if (pictureCodingType == I_TYPE)
275 {
276 m_frameNumPrevious += m_gopSizePrevious;
277 }
278 uint32_t displayOrderInGOP = framePOC;
279 uint32_t displayOrderInSeq = displayOrderInGOP + m_frameNumPrevious;
280 m_gopSizePrevious = gopPicSize;
281 m_frameIdxQueue.push(displayOrderInSeq);
282 return MOS_STATUS_SUCCESS;
283 }
284 #endif
285
286 #if _MEDIA_RESERVED
287 #define AQM_FEATURE_SOURCE_EXT
288 #include "encode_aqm_feature_ext.h"
289 #undef AQM_FEATURE_SOURCE_EXT
290 #endif
291
GetFrameMSE(AQM_Ouput_Format * pDataFrame,uint32_t (& MSE)[3])292 MOS_STATUS EncodeAqmFeature::GetFrameMSE(AQM_Ouput_Format* pDataFrame, uint32_t (&MSE)[3])
293 {
294 ENCODE_CHK_NULL_RETURN(pDataFrame);
295
296 uint64_t SSE[3] = {};
297 uint32_t areaSum = 0;
298
299 // Get Tile MSE
300 uint32_t offsetAqmTile = MOS_ALIGN_CEIL(sizeof(AQM_Ouput_Format), CL_SIZE_BYTES);
301 for (uint32_t tileIdx = 0; tileIdx < m_numTiles && tileIdx < ENCODE_VDENC_MAX_TILE_NUM; tileIdx++)
302 {
303 AQM_Ouput_Format* pTileVdaqmInfo = (AQM_Ouput_Format*)((char*)pDataFrame + offsetAqmTile * tileIdx);
304 ENCODE_CHK_NULL_RETURN(pTileVdaqmInfo);
305
306 uint32_t area = m_tile_width[tileIdx] * m_tile_height[tileIdx];
307 SSE[0] += (uint64_t)pTileVdaqmInfo->SSEY * (uint64_t)area;
308 SSE[1] += (uint64_t)pTileVdaqmInfo->SSEU * (uint64_t)area;
309 SSE[2] += (uint64_t)pTileVdaqmInfo->SSEV * (uint64_t)area;
310 areaSum += area;
311 }
312
313 if (areaSum == 0)
314 {
315 ENCODE_ASSERTMESSAGE("frame pixel num cal by each tile is zero, sth must be wrong!");
316 return MOS_STATUS_INVALID_PARAMETER;
317 }
318
319 MSE[0] = (uint32_t)(SSE[0] / (uint64_t)areaSum);
320 MSE[1] = (uint32_t)(SSE[1] / (uint64_t)areaSum);
321 MSE[2] = (uint32_t)(SSE[2] / (uint64_t)areaSum);
322
323 return MOS_STATUS_SUCCESS;
324 }
325
ReportQualityInfoFrame(uint32_t statBufIdx,EncodeStatusReportData & statusReportData)326 MOS_STATUS EncodeAqmFeature::ReportQualityInfoFrame(uint32_t statBufIdx, EncodeStatusReportData& statusReportData)
327 {
328 ENCODE_FUNC_CALL();
329
330 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
331
332 PMOS_RESOURCE pBuffer = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::VdaqmBuffer0, statBufIdx);
333 ENCODE_CHK_NULL_RETURN(pBuffer);
334
335 AQM_Ouput_Format* pDataFrameStas = (AQM_Ouput_Format*)m_allocator->LockResourceForRead(pBuffer);
336 ENCODE_CHK_NULL_RETURN(pDataFrameStas);
337
338 ENCODE_CHK_STATUS_RETURN(GetFrameMSE(pDataFrameStas, statusReportData.MSE));
339
340 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(pBuffer));
341
342 return eStatus;
343 }
344 } // namespace encode
345