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