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_avc_vdenc_fast_pass.cpp
24 //! \brief Defines the common interface for encode avc Xe2_HPM+ fast pass feature
25 //!
26
27 #include "encode_avc_vdenc_fastpass.h"
28 #include "encode_avc_vdenc_feature_manager.h"
29 #include <array>
30
31 namespace encode
32 {
33
AvcVdencFastPass(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)34 AvcVdencFastPass::AvcVdencFastPass(
35 MediaFeatureManager *featureManager,
36 EncodeAllocator *allocator,
37 CodechalHwInterfaceNext *hwInterface,
38 void *constSettings) :
39 MediaFeature(constSettings)
40 {
41 auto encFeatureManager = dynamic_cast<EncodeAvcVdencFeatureManager *>(featureManager);
42 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
43
44 m_basicFeature = dynamic_cast<AvcBasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature));
45 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
46 if (hwInterface)
47 {
48 m_userSettingPtr = hwInterface->GetOsInterface()->pfnGetUserSettingInstance(hwInterface->GetOsInterface());
49 }
50 //regkey to control fast pass encode settings
51 MediaUserSetting::Value outValue;
52 ReadUserSetting(m_userSettingPtr,
53 outValue,
54 "Enable Fast Pass Encode",
55 MediaUserSetting::Group::Sequence);
56
57 m_enabled = outValue.Get<bool>();
58 if (m_enabled)
59 {
60 MediaUserSetting::Value outValue_ratio;
61 MediaUserSetting::Value outValue_type;
62 #if (_DEBUG || _RELEASE_INTERNAL)
63
64 ReadUserSetting(m_userSettingPtr,
65 outValue_ratio,
66 "Fast Pass Encode Downscale Ratio",
67 MediaUserSetting::Group::Sequence);
68 ReadUserSetting(m_userSettingPtr,
69 outValue_type,
70 "Fast Pass Encode Downscale Type",
71 MediaUserSetting::Group::Sequence);
72 #endif
73
74 if (outValue_ratio.Get<int32_t>() == 0)
75 {
76 m_fastPassShiftIndex = 2;
77 }
78 else if (outValue_ratio.Get<int32_t>() == 1)
79 {
80 m_fastPassShiftIndex = 1;
81 }
82 else
83 m_fastPassShiftIndex = 2;
84 m_fastPassDownScaleType = (uint8_t)outValue_type.Get<int32_t>();
85 }
86 }
87
Update(void * params)88 MOS_STATUS AvcVdencFastPass::Update(void *params)
89 {
90 if (!m_enabled)
91 {
92 return MOS_STATUS_SUCCESS;
93 }
94 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams = m_basicFeature->m_seqParam;
95 ENCODE_CHK_NULL_RETURN(avcSeqParams);
96
97 m_dsWidth = MOS_ALIGN_FLOOR(avcSeqParams->FrameWidth >> m_fastPassShiftIndex, 16);
98 m_dsHeight = MOS_ALIGN_FLOOR(avcSeqParams->FrameHeight >> m_fastPassShiftIndex, 16);
99 return MOS_STATUS_SUCCESS;
100 }
101
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,AvcVdencFastPass)102 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, AvcVdencFastPass)
103 {
104 ENCODE_FUNC_CALL();
105
106 if (m_enabled)
107 {
108 params.fastPassEn = m_enabled;
109 params.fastPassScale = m_fastPassShiftIndex == 2 ? 0 : 1; // fastPassScale:0 indicates 4x4 ds, fastPassScale:1 indicates 2x2 ds
110 params.DownScaleType = m_fastPassDownScaleType; // DownScaleType:0 indicates bilinear, DownScaleType:1 indicates NN
111 }
112
113 return MOS_STATUS_SUCCESS;
114 }
115
MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE,AvcVdencFastPass)116 MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE, AvcVdencFastPass)
117 {
118 ENCODE_FUNC_CALL();
119
120 if (m_enabled)
121 {
122 params.width = MOS_ALIGN_FLOOR(m_basicFeature->m_reconSurface.dwWidth >> m_fastPassShiftIndex, 16);
123 params.height = MOS_ALIGN_FLOOR(m_basicFeature->m_reconSurface.dwHeight >> m_fastPassShiftIndex, 16);
124 }
125
126 return MOS_STATUS_SUCCESS;
127 }
MHW_SETPAR_DECL_SRC(VDENC_AVC_IMG_STATE,AvcVdencFastPass)128 MHW_SETPAR_DECL_SRC(VDENC_AVC_IMG_STATE, AvcVdencFastPass)
129 {
130 ENCODE_FUNC_CALL();
131
132 if (m_enabled)
133 {
134 params.pictureHeightMinusOne = (m_dsHeight / 16) - 1;
135 params.pictureWidth = m_dsWidth / 16;
136 }
137
138 return MOS_STATUS_SUCCESS;
139 }
MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE,AvcVdencFastPass)140 MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE, AvcVdencFastPass)
141 {
142 ENCODE_FUNC_CALL();
143
144 if (m_enabled)
145 {
146 auto frameHeight = m_dsHeight / 16;
147 auto frameWidth = m_dsWidth / 16;
148
149 auto sliceParams = &(m_basicFeature->m_sliceParams[m_basicFeature->m_curNumSlices]);
150 uint32_t MbNums = frameHeight * frameWidth;
151 auto nextsliceMbStartYPosition = (sliceParams->first_mb_in_slice + MbNums) / frameWidth;
152 params.tileSliceStartLcuMbY = sliceParams->first_mb_in_slice / frameWidth;
153 params.nextTileSliceStartLcuMbY = nextsliceMbStartYPosition > frameHeight ? frameHeight : nextsliceMbStartYPosition;
154 }
155
156 return MOS_STATUS_SUCCESS;
157 }
MHW_SETPAR_DECL_SRC(MFX_AVC_IMG_STATE,AvcVdencFastPass)158 MHW_SETPAR_DECL_SRC(MFX_AVC_IMG_STATE, AvcVdencFastPass)
159 {
160 ENCODE_FUNC_CALL();
161
162 if (m_enabled)
163 {
164 uint32_t numMBs = (m_dsWidth / 16) * (m_dsHeight / 16);
165 params.frameSize = (numMBs > 0xFFFF) ? 0xFFFF : numMBs;
166 params.frameHeight = (m_dsHeight / 16) - 1;
167 params.frameWidth = (m_dsWidth / 16) - 1;
168 }
169
170 return MOS_STATUS_SUCCESS;
171 }
MHW_SETPAR_DECL_SRC(MFX_AVC_SLICE_STATE,AvcVdencFastPass)172 MHW_SETPAR_DECL_SRC(MFX_AVC_SLICE_STATE, AvcVdencFastPass)
173 {
174 ENCODE_FUNC_CALL();
175
176 if (m_enabled)
177 {
178 auto sliceParams = &(m_basicFeature->m_sliceParams[m_basicFeature->m_curNumSlices]);
179 uint32_t startMbNum = sliceParams->first_mb_in_slice * (1 + m_basicFeature->m_seqParam->mb_adaptive_frame_field_flag);
180 uint16_t widthInMb = m_dsWidth / 16;
181 uint16_t heightInMb = m_dsHeight / 16;
182 uint16_t MbNums = widthInMb * heightInMb;
183
184 params.sliceHorizontalPosition = startMbNum % widthInMb;
185 params.sliceVerticalPosition = startMbNum / widthInMb;
186 params.nextSliceHorizontalPosition = (startMbNum + MbNums) % widthInMb;
187 params.nextSliceVerticalPosition = (startMbNum + MbNums) / widthInMb;
188 params.isLastSlice = (startMbNum + MbNums) >= (uint32_t)(widthInMb * heightInMb);
189 }
190
191 return MOS_STATUS_SUCCESS;
192 }
MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE,AvcVdencFastPass)193 MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE, AvcVdencFastPass)
194 {
195 ENCODE_FUNC_CALL();
196
197 if (m_enabled)
198 {
199 uint32_t dsWidth4x = m_dsWidth / 4;
200 uint32_t dsHeight4x = m_dsHeight / 4;
201
202 params.heightStage1 = dsHeight4x;
203 params.widthStage1 = dsWidth4x;
204 }
205
206 return MOS_STATUS_SUCCESS;
207 }
208
MHW_SETPAR_DECL_SRC(VDENC_CMD3,AvcVdencFastPass)209 MHW_SETPAR_DECL_SRC(VDENC_CMD3, AvcVdencFastPass)
210 {
211 ENCODE_FUNC_CALL();
212
213 if (m_enabled)
214 {
215 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams = m_basicFeature->m_seqParam;
216 ENCODE_CHK_NULL_RETURN(avcSeqParams);
217 PCODEC_AVC_ENCODE_PIC_PARAMS avcPicParams = m_basicFeature->m_picParam;
218 ENCODE_CHK_NULL_RETURN(avcPicParams);
219 PCODEC_AVC_ENCODE_SLICE_PARAMS avcSliceParams = m_basicFeature->m_sliceParams;
220 ENCODE_CHK_NULL_RETURN(avcSliceParams);
221
222 auto pictureType = CodecHal_Clip3(0, 2, avcPicParams->CodingType - 1);
223 uint16_t picWidthInMb = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_dsWidth);
224 uint16_t picHeightInMb = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_dsHeight);
225 auto fastpass_qp = CodecHal_Clip3(10, 51, avcPicParams->QpY + avcSliceParams->slice_qp_delta);
226 auto codingType = avcPicParams->CodingType;
227 // Only do this lambda offset for lower resolution and high QP range.
228 uint16_t gopP = (avcSeqParams->GopRefDist) ? ((avcSeqParams->GopPicSize - 1) / avcSeqParams->GopRefDist) : 0;
229 uint16_t gopB = avcSeqParams->GopPicSize - 1 - gopP;
230 uint16_t numB = ((gopP > 0) ? (gopB / gopP) : 0);
231 if ((numB != 0) && (picWidthInMb * 16 < 1920) && (picHeightInMb * 16 < 1080) && (fastpass_qp >= 32))
232 {
233 uint8_t index0 = avcPicParams->RefPicFlag ? 0 : 1;
234 static const std::array<
235 std::array<
236 uint8_t,
237 3>,
238 2>
239 table = {{
240 {0, 1, 1},
241 {0, 1, 2},
242 }};
243 fastpass_qp += table[index0][pictureType];
244 fastpass_qp = CodecHal_Clip3(0, 51, fastpass_qp);
245
246 for (auto i = 0; i < 8; i++)
247 {
248 params.vdencCmd3Par0[i] = m_CMD3Settings.AvcVdencCMD3ConstSettings_0[i][fastpass_qp];
249 }
250
251 if (codingType == I_TYPE || codingType == P_TYPE)
252 params.vdencCmd3Par19 = m_CMD3Settings.AvcVdencCMD3ConstSettings_3[pictureType][fastpass_qp];
253
254 uint8_t isIPGOP = avcSeqParams->GopRefDist == 1 ? 1 : 0;
255 uint8_t codingTypeMinus1 = avcPicParams->CodingType - 1;
256 uint8_t refPic = avcPicParams->RefPicFlag;
257
258 params.vdencCmd3Par31 = m_CMD3Settings.par31Table[isIPGOP][codingTypeMinus1][refPic][fastpass_qp];
259 params.vdencCmd3Par32 = m_CMD3Settings.par32Table[isIPGOP][codingTypeMinus1][refPic][fastpass_qp];
260 }
261 }
262
263 return MOS_STATUS_SUCCESS;
264 }
265
266 } // namespace encode