1 /*
2 * Copyright (c) 2023, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file encode_hevc_vdenc_fastpass.cpp
24 //! \brief Defines the Xe2_HPM+ Base interface for hevc encode fastpass features
25 //!
26
27 #include "encode_vdenc_hevc_fastpass.h"
28 #include "encode_hevc_vdenc_feature_manager.h"
29
30 namespace encode
31 {
32
HevcVdencFastPass(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)33 HevcVdencFastPass::HevcVdencFastPass(
34 MediaFeatureManager *featureManager,
35 EncodeAllocator *allocator,
36 CodechalHwInterfaceNext *hwInterface,
37 void* constSettings):
38 MediaFeature(constSettings,hwInterface ? hwInterface->GetOsInterface() : nullptr)
39 {
40 ENCODE_FUNC_CALL();
41 auto encFeatureManager = dynamic_cast<EncodeHevcVdencFeatureManager *>(featureManager);
42 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
43
44 m_hevcFeature = dynamic_cast<HevcBasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature));
45 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hevcFeature);
46
47 //regkey to control fast pass encode settings
48 MediaUserSetting::Value outValue;
49 ReadUserSetting(m_userSettingPtr,
50 outValue,
51 "Enable Fast Pass Encode",
52 MediaUserSetting::Group::Sequence);
53
54 m_enableFastPass = outValue.Get<bool>();
55 if (m_enableFastPass)
56 {
57 MediaUserSetting::Value outValue_ratio;
58 MediaUserSetting::Value outValue_type;
59 #if (_DEBUG || _RELEASE_INTERNAL)
60
61 ReadUserSetting(m_userSettingPtr,
62 outValue_ratio,
63 "Fast Pass Encode Downscale Ratio",
64 MediaUserSetting::Group::Sequence);
65 ReadUserSetting(m_userSettingPtr,
66 outValue_type,
67 "Fast Pass Encode Downscale Type",
68 MediaUserSetting::Group::Sequence);
69 #endif
70
71 if (outValue_ratio.Get<int32_t>() == 0)
72 {
73 m_fastPassShiftIndex = 2;
74 }
75 else if (outValue_ratio.Get<int32_t>() == 1)
76 {
77 m_fastPassShiftIndex = 1;
78 }
79 else
80 m_fastPassShiftIndex = 2;
81 m_fastPassDownScaleType = (uint8_t)outValue_type.Get<int32_t>();
82 }
83 }
84
Update(void * params)85 MOS_STATUS HevcVdencFastPass::Update(void *params)
86 {
87 if (!m_enableFastPass)
88 {
89 return MOS_STATUS_SUCCESS;
90 }
91
92 ENCODE_CHK_NULL_RETURN(m_hevcFeature);
93 m_hevcSeqParams = m_hevcFeature->m_hevcSeqParams;
94 ENCODE_CHK_NULL_RETURN(m_hevcSeqParams);
95
96 // hevc needs 8-pixels aligned
97 m_dsWidth = MOS_ALIGN_FLOOR((m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3) >> m_fastPassShiftIndex, 8);
98 m_dsHeight = MOS_ALIGN_FLOOR((m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1) << (m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3) >> m_fastPassShiftIndex, 8);
99
100 return MOS_STATUS_SUCCESS;
101 }
102
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,HevcVdencFastPass)103 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, HevcVdencFastPass)
104 {
105 ENCODE_FUNC_CALL();
106
107 if (!m_enableFastPass)
108 {
109 return MOS_STATUS_SUCCESS;
110 }
111
112 params.fastPassEn = m_enableFastPass;
113 params.fastPassScale = m_fastPassShiftIndex == 2 ? 0 : 1; // fastPassScale:0 indicates 4x4 ds, fastPassScale:1 indicates 2x2 ds
114 params.DownScaleType = m_fastPassDownScaleType; // DownScaleType:0 indicates bilinear, DownScaleType:1 indicates NN
115 params.chromaType = 1; // Fast pass uses 420 type
116 params.bitDepthMinus8 = 0; // Fast pass uses bitdepth 8
117 return MOS_STATUS_SUCCESS;
118 }
119
MHW_SETPAR_DECL_SRC(VDENC_CMD2,HevcVdencFastPass)120 MHW_SETPAR_DECL_SRC(VDENC_CMD2, HevcVdencFastPass)
121 {
122 ENCODE_FUNC_CALL();
123
124 if (!m_enableFastPass)
125 {
126 return MOS_STATUS_SUCCESS;
127 }
128
129 params.width = m_dsWidth;
130 params.height = m_dsHeight;
131
132 return MOS_STATUS_SUCCESS;
133 }
134
MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,HevcVdencFastPass)135 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, HevcVdencFastPass)
136 {
137 ENCODE_FUNC_CALL();
138
139 if (!m_enableFastPass)
140 {
141 return MOS_STATUS_SUCCESS;
142 }
143
144 uint32_t widthInPix = m_dsWidth;
145 uint32_t heightInPix = m_dsHeight;
146 //no tiling
147 params.tileWidth = widthInPix;
148 params.tileHeight = heightInPix;
149
150 if (m_hevcSeqParams->palette_mode_enabled_flag && m_hevcSeqParams->bit_depth_luma_minus8 == 2)
151 {
152 uint32_t SliceQP = m_hevcFeature->m_hevcPicParams->QpY + m_hevcFeature->m_hevcSliceParams->slice_qp_delta;
153 uint32_t tableIdx;
154 if (SliceQP <= 12)
155 {
156 tableIdx = 0;
157 }
158 else if (SliceQP > 12 && SliceQP <= 17)
159 {
160 tableIdx = 1;
161 }
162 else if (SliceQP > 17 && SliceQP <= 22)
163 {
164 tableIdx = 2;
165 }
166 else if (SliceQP > 22 && SliceQP <= 27)
167 {
168 tableIdx = 3;
169 }
170 else if (SliceQP > 27 && SliceQP <= 32)
171 {
172 tableIdx = 4;
173 }
174 else if (SliceQP > 32 && SliceQP <= 37)
175 {
176 tableIdx = 5;
177 }
178 else if (SliceQP > 37 && SliceQP <= 42)
179 {
180 tableIdx = 6;
181 }
182 else if (SliceQP > 42 && SliceQP <= 47)
183 {
184 tableIdx = 7;
185 }
186 else if (SliceQP > 47 && SliceQP <= 49)
187 {
188 tableIdx = 8;
189 }
190 else
191 {
192 tableIdx = 9;
193 }
194
195 static const uint32_t table[3][10][11] =
196 {
197 {
198 {16},
199 {16},
200 {16},
201 {16},
202 {32},
203 {48},
204 {64},
205 {96},
206 {128},
207 {256},
208 },
209 {
210 {16},
211 {16},
212 {16},
213 {16},
214 {32},
215 {48},
216 {64},
217 {96},
218 {128},
219 {256},
220 },
221 {
222 {256},
223 {256},
224 {256},
225 {256},
226 {256},
227 {768},
228 {768},
229 {768},
230 {768},
231 {768},
232 },
233 };
234
235 params.VdencHEVCVP9TileSlicePar5 = 4;
236 params.VdencHEVCVP9TileSlicePar14 = table[params.VdencHEVCVP9TileSlicePar1][tableIdx][0];
237 params.VdencHEVCVP9TileSlicePar6 >>= 2;
238 params.VdencHEVCVP9TileSlicePar7 >>= 2;
239 }
240
241 return MOS_STATUS_SUCCESS;
242 }
243
MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE,HevcVdencFastPass)244 MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE, HevcVdencFastPass)
245 {
246 ENCODE_FUNC_CALL();
247
248 if (!m_enableFastPass)
249 {
250 return MOS_STATUS_SUCCESS;
251 }
252
253 auto t_sliceParams = m_hevcFeature->m_hevcSliceParams;
254 CODEC_HEVC_ENCODE_SLICE_PARAMS *sliceParams = (CODEC_HEVC_ENCODE_SLICE_PARAMS *)&t_sliceParams[m_hevcFeature->m_curNumSlices];
255
256 uint32_t ctbSize = 1 << (m_hevcSeqParams->log2_max_coding_block_size_minus3 + 3);
257 uint32_t widthInCtb = (m_dsWidth / ctbSize) + ((m_dsWidth % ctbSize) ? 1 : 0); // round up
258 uint32_t heightInCtb = (m_dsHeight / ctbSize) + ((m_dsHeight % ctbSize) ? 1 : 0); // round up
259 //no tiling
260 params.tileSliceStartLcuMbY = sliceParams->slice_segment_address / widthInCtb;
261 params.nextTileSliceStartLcuMbX = (sliceParams->slice_segment_address + widthInCtb * heightInCtb) / heightInCtb;
262 params.nextTileSliceStartLcuMbY = (sliceParams->slice_segment_address + widthInCtb * heightInCtb) / widthInCtb;
263
264 return MOS_STATUS_SUCCESS;
265 }
266
MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE,HevcVdencFastPass)267 MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE, HevcVdencFastPass)
268 {
269 ENCODE_FUNC_CALL();
270
271 if (!m_enableFastPass)
272 {
273 return MOS_STATUS_SUCCESS;
274 }
275
276 params.width = m_dsWidth;
277 params.height = m_dsHeight;
278
279 //Fast pass uses 420 type
280 if (m_hevcSeqParams->chroma_format_idc != 1)
281 {
282 params.format = Format_NV12;
283 params.vOffset = params.uOffset;
284 }
285
286 return MOS_STATUS_SUCCESS;
287 }
288
MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE,HevcVdencFastPass)289 MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE, HevcVdencFastPass)
290 {
291 ENCODE_FUNC_CALL();
292
293 if (!m_enableFastPass)
294 {
295 return MOS_STATUS_SUCCESS;
296 }
297
298 uint32_t dsWidth4x = m_dsWidth / SCALE_FACTOR_4x;
299 uint32_t dsHeight4x = m_dsHeight / SCALE_FACTOR_4x;
300
301 params.heightStage1 = dsHeight4x >> 1;
302 params.widthStage1 = dsWidth4x >> 1;
303 params.heightStage2 = dsHeight4x;
304 params.widthStage2 = dsWidth4x;
305
306 return MOS_STATUS_SUCCESS;
307 }
MHW_SETPAR_DECL_SRC(HCP_PIC_STATE,HevcVdencFastPass)308 MHW_SETPAR_DECL_SRC(HCP_PIC_STATE, HevcVdencFastPass)
309 {
310 ENCODE_FUNC_CALL();
311
312 if (!m_enableFastPass)
313 {
314 return MOS_STATUS_SUCCESS;
315 }
316
317 params.framewidthinmincbminus1 = (m_dsWidth >> 3) - 1;
318 params.frameheightinmincbminus1 = (m_dsHeight >> 3) - 1;
319
320 //Fast pass uses 420 type, bitdepth 8
321 if (m_hevcSeqParams->chroma_format_idc != 1)
322 {
323 params.chromaSubsampling = 1;
324 params.lcuMaxBitSizeAllowedMsb2its >>= 1;
325 params.lcuMaxBitsizeAllowed >>= 1;
326 }
327 if (m_hevcSeqParams->bit_depth_luma_minus8 == 2)
328 {
329 params.bitDepthChromaMinus8 = 0;
330 params.bitDepthLumaMinus8 = 0;
331 }
332
333 //RDOQ TU7 is related to framesize, it needs to be downscaled.
334 if (m_hevcFeature->m_targetUsage == 7)
335 {
336 uint32_t frameSize_ds = m_dsWidth * m_dsHeight;
337 params.rdoqintratuthreshold = MOS_MIN(((frameSize_ds * 30) / 100) >> 8, 0xffff);
338 }
339 return MOS_STATUS_SUCCESS;
340 }
341
MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE,HevcVdencFastPass)342 MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE, HevcVdencFastPass)
343 {
344 ENCODE_FUNC_CALL();
345
346 if (!m_enableFastPass)
347 {
348 return MOS_STATUS_SUCCESS;
349 }
350
351 using namespace mhw::vdbox;
352
353 //Fast pass uses 420 type, bitdepth 8
354 if (m_hevcSeqParams->chroma_format_idc != 1)
355 {
356 params.yOffsetForVCr = (uint16_t)params.yOffsetForUCbInPixel;
357 }
358 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_PLANAR4208;
359
360 return MOS_STATUS_SUCCESS;
361 }
362
MHW_SETPAR_DECL_SRC(HEVC_VP9_RDOQ_STATE,HevcVdencFastPass)363 MHW_SETPAR_DECL_SRC(HEVC_VP9_RDOQ_STATE, HevcVdencFastPass)
364 {
365 ENCODE_FUNC_CALL();
366
367 if (!m_enableFastPass)
368 {
369 return MOS_STATUS_SUCCESS;
370 }
371
372 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams = m_hevcFeature->m_hevcPicParams;
373 ENCODE_CHK_NULL_RETURN(hevcPicParams);
374
375 //Fast pass uses bitdepth 8
376 uint8_t bitDepthLumaMinus8 = 0;
377 uint8_t bitDepthChromaMinus8 = 0;
378 uint8_t codingType = hevcPicParams->CodingType;
379 auto settings = static_cast<HevcVdencFeatureSettings *>(m_constSettings);
380 ENCODE_CHK_NULL_RETURN(settings);
381
382 uint32_t sliceTypeIdx = (codingType == I_TYPE) ? 0 : 1;
383
384 //Intra lambda
385 MOS_ZeroMemory(params.lambdaTab, sizeof(params.lambdaTab));
386 if (bitDepthLumaMinus8 == 0)
387 {
388 std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][0][0].begin(),
389 settings->rdoqLamdas8bits[sliceTypeIdx][0][0].end(),
390 std::begin(params.lambdaTab[0][0]));
391
392 std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][0][1].begin(),
393 settings->rdoqLamdas8bits[sliceTypeIdx][0][1].end(),
394 std::begin(params.lambdaTab[0][1]));
395
396 std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][1][0].begin(),
397 settings->rdoqLamdas8bits[sliceTypeIdx][1][0].end(),
398 std::begin(params.lambdaTab[1][0]));
399
400 std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][1][1].begin(),
401 settings->rdoqLamdas8bits[sliceTypeIdx][1][1].end(),
402 std::begin(params.lambdaTab[1][1]));
403 }
404
405 if (m_hevcFeature->m_hevcRDOQPerfDisabled)
406 {
407 params.disableHtqPerformanceFix0 = true;
408 params.disableHtqPerformanceFix1 = true;
409 }
410 return MOS_STATUS_SUCCESS;
411 }
412
413 } // namespace encode
414