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