1 /*
2 * Copyright (c) 2018-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 //!
24 //! \file media_scalability_factory.cpp
25 //! \brief Defines the functions for media scalability factory
26 //!
27
28 #include "media_scalability_factory.h"
29 #if !EMUL
30 #include "encode_scalability_singlepipe.h"
31 #include "encode_scalability_multipipe.h"
32 #include "decode_scalability_option.h"
33 #endif
34 #include "vp_scalability_multipipe_next.h"
35 #include "vp_scalability_singlepipe_next.h"
36
37 template<typename T>
CreateScalability(uint8_t componentType,T params,void * hwInterface,MediaContext * mediaContext,MOS_GPUCTX_CREATOPTIONS * gpuCtxCreateOption)38 MediaScalability *MediaScalabilityFactory<T>::CreateScalability(uint8_t componentType, T params, void *hwInterface, MediaContext *mediaContext, MOS_GPUCTX_CREATOPTIONS *gpuCtxCreateOption)
39 {
40 if (params == nullptr)
41 {
42 return nullptr;
43 }
44
45 //Create SinglePipe/MultiPipe scalability.
46 return CreateScalabilityCmdBuf(componentType, params, hwInterface, mediaContext, gpuCtxCreateOption);
47 }
48
49 template<typename T>
CreateScalabilityCmdBuf(uint8_t componentType,T params,void * hwInterface,MediaContext * mediaContext,MOS_GPUCTX_CREATOPTIONS * gpuCtxCreateOption)50 MediaScalability *MediaScalabilityFactory<T>::CreateScalabilityCmdBuf(uint8_t componentType, T params, void *hwInterface, MediaContext *mediaContext, MOS_GPUCTX_CREATOPTIONS *gpuCtxCreateOption)
51 {
52 switch (componentType)
53 {
54 #if !EMUL
55 case scalabilityEncoder:
56 return CreateEncodeScalability(params, hwInterface, mediaContext, gpuCtxCreateOption);
57 case scalabilityDecoder:
58 return CreateDecodeScalability(params, hwInterface, mediaContext, gpuCtxCreateOption);
59 #endif
60 case scalabilityVp:
61 return CreateVpScalability(params, hwInterface, mediaContext, gpuCtxCreateOption);
62 default:
63 return nullptr;
64 }
65 }
66 #if !EMUL
67 template<typename T>
CreateEncodeScalability(T params,void * hwInterface,MediaContext * mediaContext,MOS_GPUCTX_CREATOPTIONS * gpuCtxCreateOption)68 MediaScalability *MediaScalabilityFactory<T>::CreateEncodeScalability(T params, void *hwInterface, MediaContext *mediaContext, MOS_GPUCTX_CREATOPTIONS *gpuCtxCreateOption)
69 {
70 MediaScalability *scalabilityHandle = nullptr;
71 if (params == nullptr || hwInterface == nullptr)
72 {
73 return nullptr;
74 }
75
76 encode::EncodeScalabilityOption *option = nullptr;
77 if (std::is_same<decltype(params), ScalabilityPars*>::value)
78 {
79 option = MOS_New(encode::EncodeScalabilityOption);
80 if (option != nullptr)
81 {
82 auto scalabPars = reinterpret_cast<ScalabilityPars *>(params);
83 option->SetScalabilityOption(scalabPars);
84 }
85 }
86 else
87 {
88 auto scalabOption = reinterpret_cast<MediaScalabilityOption *>(params);
89 option = dynamic_cast<encode::EncodeScalabilityOption *>(scalabOption);
90 }
91
92 if (option == nullptr)
93 {
94 return nullptr;
95 }
96
97 //Create scalability handle refer to scalability option.
98
99 if (option->GetNumPipe() == 1)
100 {
101 scalabilityHandle = MOS_New(encode::EncodeScalabilitySinglePipe, hwInterface, mediaContext, scalabilityEncoder);
102 }
103 else
104 {
105 scalabilityHandle = MOS_New(encode::EncodeScalabilityMultiPipe, hwInterface, mediaContext, scalabilityEncoder);
106 }
107
108 if (scalabilityHandle == nullptr)
109 {
110 if (std::is_same<decltype(params), ScalabilityPars *>::value)
111 {
112 MOS_Delete(option);
113 }
114 return nullptr;
115 }
116
117 if (MOS_STATUS_SUCCESS != scalabilityHandle->Initialize(*option))
118 {
119 SCALABILITY_ASSERTMESSAGE("Scalability Initialize failed!");
120 MOS_Delete(scalabilityHandle);
121 if (std::is_same<decltype(params), ScalabilityPars *>::value)
122 {
123 MOS_Delete(option);
124 }
125 return nullptr;
126 }
127 if (gpuCtxCreateOption)
128 {
129 scalabilityHandle->GetGpuCtxCreationOption(gpuCtxCreateOption);
130 }
131
132 if (std::is_same<decltype(params), ScalabilityPars *>::value)
133 {
134 MOS_Delete(option);
135 }
136
137 return scalabilityHandle;
138 }
139
140 template<typename T>
CreateDecodeScalability(T params,void * hwInterface,MediaContext * mediaContext,MOS_GPUCTX_CREATOPTIONS * gpuCtxCreateOption)141 MediaScalability *MediaScalabilityFactory<T>::CreateDecodeScalability(T params, void *hwInterface, MediaContext *mediaContext, MOS_GPUCTX_CREATOPTIONS *gpuCtxCreateOption)
142 {
143 if (params == nullptr || hwInterface == nullptr)
144 {
145 return nullptr;
146 }
147
148 decode::DecodeScalabilityOption *option = nullptr;
149 if (std::is_same<decltype(params), ScalabilityPars*>::value)
150 {
151 option = MOS_New(decode::DecodeScalabilityOption);
152 if (option != nullptr)
153 {
154 auto scalabPars = reinterpret_cast<ScalabilityPars *>(params);
155 MOS_STATUS status = option->SetScalabilityOption(scalabPars);
156 if (status != MOS_STATUS_SUCCESS)
157 {
158 SCALABILITY_ASSERTMESSAGE("option->SetScalabilityOption failed w/ status == %d!", status);
159 MOS_Delete(option);
160 return nullptr;
161 }
162 }
163 }
164 else
165 {
166 auto scalabOption = reinterpret_cast<MediaScalabilityOption *>(params);
167 option = dynamic_cast<decode::DecodeScalabilityOption *>(scalabOption);
168 }
169
170 if (option == nullptr)
171 {
172 return nullptr;
173 }
174
175 //Create scalability handle refer to scalability option.
176 MediaScalability *scalabilityHandle = nullptr;
177 CodechalHwInterfaceNext *codecHwInterface = ((CodechalHwInterfaceNext *)hwInterface);
178 if (codecHwInterface->pfnCreateDecodeSinglePipe == nullptr || codecHwInterface->pfnCreateDecodeMultiPipe == nullptr)
179 {
180 SCALABILITY_ASSERTMESSAGE("Scalability pointer is null!");
181 if (std::is_same<decltype(params), ScalabilityPars *>::value)
182 {
183 MOS_Delete(option);
184 }
185 return nullptr;
186 }
187 if (option->GetNumPipe() == 1)
188 {
189 if ((codecHwInterface->pfnCreateDecodeSinglePipe(hwInterface, mediaContext, scalabilityDecoder)) != MOS_STATUS_SUCCESS)
190 {
191 SCALABILITY_ASSERTMESSAGE("Scalability Creation failed!");
192 if (std::is_same<decltype(params), ScalabilityPars *>::value)
193 {
194 MOS_Delete(option);
195 }
196 return nullptr;
197 }
198 scalabilityHandle = codecHwInterface->m_singlePipeScalability;
199 }
200 else
201 {
202 if ((codecHwInterface->pfnCreateDecodeMultiPipe(hwInterface, mediaContext, scalabilityDecoder)) != MOS_STATUS_SUCCESS)
203 {
204 SCALABILITY_ASSERTMESSAGE("Scalability Creation failed!");
205 if (std::is_same<decltype(params), ScalabilityPars *>::value)
206 {
207 MOS_Delete(option);
208 }
209 return nullptr;
210 }
211 scalabilityHandle = codecHwInterface->m_multiPipeScalability;
212 }
213
214 if (scalabilityHandle == nullptr)
215 {
216 if (std::is_same<decltype(params), ScalabilityPars *>::value)
217 {
218 MOS_Delete(option);
219 }
220 return nullptr;
221 }
222
223 if (MOS_STATUS_SUCCESS != scalabilityHandle->Initialize(*option))
224 {
225 SCALABILITY_ASSERTMESSAGE("Scalability Initialize failed!");
226 MOS_Delete(scalabilityHandle);
227 if (std::is_same<decltype(params), ScalabilityPars *>::value)
228 {
229 MOS_Delete(option);
230 }
231 return nullptr;
232 }
233 if (gpuCtxCreateOption)
234 {
235 scalabilityHandle->GetGpuCtxCreationOption(gpuCtxCreateOption);
236 }
237
238 if (std::is_same<decltype(params), ScalabilityPars *>::value)
239 {
240 MOS_Delete(option);
241 }
242
243 return scalabilityHandle;
244 }
245 #endif
246 template<typename T>
CreateVpScalability(T params,void * hwInterface,MediaContext * mediaContext,MOS_GPUCTX_CREATOPTIONS * gpuCtxCreateOption)247 MediaScalability *MediaScalabilityFactory<T>::CreateVpScalability(T params, void *hwInterface, MediaContext *mediaContext, MOS_GPUCTX_CREATOPTIONS *gpuCtxCreateOption)
248 {
249 if (params == nullptr || hwInterface == nullptr)
250 {
251 return nullptr;
252 }
253
254 vp::VpScalabilityOption *option = nullptr;
255 if (std::is_same<decltype(params), ScalabilityPars*>::value)
256 {
257 option = MOS_New(vp::VpScalabilityOption);
258 if (option != nullptr)
259 {
260 auto scalabPars = reinterpret_cast<ScalabilityPars *>(params);
261 option->SetScalabilityOption(scalabPars);
262 }
263 }
264 else
265 {
266 auto scalabOption = reinterpret_cast<MediaScalabilityOption *>(params);
267 option = dynamic_cast<vp::VpScalabilityOption *>(scalabOption);
268 }
269
270 if (option == nullptr)
271 {
272 return nullptr;
273 }
274
275 // will add scalability multi-pipe when 2 or more Vebox/SFC are supported
276 MediaScalability *scalabilityHandle = nullptr;
277 PVP_MHWINTERFACE vphwInterface = (PVP_MHWINTERFACE)hwInterface;
278
279 // Check CreateMultiPipe/CreateSinglePipe pointer
280 if (vphwInterface->pfnCreateSinglePipe == nullptr || vphwInterface->pfnCreateMultiPipe == nullptr)
281 {
282 SCALABILITY_ASSERTMESSAGE("Scalability pointer is null!");
283 if (std::is_same<decltype(params), ScalabilityPars *>::value)
284 {
285 MOS_Delete(option);
286 }
287 return nullptr;
288 }
289
290 if (option->GetNumPipe() == 1)
291 {
292 if ((vphwInterface->pfnCreateSinglePipe(hwInterface, mediaContext, scalabilityVp)) != MOS_STATUS_SUCCESS)
293 {
294 SCALABILITY_ASSERTMESSAGE("Scalability Creation failed!");
295 if (std::is_same<decltype(params), ScalabilityPars *>::value)
296 {
297 MOS_Delete(option);
298 }
299 return nullptr;
300 }
301 scalabilityHandle = vphwInterface->m_singlePipeScalability;
302 }
303 else
304 {
305 if ((vphwInterface->pfnCreateMultiPipe(hwInterface, mediaContext, scalabilityVp)) != MOS_STATUS_SUCCESS)
306 {
307 SCALABILITY_ASSERTMESSAGE("Scalability Creation failed!");
308 if (std::is_same<decltype(params), ScalabilityPars *>::value)
309 {
310 MOS_Delete(option);
311 }
312 return nullptr;
313 }
314 scalabilityHandle = vphwInterface->m_multiPipeScalability;
315 }
316
317 if (scalabilityHandle == nullptr)
318 {
319 if (std::is_same<decltype(params), ScalabilityPars *>::value)
320 {
321 MOS_Delete(option);
322 }
323 return nullptr;
324 }
325
326 if (MOS_STATUS_SUCCESS != scalabilityHandle->Initialize(*option))
327 {
328 SCALABILITY_ASSERTMESSAGE("Scalability Initialize failed!");
329 MOS_Delete(scalabilityHandle);
330 if (std::is_same<decltype(params), ScalabilityPars *>::value)
331 {
332 MOS_Delete(option);
333 }
334 return nullptr;
335 }
336
337 if (gpuCtxCreateOption)
338 {
339 scalabilityHandle->GetGpuCtxCreationOption(gpuCtxCreateOption);
340 }
341
342 if (std::is_same<decltype(params), ScalabilityPars *>::value)
343 {
344 MOS_Delete(option);
345 }
346
347 return scalabilityHandle;
348 }
349
350 template class MediaScalabilityFactory<ScalabilityPars*>;
351 template class MediaScalabilityFactory<MediaScalabilityOption*>;
352
353