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_vdbox_sfc_render.cpp
24 //! \brief Common interface for sfc
25 //! \details Common interface for sfc
26 //!
27 #include "vp_feature_manager.h"
28 #include "media_sfc_interface.h"
29 #include "media_vdbox_sfc_render.h"
30 #include "mos_os.h"
31 #include "vp_render_ief.h"
32 #include "vp_mem_compression.h"
33
34 using namespace vp;
35
MediaVdboxSfcRender()36 MediaVdboxSfcRender::MediaVdboxSfcRender()
37 {
38 }
39
~MediaVdboxSfcRender()40 MediaVdboxSfcRender::~MediaVdboxSfcRender()
41 {
42 Destroy();
43 }
44
Destroy()45 void MediaVdboxSfcRender::Destroy()
46 {
47 MOS_Delete(m_sfcRender);
48 MOS_Delete(m_cscFilter);
49 MOS_Delete(m_scalingFilter);
50 MOS_Delete(m_rotMirFilter);
51 MOS_Delete(m_allocator);
52 if (m_isMmcAllocated)
53 {
54 MOS_Delete(m_mmc);
55 }
56 }
57
58 //!
59 //! \brief MediaSfcInterface initialize
60 //! \details Initialize the BltState, create BLT context.
61 //! \return MOS_STATUS
62 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
63 //!
Initialize(VP_MHWINTERFACE & vpMhwinterface,MediaMemComp * mmc)64 MOS_STATUS MediaVdboxSfcRender::Initialize(VP_MHWINTERFACE &vpMhwinterface, MediaMemComp *mmc)
65 {
66 VP_PUBLIC_CHK_NULL_RETURN(vpMhwinterface.m_vpPlatformInterface);
67 VP_PUBLIC_CHK_NULL_RETURN(vpMhwinterface.m_osInterface);
68
69 m_vpMhwInterface = vpMhwinterface;
70 m_osInterface = m_vpMhwInterface.m_osInterface;
71
72 if (mmc)
73 {
74 m_mmc = mmc;
75 m_isMmcAllocated = false;
76 }
77 else
78 {
79 m_mmc = MOS_New(VPMediaMemComp, m_osInterface, m_vpMhwInterface);
80 VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
81 m_isMmcAllocated = true;
82 }
83
84 m_allocator = MOS_New(VpAllocator, m_osInterface, m_mmc);
85 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
86 m_cscFilter = MOS_New(VpCscFilter, &m_vpMhwInterface);
87 VP_PUBLIC_CHK_NULL_RETURN(m_cscFilter);
88 m_scalingFilter = MOS_New(VpScalingFilter, &m_vpMhwInterface);
89 VP_PUBLIC_CHK_NULL_RETURN(m_scalingFilter);
90 m_rotMirFilter = MOS_New(VpRotMirFilter, &m_vpMhwInterface);
91 VP_PUBLIC_CHK_NULL_RETURN(m_rotMirFilter);
92 VP_PUBLIC_CHK_STATUS_RETURN(m_vpMhwInterface.m_vpPlatformInterface->CreateSfcRender(m_sfcRender, m_vpMhwInterface, m_allocator));
93 VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender);
94 return MOS_STATUS_SUCCESS;
95 }
96
SetCSCParams(VDBOX_SFC_PARAMS & sfcParam,VP_EXECUTE_CAPS & vpExecuteCaps)97 MOS_STATUS MediaVdboxSfcRender::SetCSCParams(VDBOX_SFC_PARAMS &sfcParam, VP_EXECUTE_CAPS &vpExecuteCaps)
98 {
99 VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender);
100 VP_PUBLIC_CHK_NULL_RETURN(m_cscFilter);
101 FeatureParamCsc cscParams = {};
102 cscParams.type = FeatureTypeCscOnSfc;
103 cscParams.formatInput = sfcParam.input.format;
104 cscParams.formatOutput = sfcParam.output.surface->Format;
105 cscParams.input.colorSpace = sfcParam.input.colorSpace;
106 cscParams.output.colorSpace = sfcParam.output.colorSpace;
107 cscParams.input.chromaSiting = sfcParam.input.chromaSiting;
108 cscParams.output.chromaSiting = sfcParam.output.chromaSiting;
109
110 m_cscFilter->Init();
111 m_cscFilter->SetExecuteEngineCaps(cscParams, vpExecuteCaps);
112 m_cscFilter->CalculateEngineParams();
113
114 return m_sfcRender->SetCSCParams(m_cscFilter->GetSfcParams());
115 }
116
SetScalingParams(VDBOX_SFC_PARAMS & sfcParam,VP_EXECUTE_CAPS & vpExecuteCaps)117 MOS_STATUS MediaVdboxSfcRender::SetScalingParams(VDBOX_SFC_PARAMS &sfcParam, VP_EXECUTE_CAPS &vpExecuteCaps)
118 {
119 VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender);
120 VP_PUBLIC_CHK_NULL_RETURN(m_scalingFilter);
121
122 RECT rcSrcInput = {0, 0, (int32_t)sfcParam.input.width, (int32_t)sfcParam.input.height };
123 RECT rcEffectiveSrcInput = {0, 0, (int32_t)sfcParam.input.effectiveWidth, (int32_t)sfcParam.input.effectiveHeight };
124 RECT rcOutput = {0, 0, (int32_t)sfcParam.output.surface->dwWidth, (int32_t)sfcParam.output.surface->dwHeight };
125 FeatureParamScaling scalingParams = {};
126 scalingParams.type = FeatureTypeScalingOnSfc;
127 scalingParams.formatInput = sfcParam.input.format;
128 scalingParams.formatOutput = sfcParam.output.surface->Format;
129 scalingParams.scalingMode = GetScalingMode(sfcParam.scalingMode);
130 scalingParams.scalingPreference = VPHAL_SCALING_PREFER_SFC; //!< DDI indicate Scaling preference
131 scalingParams.bDirectionalScalar = false; //!< Vebox Directional Scalar
132 scalingParams.input.rcSrc = rcEffectiveSrcInput; //!< rcEffectiveSrcInput exclude right/bottom padding area of SFC input.
133 scalingParams.input.rcDst = sfcParam.output.rcDst;
134 scalingParams.input.rcMaxSrc = rcSrcInput;
135 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.
136 scalingParams.input.dwHeight = sfcParam.input.height;
137 scalingParams.output.rcSrc = rcOutput;
138 scalingParams.output.rcDst = rcOutput;
139 scalingParams.output.rcMaxSrc = rcOutput;
140 scalingParams.output.dwWidth = sfcParam.output.surface->dwWidth;
141 scalingParams.output.dwHeight = sfcParam.output.surface->dwHeight;
142 scalingParams.pColorFillParams = nullptr;
143 scalingParams.pCompAlpha = nullptr;
144 scalingParams.csc.colorSpaceOutput = sfcParam.output.colorSpace;
145 scalingParams.interlacedScalingType = sfcParam.videoParams.fieldParams.isFieldToInterleaved ? ISCALING_FIELD_TO_INTERLEAVED : ISCALING_NONE;
146 if (sfcParam.videoParams.fieldParams.isFieldToInterleaved)
147 {
148 scalingParams.input.sampleType = sfcParam.videoParams.fieldParams.isBottomField ? SAMPLE_SINGLE_BOTTOM_FIELD : SAMPLE_SINGLE_TOP_FIELD;
149 scalingParams.output.sampleType = sfcParam.videoParams.fieldParams.isBottomFirst ? SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD : SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
150 }
151 else
152 {
153 scalingParams.input.sampleType = SAMPLE_PROGRESSIVE;
154 scalingParams.output.sampleType = SAMPLE_PROGRESSIVE;
155 }
156
157 m_scalingFilter->Init(sfcParam.videoParams.codecStandard, sfcParam.videoParams.jpeg.jpegChromaType);
158 VP_PUBLIC_CHK_STATUS_RETURN(m_scalingFilter->SetExecuteEngineCaps(scalingParams, vpExecuteCaps));
159 VP_PUBLIC_CHK_STATUS_RETURN(m_scalingFilter->CalculateEngineParams());
160
161 return m_sfcRender->SetScalingParams(m_scalingFilter->GetSfcParams());
162 }
163
SetSfcMmcParams(VDBOX_SFC_PARAMS & sfcParam)164 MOS_STATUS MediaVdboxSfcRender::SetSfcMmcParams(VDBOX_SFC_PARAMS &sfcParam)
165 {
166 VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->SetSurfaceMmcState(sfcParam.output.surface));
167 VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->SetSurfaceMmcMode(sfcParam.output.surface));
168 VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->SetSurfaceMmcFormat(sfcParam.output.surface));
169 return m_sfcRender->SetMmcParams(sfcParam.output.surface, true, m_mmc->IsMmcEnabled());
170 }
171
SetRotMirParams(VDBOX_SFC_PARAMS & sfcParam,VP_EXECUTE_CAPS & vpExecuteCaps)172 MOS_STATUS MediaVdboxSfcRender::SetRotMirParams(VDBOX_SFC_PARAMS &sfcParam, VP_EXECUTE_CAPS &vpExecuteCaps)
173 {
174 VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender);
175 VP_PUBLIC_CHK_NULL_RETURN(m_rotMirFilter);
176 FeatureParamRotMir rotMirParams = {};
177 rotMirParams.type = FeatureTypeRotMirOnSfc;
178 rotMirParams.formatInput = sfcParam.input.format;
179 rotMirParams.formatOutput = sfcParam.output.surface->Format;
180 rotMirParams.rotation = sfcParam.input.mirrorEnabled ? VPHAL_MIRROR_HORIZONTAL : VPHAL_ROTATION_IDENTITY;
181 rotMirParams.surfInfo.tileOutput = sfcParam.output.surface->TileType;
182
183 m_rotMirFilter->Init();
184 m_rotMirFilter->SetExecuteEngineCaps(rotMirParams, vpExecuteCaps);
185 m_rotMirFilter->CalculateEngineParams();
186
187 return m_sfcRender->SetRotMirParams(m_rotMirFilter->GetSfcParams());
188 }
189
SetHistogramParams(VDBOX_SFC_PARAMS & sfcParam)190 MOS_STATUS MediaVdboxSfcRender::SetHistogramParams(VDBOX_SFC_PARAMS& sfcParam)
191 {
192 return m_sfcRender->SetHistogramBuf(sfcParam.output.histogramBuf);
193 }
194
AddSfcStates(MOS_COMMAND_BUFFER * cmdBuffer,VDBOX_SFC_PARAMS & sfcParam)195 MOS_STATUS MediaVdboxSfcRender::AddSfcStates(MOS_COMMAND_BUFFER *cmdBuffer, VDBOX_SFC_PARAMS &sfcParam)
196 {
197 VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender);
198 VP_PUBLIC_CHK_NULL_RETURN(sfcParam.output.surface);
199 VP_PUBLIC_CHK_NULL_RETURN(cmdBuffer);
200
201 VP_EXECUTE_CAPS vpExecuteCaps = {};
202 vpExecuteCaps.bSFC = 1;
203 vpExecuteCaps.bSfcCsc = 1;
204 vpExecuteCaps.bSfcScaling = 1;
205 vpExecuteCaps.bSfcRotMir = 1;
206
207 VP_PUBLIC_CHK_STATUS_RETURN(m_sfcRender->Init(sfcParam.videoParams));
208 VP_PUBLIC_CHK_STATUS_RETURN(SetCSCParams(sfcParam, vpExecuteCaps));
209 VP_PUBLIC_CHK_STATUS_RETURN(SetScalingParams(sfcParam, vpExecuteCaps));
210 VP_PUBLIC_CHK_STATUS_RETURN(SetRotMirParams(sfcParam, vpExecuteCaps));
211 VP_PUBLIC_CHK_STATUS_RETURN(SetHistogramParams(sfcParam));
212 VP_PUBLIC_CHK_STATUS_RETURN(SetSfcMmcParams(sfcParam));
213
214 RECT rcOutput = {0, 0, (int32_t)sfcParam.output.surface->dwWidth, (int32_t)sfcParam.output.surface->dwHeight};
215 // The value of plane offset are different between vp and codec. updatePlaneOffset need be set to true when create vp surface
216 // with mos surface from codec hal.
217 VP_SURFACE *renderTarget = m_allocator->AllocateVpSurface(*sfcParam.output.surface,
218 sfcParam.output.colorSpace,
219 sfcParam.output.chromaSiting,
220 rcOutput,
221 rcOutput,
222 SURF_OUT_RENDERTARGET,
223 true);
224
225 //---------------------------------
226 // Send CMD: SFC pipe commands
227 //---------------------------------
228
229 VP_RENDER_CHK_STATUS_RETURN(m_sfcRender->SetupSfcState(renderTarget));
230 VP_RENDER_CHK_STATUS_RETURN(m_sfcRender->SendSfcCmd(
231 CODECHAL_JPEG != sfcParam.videoParams.codecStandard,
232 cmdBuffer));
233
234 m_allocator->DestroyVpSurface(renderTarget);
235 m_allocator->CleanRecycler();
236
237 return MOS_STATUS_SUCCESS;
238 }
239
GetScalingMode(CODECHAL_SCALING_MODE scalingMode)240 VPHAL_SCALING_MODE MediaVdboxSfcRender::GetScalingMode(CODECHAL_SCALING_MODE scalingMode)
241 {
242 // Default mode is VPHAL_SCALING_AVS
243 VPHAL_SCALING_MODE sfcScalingMode = VPHAL_SCALING_AVS;
244
245 switch(scalingMode)
246 {
247 case CODECHAL_SCALING_BILINEAR:
248 sfcScalingMode = VPHAL_SCALING_BILINEAR;
249 break;
250 case CODECHAL_SCALING_NEAREST:
251 case CODECHAL_SCALING_AVS:
252 case CODECHAL_SCALING_ADV_QUALITY:
253 default:
254 sfcScalingMode = VPHAL_SCALING_AVS;
255 break;
256 }
257
258 return sfcScalingMode;
259 }
260
IsVdboxSfcFormatSupported(CODECHAL_STANDARD codecStandard,MOS_FORMAT inputFormat,MOS_FORMAT outputFormat,MOS_TILE_TYPE tileType)261 bool MediaVdboxSfcRender::IsVdboxSfcFormatSupported(
262 CODECHAL_STANDARD codecStandard,
263 MOS_FORMAT inputFormat,
264 MOS_FORMAT outputFormat,
265 MOS_TILE_TYPE tileType)
266 {
267 if (nullptr == m_sfcRender)
268 {
269 return false;
270 }
271
272 return (m_sfcRender->IsVdboxSfcInputFormatSupported(codecStandard, inputFormat) &&
273 m_sfcRender->IsVdboxSfcOutputFormatSupported(codecStandard, outputFormat, tileType));
274 }
275