1 /*
2 * Copyright (c) 2020-2021, 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 meida_sfc_render.cpp
24 //! \brief Common interface for sfc
25 //! \details Common interface for sfc
26 //!
27 #include "media_sfc_interface.h"
28 #include "media_sfc_render.h"
29 #include "vp_feature_manager.h"
30 #include "mhw_vebox.h"
31 #include "vp_common.h"
32 #include "vp_platform_interface.h"
33 #include "vp_pipeline.h"
34 #include "media_vdbox_sfc_render.h"
35 #include "media_interfaces_vphal.h"
36 #include "mos_os.h"
37 #include "renderhal.h"
38 #include "media_mem_compression.h"
39 #include "media_interfaces_mhw_next.h"
40 #include "renderhal_platform_interface.h"
41
42 using namespace vp;
43
44 typedef MediaFactory<uint32_t, VphalDevice> VphalFactory;
45
MediaSfcRender(PMOS_INTERFACE osInterface,MEDIA_SFC_INTERFACE_MODE mode,MediaMemComp * mmc)46 MediaSfcRender::MediaSfcRender(PMOS_INTERFACE osInterface, MEDIA_SFC_INTERFACE_MODE mode, MediaMemComp *mmc) :
47 m_osInterface(osInterface), m_mode(mode), m_mmc(mmc)
48 {
49 }
50
~MediaSfcRender()51 MediaSfcRender::~MediaSfcRender()
52 {
53 Destroy();
54 }
55
Destroy()56 void MediaSfcRender::Destroy()
57 {
58 MOS_STATUS status = MOS_STATUS_SUCCESS;
59 MOS_Delete(m_vdboxSfcRender);
60 MOS_Delete(m_vpPipeline);
61 MOS_Delete(m_vpPlatformInterface);
62 MOS_Delete(m_vpMhwinterface);
63
64 if (m_renderHal)
65 {
66 if (m_renderHal->pfnDestroy)
67 {
68 status = m_renderHal->pfnDestroy(m_renderHal);
69 if (MOS_STATUS_SUCCESS != status)
70 {
71 VP_PUBLIC_ASSERTMESSAGE("Failed to destroy RenderHal, eStatus:%d.\n", status);
72 }
73 }
74 MOS_FreeMemory(m_renderHal);
75 }
76 if (m_cpInterface)
77 {
78 if (m_osInterface)
79 {
80 m_osInterface->pfnDeleteMhwCpInterface(m_cpInterface);
81 m_cpInterface = nullptr;
82 }
83 else
84 {
85 VP_PUBLIC_ASSERTMESSAGE("Failed to destroy cpInterface.");
86 }
87 }
88
89 if (m_veboxItf)
90 {
91 status = m_veboxItf->DestroyHeap();
92 if (MOS_FAILED(status))
93 {
94 VP_PUBLIC_ASSERTMESSAGE("Failed to destroy veboxItf heap, eStatus:%d.\n", status);
95 }
96 }
97
98 MOS_Delete(m_statusTable);
99 }
100
Render(VEBOX_SFC_PARAMS & sfcParam)101 MOS_STATUS MediaSfcRender::Render(VEBOX_SFC_PARAMS &sfcParam)
102 {
103 if (!m_initialized || !m_mode.veboxSfcEnabled)
104 {
105 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_UNINITIALIZED);
106 }
107
108 VP_PUBLIC_CHK_STATUS_RETURN(IsParameterSupported(sfcParam));
109
110 VP_PARAMS params = {};
111 params.type = PIPELINE_PARAM_TYPE_MEDIA_SFC_INTERFACE;
112 params.sfcParams = &sfcParam;
113 VP_PUBLIC_CHK_STATUS_RETURN(m_vpPipeline->Prepare(¶ms));
114 VP_PUBLIC_CHK_STATUS_RETURN(m_vpPipeline->Execute());
115 return MOS_STATUS_SUCCESS;
116 }
117
Render(MOS_COMMAND_BUFFER * cmdBuffer,VDBOX_SFC_PARAMS & param)118 MOS_STATUS MediaSfcRender::Render(MOS_COMMAND_BUFFER *cmdBuffer, VDBOX_SFC_PARAMS ¶m)
119 {
120 if (!m_initialized || !m_mode.vdboxSfcEnabled)
121 {
122 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_UNINITIALIZED);
123 }
124
125 VP_PUBLIC_CHK_NULL_RETURN(m_vdboxSfcRender);
126 VP_PUBLIC_CHK_NULL_RETURN(cmdBuffer);
127 VP_PUBLIC_CHK_STATUS_RETURN(IsParameterSupported(param));
128
129 VP_PUBLIC_CHK_STATUS_RETURN(m_vdboxSfcRender->AddSfcStates(cmdBuffer, param));
130 return MOS_STATUS_SUCCESS;
131 }
132
133 //!
134 //! \brief MediaSfcInterface initialize
135 //! \details Initialize the BltState, create BLT context.
136 //! \return MOS_STATUS
137 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
138 //!
Initialize()139 MOS_STATUS MediaSfcRender::Initialize()
140 {
141 if (m_initialized)
142 {
143 return MOS_STATUS_SUCCESS;
144 }
145
146 VphalDevice *vphalDevice = nullptr;
147 PLATFORM platform = {};
148 MOS_STATUS status = MOS_STATUS_SUCCESS;
149 MEDIA_FEATURE_TABLE *skuTable = nullptr;
150 MEDIA_WA_TABLE *waTable = nullptr;
151
152 VP_PUBLIC_CHK_NULL_RETURN(m_osInterface);
153 VP_PUBLIC_CHK_NULL_RETURN(m_osInterface->pfnGetPlatform);
154 VP_PUBLIC_CHK_NULL_RETURN(m_osInterface->pfnGetSkuTable);
155 VP_PUBLIC_CHK_NULL_RETURN(m_osInterface->pfnGetWaTable);
156
157 skuTable = m_osInterface->pfnGetSkuTable(m_osInterface);
158 waTable = m_osInterface->pfnGetWaTable(m_osInterface);
159
160 VP_PUBLIC_CHK_NULL_RETURN(skuTable);
161 VP_PUBLIC_CHK_NULL_RETURN(waTable);
162
163 // Check whether SFC supported.
164 if (!MEDIA_IS_SKU(skuTable, FtrSFCPipe))
165 {
166 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
167 }
168
169 // Clean the garbage data if any.
170 Destroy();
171
172 m_statusTable = MOS_New(VPHAL_STATUS_TABLE);
173 VP_PUBLIC_CHK_NULL_RETURN(m_statusTable);
174
175 // Create platform interface and vp pipeline by vphalDevice.
176 m_osInterface->pfnGetPlatform(m_osInterface, &platform);
177 vphalDevice = VphalFactory::Create(platform.eProductFamily);
178 VP_PUBLIC_CHK_NULL_RETURN(vphalDevice);
179
180 if (m_mode.veboxSfcEnabled)
181 {
182 if (vphalDevice->Initialize(m_osInterface, false, &status) != MOS_STATUS_SUCCESS)
183 {
184 vphalDevice->Destroy();
185 MOS_Delete(vphalDevice);
186 return status;
187 }
188 if (nullptr == vphalDevice->m_vpPipeline || nullptr == vphalDevice->m_vpPlatformInterface)
189 {
190 vphalDevice->Destroy();
191 MOS_Delete(vphalDevice);
192 return status;
193 }
194 }
195 else
196 {
197 if (vphalDevice->CreateVpPlatformInterface(m_osInterface, &status) != MOS_STATUS_SUCCESS)
198 {
199 vphalDevice->Destroy();
200 MOS_Delete(vphalDevice);
201 return status;
202 }
203 if (nullptr == vphalDevice->m_vpPlatformInterface)
204 {
205 vphalDevice->Destroy();
206 MOS_Delete(vphalDevice);
207 return status;
208 }
209 }
210
211 m_vpPipeline = vphalDevice->m_vpPipeline;
212 m_vpPlatformInterface = vphalDevice->m_vpPlatformInterface;
213 MOS_Delete(vphalDevice);
214
215 // Create mhw interfaces.
216 MhwInterfacesNext::CreateParams paramsNext = {};
217 paramsNext.Flags.m_sfc = MEDIA_IS_SKU(skuTable, FtrSFCPipe);
218 paramsNext.Flags.m_vebox = MEDIA_IS_SKU(skuTable, FtrVERing);
219 MhwInterfacesNext *mhwInterfacesNext = MhwInterfacesNext::CreateFactory(paramsNext, m_osInterface);
220
221 VP_PUBLIC_CHK_NULL_RETURN(mhwInterfacesNext);
222 m_sfcItf = mhwInterfacesNext->m_sfcItf;
223 m_veboxItf = mhwInterfacesNext->m_veboxItf;
224
225 // mi interface and cp interface will always be created during MhwInterfaces::CreateFactory.
226 // Delete them here since they will also be created by RenderHal_InitInterface.
227 m_osInterface->pfnDeleteMhwCpInterface(mhwInterfacesNext->m_cpInterface);
228 MOS_Delete(mhwInterfacesNext);
229
230 VP_PUBLIC_CHK_NULL_RETURN(m_veboxItf);
231 const MHW_VEBOX_HEAP *veboxHeap = nullptr;
232 m_veboxItf->GetVeboxHeapInfo(&veboxHeap);
233 uint32_t uiNumInstances = m_veboxItf->GetVeboxNumInstances();
234
235 if (uiNumInstances > 0 &&
236 veboxHeap == nullptr)
237 {
238 // Allocate VEBOX Heap
239 VP_PUBLIC_CHK_STATUS_RETURN(m_veboxItf->CreateHeap());
240 }
241
242 // Initialize render hal.
243 m_renderHal = (PRENDERHAL_INTERFACE)MOS_AllocAndZeroMemory(sizeof(RENDERHAL_INTERFACE));
244 VP_PUBLIC_CHK_NULL_RETURN(m_renderHal);
245 VP_PUBLIC_CHK_STATUS_RETURN(RenderHal_InitInterface(
246 m_renderHal,
247 &m_cpInterface,
248 m_osInterface));
249 RENDERHAL_SETTINGS RenderHalSettings = {};
250 RenderHalSettings.iMediaStates = 32; // Init MEdia state values
251 VP_PUBLIC_CHK_STATUS_RETURN(m_renderHal->pfnInitialize(m_renderHal, &RenderHalSettings));
252 m_miItf = m_renderHal->pRenderHalPltInterface->GetMhwMiItf();
253
254 // Initialize vpPipeline.
255 m_vpMhwinterface = MOS_New(VP_MHWINTERFACE);
256 VP_PUBLIC_CHK_NULL_RETURN(m_vpMhwinterface);
257 MOS_ZeroMemory(m_vpMhwinterface, sizeof(VP_MHWINTERFACE));
258 m_osInterface->pfnGetPlatform(m_osInterface, &m_vpMhwinterface->m_platform);
259 m_vpMhwinterface->m_waTable = waTable;
260 m_vpMhwinterface->m_skuTable = skuTable;
261 m_vpMhwinterface->m_osInterface = m_osInterface;
262 m_vpMhwinterface->m_renderHal = m_renderHal;
263 m_vpMhwinterface->m_cpInterface = m_cpInterface;
264 m_vpMhwinterface->m_statusTable = m_statusTable;
265 m_vpMhwinterface->m_vpPlatformInterface = m_vpPlatformInterface;
266 m_vpMhwinterface->m_settings = nullptr;
267 m_vpMhwinterface->m_reporting = nullptr;
268 m_vpPlatformInterface->SetMhwSfcItf(m_sfcItf);
269 m_vpPlatformInterface->SetMhwVeboxItf(m_veboxItf);
270 m_vpPlatformInterface->SetMhwMiItf(m_miItf);
271 m_vpMhwinterface->m_vpPlatformInterface = m_vpPlatformInterface;
272 m_vpMhwinterface->m_bIsMediaSfcInterfaceInUse = true;
273
274 if (m_mode.veboxSfcEnabled)
275 {
276 VP_PUBLIC_CHK_STATUS_RETURN(m_vpPipeline->Init(m_vpMhwinterface));
277 }
278 else
279 {
280 MOS_Delete(m_vpPipeline);
281 }
282
283 if (m_mode.vdboxSfcEnabled)
284 {
285 m_vdboxSfcRender = MOS_New(MediaVdboxSfcRender);
286 VP_PUBLIC_CHK_NULL_RETURN(m_vdboxSfcRender);
287 VP_PUBLIC_CHK_STATUS_RETURN(m_vdboxSfcRender->Initialize(*m_vpMhwinterface, m_mmc));
288 }
289
290 m_initialized = true;
291
292 return MOS_STATUS_SUCCESS;
293 }
294
InitScalingParams(FeatureParamScaling & scalingParams,VDBOX_SFC_PARAMS & sfcParam)295 MOS_STATUS MediaSfcRender::InitScalingParams(FeatureParamScaling &scalingParams, VDBOX_SFC_PARAMS &sfcParam)
296 {
297 if (!m_mode.vdboxSfcEnabled)
298 {
299 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_UNINITIALIZED);
300 }
301
302 VP_PUBLIC_CHK_NULL_RETURN(sfcParam.output.surface);
303
304 RECT rcSrcInput = {0, 0, (int32_t)sfcParam.input.width, (int32_t)sfcParam.input.height };
305 RECT rcEffectiveSrcInput = {0, 0, (int32_t)sfcParam.input.effectiveWidth, (int32_t)sfcParam.input.effectiveHeight };
306 RECT rcOutput = {0, 0, (int32_t)sfcParam.output.surface->dwWidth, (int32_t)sfcParam.output.surface->dwHeight };
307
308 scalingParams.type = FeatureTypeScalingOnSfc;
309 scalingParams.formatInput = sfcParam.input.format;
310 scalingParams.formatOutput = sfcParam.output.surface->Format;
311 scalingParams.scalingMode = VPHAL_SCALING_AVS;
312 scalingParams.scalingPreference = VPHAL_SCALING_PREFER_SFC; //!< DDI indicate Scaling preference
313 scalingParams.bDirectionalScalar = false; //!< Vebox Directional Scalar
314 scalingParams.input.rcSrc = rcEffectiveSrcInput; //!< rcEffectiveSrcInput exclude right/bottom padding area of SFC input.
315 scalingParams.input.rcDst = sfcParam.output.rcDst;
316 scalingParams.input.rcMaxSrc = rcSrcInput;
317 scalingParams.input.dwWidth = sfcParam.input.width; //!< No input crop support for VD mode. Input Frame Height/Width must have same width/height of decoded frames.
318 scalingParams.input.dwHeight = sfcParam.input.height;
319 scalingParams.output.rcSrc = rcOutput;
320 scalingParams.output.rcDst = rcOutput;
321 scalingParams.output.rcMaxSrc = rcOutput;
322 scalingParams.output.dwWidth = sfcParam.output.surface->dwWidth;
323 scalingParams.output.dwHeight = sfcParam.output.surface->dwHeight;
324 scalingParams.pColorFillParams = nullptr;
325 scalingParams.pCompAlpha = nullptr;
326 scalingParams.csc.colorSpaceOutput = sfcParam.output.colorSpace;
327 return MOS_STATUS_SUCCESS;
328 }
329
InitScalingParams(FeatureParamScaling & scalingParams,VEBOX_SFC_PARAMS & sfcParam)330 MOS_STATUS MediaSfcRender::InitScalingParams(FeatureParamScaling &scalingParams, VEBOX_SFC_PARAMS &sfcParam)
331 {
332 if (!m_mode.veboxSfcEnabled)
333 {
334 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_UNINITIALIZED);
335 }
336
337 VP_PUBLIC_CHK_NULL_RETURN(sfcParam.input.surface);
338 VP_PUBLIC_CHK_NULL_RETURN(sfcParam.output.surface);
339
340 scalingParams.scalingMode = VPHAL_SCALING_AVS;
341 scalingParams.scalingPreference = VPHAL_SCALING_PREFER_SFC;
342 scalingParams.bDirectionalScalar = false;
343 scalingParams.formatInput = sfcParam.input.surface->Format;
344 scalingParams.input.rcSrc = sfcParam.input.rcSrc;
345 scalingParams.input.rcMaxSrc = sfcParam.input.rcSrc;
346 scalingParams.input.dwWidth = sfcParam.input.surface->dwWidth;
347 scalingParams.input.dwHeight = sfcParam.input.surface->dwHeight;
348 scalingParams.formatOutput = sfcParam.output.surface->Format;
349 scalingParams.csc.colorSpaceOutput = sfcParam.output.colorSpace;
350 scalingParams.pColorFillParams = nullptr;
351 scalingParams.pCompAlpha = nullptr;
352
353 RECT recOutput = {0, 0, (int32_t)sfcParam.output.surface->dwWidth, (int32_t)sfcParam.output.surface->dwHeight};
354
355 if (sfcParam.input.rotation == (MEDIA_ROTATION)VPHAL_ROTATION_IDENTITY ||
356 sfcParam.input.rotation == (MEDIA_ROTATION)VPHAL_ROTATION_180 ||
357 sfcParam.input.rotation == (MEDIA_ROTATION)VPHAL_MIRROR_HORIZONTAL ||
358 sfcParam.input.rotation == (MEDIA_ROTATION)VPHAL_MIRROR_VERTICAL)
359 {
360 scalingParams.output.dwWidth = sfcParam.output.surface->dwWidth;
361 scalingParams.output.dwHeight = sfcParam.output.surface->dwHeight;
362 scalingParams.input.rcDst = sfcParam.output.rcDst;
363 scalingParams.output.rcSrc = recOutput;
364 scalingParams.output.rcDst = recOutput;
365 scalingParams.output.rcMaxSrc = recOutput;
366 }
367 else
368 {
369 scalingParams.output.dwWidth = sfcParam.output.surface->dwHeight;
370 scalingParams.output.dwHeight = sfcParam.output.surface->dwWidth;
371 RECT_ROTATE(scalingParams.input.rcDst, sfcParam.output.rcDst);
372 RECT_ROTATE(scalingParams.output.rcSrc, recOutput);
373 RECT_ROTATE(scalingParams.output.rcDst, recOutput);
374 RECT_ROTATE(scalingParams.output.rcMaxSrc, recOutput);
375 }
376 return MOS_STATUS_SUCCESS;
377 }
378
IsParameterSupported(VDBOX_SFC_PARAMS & sfcParam)379 MOS_STATUS MediaSfcRender::IsParameterSupported(
380 VDBOX_SFC_PARAMS &sfcParam)
381 {
382 if (!m_mode.vdboxSfcEnabled)
383 {
384 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_UNINITIALIZED);
385 }
386
387 VP_PUBLIC_CHK_NULL_RETURN(sfcParam.output.surface);
388 VP_PUBLIC_CHK_NULL_RETURN(m_vdboxSfcRender);
389 VP_PUBLIC_CHK_NULL_RETURN(m_sfcItf);
390
391 VpScalingFilter scalingFilter(m_vpMhwinterface);
392 FeatureParamScaling scalingParams = {};
393
394 VP_PUBLIC_CHK_STATUS_RETURN(InitScalingParams(scalingParams, sfcParam));
395
396 VP_EXECUTE_CAPS vpExecuteCaps = {};
397 vpExecuteCaps.bSFC = 1;
398 vpExecuteCaps.bSfcCsc = 1;
399 vpExecuteCaps.bSfcScaling = 1;
400 vpExecuteCaps.bSfcRotMir = 1;
401
402 VP_PUBLIC_CHK_STATUS_RETURN(scalingFilter.Init(sfcParam.videoParams.codecStandard, sfcParam.videoParams.jpeg.jpegChromaType));
403 VP_PUBLIC_CHK_STATUS_RETURN(scalingFilter.SetExecuteEngineCaps(scalingParams, vpExecuteCaps));
404 VP_PUBLIC_CHK_STATUS_RETURN(scalingFilter.CalculateEngineParams());
405
406 SFC_SCALING_PARAMS *params = scalingFilter.GetSfcParams();
407 VP_PUBLIC_CHK_NULL_RETURN(params);
408
409 // Check original input size (for JPEG)
410 uint32_t minWidth = 0, minHeight = 0, maxWidth = 0, maxHeight = 0;
411 VP_PUBLIC_CHK_STATUS_RETURN(m_sfcItf->GetMinWidthHeightInfo(minWidth, minHeight));
412 VP_PUBLIC_CHK_STATUS_RETURN(m_sfcItf->GetMaxWidthHeightInfo(maxWidth, maxHeight));
413 if (!MOS_WITHIN_RANGE(sfcParam.input.width, minWidth, maxWidth) ||
414 !MOS_WITHIN_RANGE(sfcParam.input.height, minHeight, maxHeight))
415 {
416 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
417 }
418
419 // Check input size
420 if (!MOS_WITHIN_RANGE(params->dwInputFrameWidth, minWidth, maxWidth) ||
421 !MOS_WITHIN_RANGE(params->dwInputFrameHeight, minHeight, maxHeight))
422 {
423 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
424 }
425
426 // Check output size
427 if (!MOS_WITHIN_RANGE(params->dwOutputFrameWidth, minWidth, maxWidth) ||
428 !MOS_WITHIN_RANGE(params->dwOutputFrameHeight, minHeight, maxHeight))
429 {
430 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
431 }
432
433 // Check output region rectangles
434 if ((scalingParams.input.rcDst.bottom - scalingParams.input.rcDst.top > (int32_t)scalingParams.output.dwHeight) ||
435 (scalingParams.input.rcDst.right - scalingParams.input.rcDst.left > (int32_t)scalingParams.output.dwWidth))
436 {
437 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
438 }
439
440 float minScalingRatio = 0, maxScalingRatio = 0;
441 VP_PUBLIC_CHK_STATUS_RETURN(m_sfcItf->GetScalingRatioLimit(minScalingRatio, maxScalingRatio));
442
443 // Check scaling ratio
444 if (!MOS_WITHIN_RANGE(params->fAVSXScalingRatio, minScalingRatio, maxScalingRatio) ||
445 !MOS_WITHIN_RANGE(params->fAVSYScalingRatio, minScalingRatio, maxScalingRatio))
446 {
447 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
448 }
449
450 // Check input and output format (limited only to current decode processing usage)
451 if (!m_vdboxSfcRender->IsVdboxSfcFormatSupported(sfcParam.videoParams.codecStandard, sfcParam.input.format, sfcParam.output.surface->Format, sfcParam.output.surface->TileType))
452 {
453 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
454 }
455
456 return MOS_STATUS_SUCCESS;
457 }
458
IsParameterSupported(VEBOX_SFC_PARAMS & sfcParam)459 MOS_STATUS MediaSfcRender::IsParameterSupported(
460 VEBOX_SFC_PARAMS &sfcParam)
461 {
462 if (!m_mode.veboxSfcEnabled)
463 {
464 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_UNINITIALIZED);
465 }
466
467 VP_PUBLIC_CHK_NULL_RETURN(sfcParam.input.surface);
468 VP_PUBLIC_CHK_NULL_RETURN(sfcParam.output.surface);
469 VP_PUBLIC_CHK_NULL_RETURN(m_sfcItf);
470
471 VpScalingFilter scalingFilter(m_vpMhwinterface);
472 FeatureParamScaling scalingParams = {};
473
474 VP_PUBLIC_CHK_STATUS_RETURN(InitScalingParams(scalingParams, sfcParam));
475
476 VP_EXECUTE_CAPS vpExecuteCaps = {};
477 vpExecuteCaps.bSFC = 1;
478 vpExecuteCaps.bSfcCsc = 1;
479 vpExecuteCaps.bSfcScaling = 1;
480 vpExecuteCaps.bSfcRotMir = 1;
481
482 VP_PUBLIC_CHK_STATUS_RETURN(scalingFilter.Init());
483 VP_PUBLIC_CHK_STATUS_RETURN(scalingFilter.SetExecuteEngineCaps(scalingParams, vpExecuteCaps));
484 VP_PUBLIC_CHK_STATUS_RETURN(scalingFilter.CalculateEngineParams());
485
486 SFC_SCALING_PARAMS *params = scalingFilter.GetSfcParams();
487 VP_PUBLIC_CHK_NULL_RETURN(params);
488
489 // Check original input size
490 uint32_t minInputWidth = 0, minInputHeight = 0, minOutputWidth = 0, minOutputHeight = 0, maxWidth = 0, maxHeight = 0;
491 VP_PUBLIC_CHK_STATUS_RETURN(m_sfcItf->GetInputMinWidthHeightInfo(minInputWidth, minInputHeight));
492 VP_PUBLIC_CHK_STATUS_RETURN(m_sfcItf->GetOutputMinWidthHeightInfo(minOutputWidth, minOutputHeight));
493 VP_PUBLIC_CHK_STATUS_RETURN(m_sfcItf->GetMaxWidthHeightInfo(maxWidth, maxHeight));
494
495 // Check input size
496 if (!MOS_WITHIN_RANGE(params->dwInputFrameWidth, minInputWidth, maxWidth) ||
497 !MOS_WITHIN_RANGE(params->dwInputFrameHeight, minInputHeight, maxHeight))
498 {
499 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
500 }
501
502 // Check output size
503 if (!MOS_WITHIN_RANGE(params->dwOutputFrameWidth, minOutputWidth, maxWidth) ||
504 !MOS_WITHIN_RANGE(params->dwOutputFrameHeight, minOutputHeight, maxHeight))
505 {
506 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
507 }
508
509 // Check input region rectangles
510 if ((scalingParams.input.rcSrc.bottom - scalingParams.input.rcSrc.top > (int32_t)scalingParams.input.dwHeight) ||
511 (scalingParams.input.rcSrc.right - scalingParams.input.rcSrc.left > (int32_t)scalingParams.input.dwWidth))
512 {
513 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
514 }
515
516 // Check output region rectangles
517 if ((scalingParams.input.rcDst.bottom - scalingParams.input.rcDst.top > (int32_t)scalingParams.output.dwHeight) ||
518 (scalingParams.input.rcDst.right - scalingParams.input.rcDst.left > (int32_t)scalingParams.output.dwWidth))
519 {
520 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
521 }
522
523 float minScalingRatio = 0, maxScalingRatio = 0;
524 VP_PUBLIC_CHK_STATUS_RETURN(m_sfcItf->GetScalingRatioLimit(minScalingRatio, maxScalingRatio));
525 // Check scaling ratio
526 if (!MOS_WITHIN_RANGE(params->fAVSXScalingRatio, minScalingRatio, maxScalingRatio) ||
527 !MOS_WITHIN_RANGE(params->fAVSYScalingRatio, minScalingRatio, maxScalingRatio))
528 {
529 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
530 }
531
532 // Check input and output format
533 if (!m_vpPipeline->IsVeboxSfcFormatSupported(sfcParam.input.surface->Format, sfcParam.output.surface->Format))
534 {
535 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
536 }
537
538 return MOS_STATUS_SUCCESS;
539 }
540