1 /*
2 * Copyright (c) 2014-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 mhw_sfc.cpp
24 //! \brief MHW interface for constructing commands for the SFC
25 //! \details Impelements the functionalities common across all platforms for MHW_SFC
26 //!
27
28 #include "mhw_sfc.h"
29 #include "mhw_utilities.h"
30
MhwSfcInterface(PMOS_INTERFACE pOsInterface)31 MhwSfcInterface::MhwSfcInterface(PMOS_INTERFACE pOsInterface)
32 {
33 MHW_FUNCTION_ENTER;
34
35 MOS_ZeroMemory(&m_outputSurfCtrl, sizeof(m_outputSurfCtrl));
36 MOS_ZeroMemory(&m_avsLineBufferCtrl, sizeof(m_avsLineBufferCtrl));
37 MOS_ZeroMemory(&m_iefLineBufferCtrl, sizeof(m_iefLineBufferCtrl));
38 MOS_ZeroMemory(&m_sfdLineBufferCtrl, sizeof(m_sfdLineBufferCtrl));
39 pfnAddResourceToCmd = nullptr;
40 m_scalingMode = MHW_SCALING_AVS;
41
42 if (pOsInterface == nullptr)
43 {
44 MHW_ASSERTMESSAGE("Invalid input pointers provided");
45 return;
46 }
47 if (!pOsInterface->bUsesGfxAddress && !pOsInterface->bUsesPatchList)
48 {
49 MHW_ASSERTMESSAGE("No valid addressing mode indicated");
50 return;
51 }
52
53 m_osInterface = pOsInterface;
54
55 if (m_osInterface->bUsesGfxAddress)
56 {
57 pfnAddResourceToCmd = Mhw_AddResourceToCmd_GfxAddress;
58 }
59 else //PatchList
60 {
61 pfnAddResourceToCmd = Mhw_AddResourceToCmd_PatchList;
62 }
63 }
64
SetSfcAVSChromaTable(PSFC_AVS_CHROMA_FILTER_COEFF pUVCoeffTable,int32_t * piUVCoefsX,int32_t * piUVCoefsY)65 void MhwSfcInterface::SetSfcAVSChromaTable(
66 PSFC_AVS_CHROMA_FILTER_COEFF pUVCoeffTable,
67 int32_t *piUVCoefsX,
68 int32_t *piUVCoefsY)
69 {
70 int32_t i;
71
72 MHW_CHK_NULL_NO_STATUS_RETURN(pUVCoeffTable);
73 MHW_CHK_NULL_NO_STATUS_RETURN(piUVCoefsX);
74 MHW_CHK_NULL_NO_STATUS_RETURN(piUVCoefsY);
75
76 for (i = 0; i < NUM_HW_POLYPHASE_TABLES; i++, pUVCoeffTable++)
77 {
78 pUVCoeffTable->DW0.Table1XFilterCoefficient2 = *(piUVCoefsX++);
79 pUVCoeffTable->DW0.Table1XFilterCoefficient3 = *(piUVCoefsX++);
80 pUVCoeffTable->DW1.Table1XFilterCoefficient4 = *(piUVCoefsX++);
81 pUVCoeffTable->DW1.Table1XFilterCoefficient5 = *(piUVCoefsX++);
82
83 pUVCoeffTable->DW0.Table1YFilterCoefficient2 = *(piUVCoefsY++);
84 pUVCoeffTable->DW0.Table1YFilterCoefficient3 = *(piUVCoefsY++);
85 pUVCoeffTable->DW1.Table1YFilterCoefficient4 = *(piUVCoefsY++);
86 pUVCoeffTable->DW1.Table1YFilterCoefficient5 = *(piUVCoefsY++);
87 }
88 }
89
SetSfcAVSLumaTable(MOS_FORMAT SrcFormat,PSFC_AVS_LUMA_FILTER_COEFF pCoeffTable,int32_t * piYCoefsX,int32_t * piYCoefsY,bool bUse8x8Filter)90 void MhwSfcInterface::SetSfcAVSLumaTable(
91 MOS_FORMAT SrcFormat,
92 PSFC_AVS_LUMA_FILTER_COEFF pCoeffTable,
93 int32_t *piYCoefsX,
94 int32_t *piYCoefsY,
95 bool bUse8x8Filter)
96 {
97 int32_t i;
98
99 MHW_CHK_NULL_NO_STATUS_RETURN(pCoeffTable);
100 MHW_CHK_NULL_NO_STATUS_RETURN(piYCoefsX);
101 MHW_CHK_NULL_NO_STATUS_RETURN(piYCoefsY);
102
103 for (i = 0; i < NUM_HW_POLYPHASE_TABLES; i++, pCoeffTable++)
104 {
105 // 4-tap filtering for G-channel, update only center 4 coeffs.
106 if (IS_RGB32_FORMAT(SrcFormat) && (!bUse8x8Filter))
107 {
108 pCoeffTable->DW0.Table0XFilterCoefficient0 = 0;
109 pCoeffTable->DW0.Table0XFilterCoefficient1 = 0;
110 pCoeffTable->DW1.Table0XFilterCoefficient2 = *(piYCoefsX++);
111 pCoeffTable->DW1.Table0XFilterCoefficient3 = *(piYCoefsX++);
112 pCoeffTable->DW2.Table0XFilterCoefficient4 = *(piYCoefsX++);
113 pCoeffTable->DW2.Table0XFilterCoefficient5 = *(piYCoefsX++);
114 pCoeffTable->DW3.Table0XFilterCoefficient6 = 0;
115 pCoeffTable->DW3.Table0XFilterCoefficient7 = 0;
116
117 pCoeffTable->DW0.Table0YFilterCoefficient0 = 0;
118 pCoeffTable->DW0.Table0YFilterCoefficient1 = 0;
119 pCoeffTable->DW1.Table0YFilterCoefficient2 = *(piYCoefsY++);
120 pCoeffTable->DW1.Table0YFilterCoefficient3 = *(piYCoefsY++);
121 pCoeffTable->DW2.Table0YFilterCoefficient4 = *(piYCoefsY++);
122 pCoeffTable->DW2.Table0YFilterCoefficient5 = *(piYCoefsY++);
123 pCoeffTable->DW3.Table0YFilterCoefficient6 = 0;
124 pCoeffTable->DW3.Table0YFilterCoefficient7 = 0;
125 }
126 else
127 {
128 pCoeffTable->DW0.Table0XFilterCoefficient0 = *(piYCoefsX++);
129 pCoeffTable->DW0.Table0XFilterCoefficient1 = *(piYCoefsX++);
130 pCoeffTable->DW1.Table0XFilterCoefficient2 = *(piYCoefsX++);
131 pCoeffTable->DW1.Table0XFilterCoefficient3 = *(piYCoefsX++);
132 pCoeffTable->DW2.Table0XFilterCoefficient4 = *(piYCoefsX++);
133 pCoeffTable->DW2.Table0XFilterCoefficient5 = *(piYCoefsX++);
134 pCoeffTable->DW3.Table0XFilterCoefficient6 = *(piYCoefsX++);
135 pCoeffTable->DW3.Table0XFilterCoefficient7 = *(piYCoefsX++);
136
137 pCoeffTable->DW0.Table0YFilterCoefficient0 = *(piYCoefsY++);
138 pCoeffTable->DW0.Table0YFilterCoefficient1 = *(piYCoefsY++);
139 pCoeffTable->DW1.Table0YFilterCoefficient2 = *(piYCoefsY++);
140 pCoeffTable->DW1.Table0YFilterCoefficient3 = *(piYCoefsY++);
141 pCoeffTable->DW2.Table0YFilterCoefficient4 = *(piYCoefsY++);
142 pCoeffTable->DW2.Table0YFilterCoefficient5 = *(piYCoefsY++);
143 pCoeffTable->DW3.Table0YFilterCoefficient6 = *(piYCoefsY++);
144 pCoeffTable->DW3.Table0YFilterCoefficient7 = *(piYCoefsY++);
145 }
146 }
147 }
148
SetSfcSamplerTable(PMHW_SFC_AVS_LUMA_TABLE pLumaTable,PMHW_SFC_AVS_CHROMA_TABLE pChromaTable,PMHW_AVS_PARAMS pAvsParams,MOS_FORMAT SrcFormat,float fScaleX,float fScaleY,uint32_t dwChromaSiting,bool bUse8x8Filter,float fHPStrength,float fLanczosT)149 MOS_STATUS MhwSfcInterface::SetSfcSamplerTable(
150 PMHW_SFC_AVS_LUMA_TABLE pLumaTable,
151 PMHW_SFC_AVS_CHROMA_TABLE pChromaTable,
152 PMHW_AVS_PARAMS pAvsParams,
153 MOS_FORMAT SrcFormat,
154 float fScaleX,
155 float fScaleY,
156 uint32_t dwChromaSiting,
157 bool bUse8x8Filter,
158 float fHPStrength,
159 float fLanczosT)
160 {
161 int32_t iPhaseOffset;
162
163 int32_t *piYCoefsX, *piYCoefsY;
164 int32_t *piUVCoefsX, *piUVCoefsY;
165 MHW_PLANE Plane;
166
167 MHW_CHK_NULL_RETURN(pLumaTable);
168 MHW_CHK_NULL_RETURN(pChromaTable);
169 MHW_CHK_NULL_RETURN(pAvsParams);
170
171 piYCoefsX = pAvsParams->piYCoefsX;
172 piYCoefsY = pAvsParams->piYCoefsY;
173 piUVCoefsX = pAvsParams->piUVCoefsX;
174 piUVCoefsY = pAvsParams->piUVCoefsY;
175
176 // Skip calculation if no changes to AVS parameters
177 if (SrcFormat == pAvsParams->Format &&
178 fScaleX == pAvsParams->fScaleX &&
179 fScaleY == pAvsParams->fScaleY)
180 {
181 return MOS_STATUS_SUCCESS;
182 }
183
184 // AVS Coefficients don't change for Scaling Factors > 1.0x
185 // Hence recalculation is avoided
186 if (fScaleX > 1.0F && pAvsParams->fScaleX > 1.0F)
187 {
188 pAvsParams->fScaleX = fScaleX;
189 }
190
191 // AVS Coefficients don't change for Scaling Factors > 1.0x
192 // Hence recalculation is avoided
193 if (fScaleY > 1.0F && pAvsParams->fScaleY > 1.0F)
194 {
195 pAvsParams->fScaleY = fScaleY;
196 }
197
198 // Recalculate Horizontal scaling table
199 if (SrcFormat != pAvsParams->Format || fScaleX != pAvsParams->fScaleX)
200 {
201 MOS_ZeroMemory(
202 piYCoefsX,
203 8 * 32 * sizeof(int32_t));
204
205 MOS_ZeroMemory(
206 piUVCoefsX,
207 4 * 32 * sizeof(int32_t));
208
209 // 4-tap filtering for RGB format G-channel.
210 Plane = IS_RGB32_FORMAT(SrcFormat) ? MHW_U_PLANE : MHW_Y_PLANE;
211
212 pAvsParams->fScaleX = fScaleX;
213
214 // Nearest, overwrite the coefficients.
215 if (m_scalingMode == MHW_SCALING_NEAREST)
216 {
217 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
218 piYCoefsX,
219 Plane,
220 true));
221
222 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
223 piUVCoefsX,
224 MHW_U_PLANE,
225 true));
226 }
227 else
228 {
229 // By default AVS coefficients
230 // For 1x scaling in horizontal direction and not force polyphase coefs, use special coefficients for filtering
231 if (fScaleX == 1.0F && !pAvsParams->bForcePolyPhaseCoefs)
232 {
233 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
234 piYCoefsX,
235 Plane,
236 true));
237
238 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
239 piUVCoefsX,
240 MHW_U_PLANE,
241 true));
242 }
243 else
244 {
245 // Clamp the Scaling Factor if > 1.0x
246 fScaleX = MOS_MIN(1.0F, fScaleX);
247
248 MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesY(
249 piYCoefsX,
250 fScaleX,
251 Plane,
252 SrcFormat,
253 fHPStrength,
254 bUse8x8Filter,
255 NUM_HW_POLYPHASE_TABLES,
256 fLanczosT));
257 }
258
259 // If Chroma Siting info is present
260 if (dwChromaSiting & MHW_CHROMA_SITING_HORZ_LEFT)
261 {
262 // No Chroma Siting
263 MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesUV(
264 piUVCoefsX,
265 2.0F,
266 fScaleX));
267 }
268 else
269 {
270 // Chroma siting offset needs to be added
271 if (dwChromaSiting & MHW_CHROMA_SITING_HORZ_CENTER)
272 {
273 iPhaseOffset = MOS_UF_ROUND(0.5F * 16.0F); // U0.4
274 }
275 else //if (ChromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT)
276 {
277 iPhaseOffset = MOS_UF_ROUND(1.0F * 16.0F); // U0.4
278 }
279
280 MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesUVOffset(
281 piUVCoefsX,
282 3.0F,
283 fScaleX,
284 iPhaseOffset));
285 }
286 }
287 }
288
289 // Recalculate Vertical scaling table
290 if (SrcFormat != pAvsParams->Format || fScaleY != pAvsParams->fScaleY)
291 {
292 MOS_ZeroMemory(piYCoefsY, 8 * 32 * sizeof(int32_t));
293
294 MOS_ZeroMemory(piUVCoefsY, 4 * 32 * sizeof(int32_t));
295
296 // 4-tap filtering for RGB format G-channel.
297 Plane = IS_RGB32_FORMAT(SrcFormat) ? MHW_U_PLANE : MHW_Y_PLANE;
298
299 pAvsParams->fScaleY = fScaleY;
300
301 // Nearest, overwrite the coefficients.
302 if (m_scalingMode == MHW_SCALING_NEAREST)
303 {
304 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
305 piYCoefsY,
306 Plane,
307 true));
308
309 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
310 piUVCoefsY,
311 MHW_U_PLANE,
312 true));
313 }
314 else
315 {
316 // For 1x scaling in vertical direction and not force polyphase coefs, use special coefficients for filtering
317 if (fScaleY == 1.0F && !pAvsParams->bForcePolyPhaseCoefs)
318 {
319 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
320 piYCoefsY,
321 Plane,
322 true));
323
324 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
325 piUVCoefsY,
326 MHW_U_PLANE,
327 true));
328 }
329 else
330 {
331 // Clamp the Scaling Factor if > 1.0x
332 fScaleY = MOS_MIN(1.0F, fScaleY);
333
334 MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesY(
335 piYCoefsY,
336 fScaleY,
337 Plane,
338 SrcFormat,
339 fHPStrength,
340 bUse8x8Filter,
341 NUM_HW_POLYPHASE_TABLES,
342 fLanczosT));
343 }
344
345 // If Chroma Siting info is present
346 if (dwChromaSiting & MHW_CHROMA_SITING_VERT_TOP)
347 {
348 // No Chroma Siting
349 MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesUV(
350 piUVCoefsY,
351 2.0F,
352 fScaleY));
353 }
354 else
355 {
356 // Chroma siting offset needs to be added
357 if (dwChromaSiting & MHW_CHROMA_SITING_VERT_CENTER)
358 {
359 iPhaseOffset = MOS_UF_ROUND(0.5F * 16.0F); // U0.4
360 }
361 else //if (ChromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM)
362 {
363 iPhaseOffset = MOS_UF_ROUND(1.0F * 16.0F); // U0.4
364 }
365
366 MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesUVOffset(
367 piUVCoefsY,
368 3.0F,
369 fScaleY,
370 iPhaseOffset));
371 }
372 }
373 }
374
375 // Save format used to calculate AVS parameters
376 pAvsParams->Format = SrcFormat;
377
378 SetSfcAVSLumaTable(
379 SrcFormat,
380 pLumaTable->LumaTable,
381 piYCoefsX,
382 piYCoefsY,
383 bUse8x8Filter);
384
385 SetSfcAVSChromaTable(
386 pChromaTable->ChromaTable,
387 piUVCoefsX,
388 piUVCoefsY);
389
390 return MOS_STATUS_SUCCESS;
391 }
392
GetInputFrameWidthHeightAlignUnit(uint32_t & widthAlignUnit,uint32_t & heightAlignUnit,bool bVdbox,CODECHAL_STANDARD codecStandard,CodecDecodeJpegChromaType jpegChromaType)393 MOS_STATUS MhwSfcInterface::GetInputFrameWidthHeightAlignUnit(uint32_t &widthAlignUnit, uint32_t &heightAlignUnit,
394 bool bVdbox, CODECHAL_STANDARD codecStandard, CodecDecodeJpegChromaType jpegChromaType)
395 {
396 if (bVdbox)
397 {
398 if (CODECHAL_JPEG == codecStandard &&( jpegYUV400 == jpegChromaType ||
399 jpegYUV444 == jpegChromaType || jpegYUV422H2Y == jpegChromaType) ||
400 jpegBGR == jpegChromaType || jpegRGB == jpegChromaType)
401 {
402 widthAlignUnit = 8;
403 heightAlignUnit = 8;
404 return MOS_STATUS_SUCCESS;
405 }
406 else if (CODECHAL_HEVC == codecStandard || CODECHAL_VP9 == codecStandard)
407 {
408 widthAlignUnit = 8;
409 heightAlignUnit = 8;
410 return MOS_STATUS_SUCCESS;
411 }
412 else if (CODECHAL_AV1 == codecStandard)
413 {
414 widthAlignUnit = 1;
415 heightAlignUnit = 1;
416 return MOS_STATUS_SUCCESS;
417 }
418 else
419 {
420 widthAlignUnit = 16;
421 heightAlignUnit = 16;
422 return MOS_STATUS_SUCCESS;
423 }
424 }
425 else
426 {
427 widthAlignUnit = m_veWidthAlignment;
428 heightAlignUnit = m_veHeightAlignment;
429 return MOS_STATUS_SUCCESS;
430 }
431 }
432