1 // Copyright (c) 2017 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #include "math.h"
22 #include "mfx_common.h"
23 
24 #if defined (MFX_ENABLE_VPP)
25 #include "mfx_enc_common.h"
26 #include "mfx_session.h"
27 #include "mfxmvc.h"
28 
29 #include "mfx_vpp_utils.h"
30 #include "mfx_vpp_main.h"
31 #include "mfx_vpp_sw.h"
32 
33 #include "mfx_vpp_mvc.h"
34 
35 
36 using namespace MfxVideoProcessing;
37 
38 /* ******************************************************************** */
39 /*                 Main (High Level) Class of MSDK VPP                  */
40 /* ******************************************************************** */
41 
42 
Query(VideoCORE * core,mfxVideoParam * in,mfxVideoParam * out)43 mfxStatus VideoVPPMain::Query(VideoCORE* core, mfxVideoParam *in, mfxVideoParam *out)
44 {
45     return ImplementationMvc::Query(core, in, out);
46 } // mfxStatus VideoVPPMain::Query(VideoCORE* core, mfxVideoParam *in, mfxVideoParam *out)
47 
48 
QueryIOSurf(VideoCORE * core,mfxVideoParam * par,mfxFrameAllocRequest * request)49 mfxStatus VideoVPPMain::QueryIOSurf(VideoCORE* core, mfxVideoParam *par, mfxFrameAllocRequest *request)
50 {
51 
52     return ImplementationMvc::QueryIOSurf(core, par, request);
53 
54 } // mfxStatus VideoVPPMain::QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request, const mfxU32 adapterNum)
55 
56 
VideoVPPMain(VideoCORE * core,mfxStatus * sts)57 VideoVPPMain::VideoVPPMain(VideoCORE *core, mfxStatus* sts )
58 : m_core( core )
59 {
60     m_bOpaqMode[VPP_IN] = m_bOpaqMode[VPP_OUT] = false;
61 
62     *sts   = MFX_ERR_NONE;
63 
64 } // VideoVPPMain::VideoVPPMain(VideoCORE *core, mfxStatus* sts )
65 
66 
~VideoVPPMain()67 VideoVPPMain::~VideoVPPMain()
68 {
69     Close();
70 
71 } // VideoVPPMain::~VideoVPPMain()
72 
73 
Init(mfxVideoParam * par)74 mfxStatus VideoVPPMain::Init(mfxVideoParam *par)
75 {
76     MFX_CHECK_NULL_PTR1( par );
77     mfxStatus internalSts = MFX_ERR_NONE;
78 
79     if( m_impl.get() )
80     {
81         return MFX_ERR_UNDEFINED_BEHAVIOR;
82     }
83 
84     std::unique_ptr<VideoVPP> impl(
85               (VideoVPP*) new ImplementationMvc(m_core));
86 
87     mfxStatus mfxSts = impl->Init(par);
88     MFX_CHECK(
89         mfxSts == MFX_ERR_NONE                 ||
90         mfxSts == MFX_WRN_PARTIAL_ACCELERATION ||
91         mfxSts == MFX_WRN_FILTER_SKIPPED       ||
92         mfxSts == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM,
93         mfxSts);
94 
95     /*if( MFX_WRN_PARTIAL_ACCELERATION == mfxSts)
96     {
97         isPartialAcceleration = true;
98     }
99     else if(MFX_WRN_FILTER_SKIPPED == mfxSts)
100     {
101         isFilterSkipped = true;
102     }
103     else if(MFX_WRN_INCOMPATIBLE_VIDEO_PARAM == mfxSts)
104     {
105         isIncompatibleParam = true;
106     }*/
107 
108     internalSts = mfxSts;
109 
110     // opaque configuration
111     mfxSts = CheckOpaqMode( par, m_bOpaqMode );
112     MFX_CHECK_STS( mfxSts );
113 
114     if( m_bOpaqMode[VPP_IN] || m_bOpaqMode[VPP_OUT] )
115     {
116         mfxExtOpaqueSurfaceAlloc *pOpaqAlloc = (mfxExtOpaqueSurfaceAlloc *)GetExtendedBufferInternal(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION);
117 
118         mfxFrameAllocRequest  requestOpaq;
119 
120         if( m_bOpaqMode[VPP_IN] )
121         {
122             requestOpaq.Info = par->vpp.In;
123             requestOpaq.NumFrameMin = requestOpaq.NumFrameSuggested = (mfxU16)pOpaqAlloc->In.NumSurface;
124             requestOpaq.Type = (mfxU16)(pOpaqAlloc->In.Type|MFX_MEMTYPE_FROM_VPPIN);
125 
126             mfxSts = m_core->AllocFrames(&(requestOpaq),
127                                          &(m_responseOpaq[VPP_IN]),
128                                          pOpaqAlloc->In.Surfaces,
129                                          pOpaqAlloc->In.NumSurface);
130             MFX_CHECK_STS( mfxSts );
131         }
132 
133         if( m_bOpaqMode[VPP_OUT] )
134         {
135             requestOpaq.Info = par->vpp.Out;
136             requestOpaq.NumFrameMin = requestOpaq.NumFrameSuggested = (mfxU16)pOpaqAlloc->Out.NumSurface;
137             requestOpaq.Type = (mfxU16)(pOpaqAlloc->Out.Type|MFX_MEMTYPE_FROM_VPPOUT);
138 
139             mfxSts = m_core->AllocFrames(&(requestOpaq),
140                                          &(m_responseOpaq[VPP_OUT]),
141                                          pOpaqAlloc->Out.Surfaces,
142                                          pOpaqAlloc->Out.NumSurface);
143 
144             MFX_CHECK_STS( mfxSts );
145 
146         }
147     }
148 
149     m_impl = std::move(impl);
150 
151     return (MFX_ERR_NONE == mfxSts) ? internalSts : mfxSts;
152 
153 } // mfxStatus VideoVPPMain::Init(mfxVideoParam *par)
154 
155 
Close(void)156 mfxStatus VideoVPPMain::Close( void )
157 {
158     if( !m_impl.get() )
159     {
160         return MFX_ERR_NONE;
161     }
162 
163     m_impl->Close();
164     m_impl.reset();
165 
166     /* opaque processing */
167     if( m_bOpaqMode[VPP_IN] )
168     {
169         m_core->FreeFrames( &(m_responseOpaq[VPP_IN]) );
170         m_responseOpaq[VPP_IN].NumFrameActual  = 0;
171     }
172     if( m_bOpaqMode[VPP_OUT] )
173     {
174         m_core->FreeFrames( &(m_responseOpaq[VPP_OUT]) );
175         m_responseOpaq[VPP_OUT].NumFrameActual = 0;
176     }
177 
178     m_bOpaqMode[VPP_IN] = m_bOpaqMode[VPP_OUT] = false;
179 
180     return MFX_ERR_NONE;
181 
182 } // mfxStatus VideoVPPMain::Close( void )
183 
GetThreadingPolicy(void)184 mfxTaskThreadingPolicy VideoVPPMain::GetThreadingPolicy(void)
185 {
186     return MFX_TASK_THREADING_INTRA;
187 
188 } // mfxTaskThreadingPolicy VideoVPPMain::GetThreadingPolicy(void)
189 
190 
VppFrameCheck(mfxFrameSurface1 * in,mfxFrameSurface1 * out,mfxExtVppAuxData * aux,MFX_ENTRY_POINT pEntryPoint[],mfxU32 & numEntryPoints)191 mfxStatus VideoVPPMain::VppFrameCheck(mfxFrameSurface1 *in,
192                                       mfxFrameSurface1 *out,
193                                       mfxExtVppAuxData *aux,
194                                       MFX_ENTRY_POINT pEntryPoint[],
195                                       mfxU32 &numEntryPoints)
196 {
197     MFX_CHECK_NULL_PTR1( out );
198 
199     if( !m_impl.get() )
200     {
201         return MFX_ERR_NOT_INITIALIZED;
202     }
203 
204     if (in && m_bOpaqMode[VPP_IN])
205     {
206         if (in->Data.Y || in->Data.U || in->Data.V || in->Data.A || in->Data.MemId)
207             return MFX_ERR_UNDEFINED_BEHAVIOR;
208     }
209 
210     if (out && m_bOpaqMode[VPP_OUT])
211     {
212         if (out->Data.Y || out->Data.U || out->Data.V || out->Data.A || out->Data.MemId)
213             return MFX_ERR_UNDEFINED_BEHAVIOR;
214     }
215 
216     mfxFrameSurface1* pInputNative  =  GetNativeSurface(in, VPP_IN);
217     mfxFrameSurface1* pOutputNative =  GetNativeSurface(out, VPP_OUT);
218 
219     // to prevent Opaque issue
220     if( (in && (NULL == pInputNative)) || (out && (NULL == pOutputNative)) )
221     {
222         return MFX_ERR_UNDEFINED_BEHAVIOR;
223     }
224 
225 
226     mfxStatus mfxSts = m_impl->VppFrameCheck( pInputNative, pOutputNative, aux, pEntryPoint, numEntryPoints );
227 
228 
229     // Check() updated out:frameInfo & out:Data. so we need sync in case of output opaq surface
230     if( m_bOpaqMode[VPP_OUT] && pOutputNative )
231     {
232         if( (MFX_ERR_NONE == mfxSts) ||
233             (MFX_ERR_MORE_DATA == mfxSts) ||
234             ((mfxStatus)MFX_ERR_MORE_DATA_SUBMIT_TASK == mfxSts) ||
235             (MFX_ERR_MORE_SURFACE == mfxSts) )
236         {
237             out->Data.FrameOrder = pOutputNative->Data.FrameOrder;
238             out->Data.TimeStamp  = pOutputNative->Data.TimeStamp;
239             out->Info = pOutputNative->Info;
240         }
241     }
242 
243     return mfxSts;
244 
245 } // mfxStatus VideoVPPMain::VppFrameCheck(...)
246 
247 
RunFrameVPP(mfxFrameSurface1 * in,mfxFrameSurface1 * out,mfxExtVppAuxData * aux)248 mfxStatus VideoVPPMain::RunFrameVPP(mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux)
249 {
250 
251     mfxFrameSurface1* pNativeInput  = GetNativeSurface(in,   VPP_IN);
252     mfxFrameSurface1* pNativeOutput = GetNativeSurface(out,  VPP_OUT);
253 
254     mfxStatus mfxSts = m_impl->RunFrameVPP(
255         pNativeInput,
256         pNativeOutput,
257         aux);
258 
259     return mfxSts;
260 
261 } // mfxStatus VideoVPPMain::RunFrameVPP(mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux)
262 
263 #endif // MFX_ENABLE_VPP
264 /* EOF */
265