1 // Copyright (c) 2017-2020 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 #ifndef __MFXPLUGINPLUSPLUS_H
22 #define __MFXPLUGINPLUSPLUS_H
23 
24 #include "mfxplugin.h"
25 
26 // base class for MFXVideoUSER/MFXAudioUSER API
27 
28 class MFXBaseUSER {
29 public:
30     explicit MFXBaseUSER(mfxSession session = NULL)
m_session(session)31         : m_session(session){}
32 
~MFXBaseUSER()33     virtual ~MFXBaseUSER() {}
34 
35     virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) = 0;
36     virtual mfxStatus Unregister(mfxU32 type) = 0;
37     virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) = 0;
38 
39 protected:
40     mfxSession m_session;
41 };
42 
43 //c++ wrapper over only 3 exposed functions from MFXVideoUSER module
44 class MFXVideoUSER: public MFXBaseUSER {
45 public:
46     explicit MFXVideoUSER(mfxSession session = NULL)
MFXBaseUSER(session)47         : MFXBaseUSER(session){}
48 
Register(mfxU32 type,const mfxPlugin * par)49     virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) {
50         return MFXVideoUSER_Register(m_session, type, par);
51     }
Unregister(mfxU32 type)52     virtual mfxStatus Unregister(mfxU32 type) {
53         return MFXVideoUSER_Unregister(m_session, type);
54     }
ProcessFrameAsync(const mfxHDL * in,mfxU32 in_num,const mfxHDL * out,mfxU32 out_num,mfxSyncPoint * syncp)55     virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) {
56         return MFXVideoUSER_ProcessFrameAsync(m_session, in, in_num, out, out_num, syncp);
57     }
58 };
59 
60 //c++ wrapper over only 3 exposed functions from MFXAudioUSER module
61 class MFXAudioUSER: public MFXBaseUSER {
62 public:
63     explicit MFXAudioUSER(mfxSession session = NULL)
MFXBaseUSER(session)64         : MFXBaseUSER(session){}
65 
Register(mfxU32 type,const mfxPlugin * par)66     virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) {
67         return MFXAudioUSER_Register(m_session, type, par);
68     }
Unregister(mfxU32 type)69     virtual mfxStatus Unregister(mfxU32 type) {
70         return MFXAudioUSER_Unregister(m_session, type);
71     }
ProcessFrameAsync(const mfxHDL * in,mfxU32 in_num,const mfxHDL * out,mfxU32 out_num,mfxSyncPoint * syncp)72     virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) {
73         return MFXAudioUSER_ProcessFrameAsync(m_session, in, in_num, out, out_num, syncp);
74     }
75 };
76 
77 
78 //initialize mfxPlugin struct
79 class MFXPluginParam {
80     mfxPluginParam m_param;
81 
82 public:
83     MFXPluginParam(mfxU32 CodecId, mfxU32  Type, mfxPluginUID uid, mfxThreadPolicy ThreadPolicy = MFX_THREADPOLICY_SERIAL, mfxU32  MaxThreadNum = 1)
m_param()84         : m_param() {
85         m_param.PluginUID = uid;
86         m_param.Type = Type;
87         m_param.CodecId = CodecId;
88         m_param.MaxThreadNum = MaxThreadNum;
89         m_param.ThreadPolicy = ThreadPolicy;
90     }
91     operator const mfxPluginParam& () const {
92         return m_param;
93     }
94     operator mfxPluginParam& () {
95         return m_param;
96     }
97 };
98 
99 //common interface part for every plugin: decoder/encoder and generic
100 struct MFXPlugin
101 {
~MFXPluginMFXPlugin102     virtual ~MFXPlugin() {};
103     //init function always required for any transform or codec plugins, for codec plugins it maps to callback from MediaSDK
104     //for generic plugin application should call it
105     //MediaSDK mfxPlugin API mapping
106     virtual mfxStatus PluginInit(mfxCoreInterface *core) = 0;
107     //release CoreInterface, and destroy plugin state, not destroy plugin instance
108     virtual mfxStatus PluginClose() = 0;
109     virtual mfxStatus GetPluginParam(mfxPluginParam *par) = 0;
110     virtual mfxStatus Execute(mfxThreadTask task, mfxU32 uid_p, mfxU32 uid_a) = 0;
111     virtual mfxStatus FreeResources(mfxThreadTask task, mfxStatus sts) = 0;
112     //destroy plugin due to shared module distribution model plugin wont support virtual destructor
113     virtual void      Release() = 0;
114     //release resources associated with current instance of plugin, but do not release CoreInterface related resource set in pluginInit
115     virtual mfxStatus Close()  = 0;
116     //communication protocol between particular version of plugin and application
117     virtual mfxStatus SetAuxParams(void* auxParam, int auxParamSize) = 0;
118 };
119 
120 //common extension interface that codec plugins should expose additionally to MFXPlugin
121 struct MFXCodecPlugin : MFXPlugin
122 {
123     virtual mfxStatus Init(mfxVideoParam *par) = 0;
124     virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out) = 0;
125     virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) =0;
126     virtual mfxStatus Reset(mfxVideoParam *par) = 0;
127     virtual mfxStatus GetVideoParam(mfxVideoParam *par) = 0;
128 };
129 
130 //common extension interface that audio codec plugins should expose additionally to MFXPlugin
131 struct MFXAudioCodecPlugin : MFXPlugin
132 {
133     virtual mfxStatus Init(mfxAudioParam *par) = 0;
134     virtual mfxStatus Query(mfxAudioParam *in, mfxAudioParam *out) =0;
135     virtual mfxStatus QueryIOSize(mfxAudioParam *par, mfxAudioAllocRequest *request) = 0;
136     virtual mfxStatus Reset(mfxAudioParam *par) = 0;
137     virtual mfxStatus GetAudioParam(mfxAudioParam *par) = 0;
138 };
139 
140 //general purpose transform plugin interface, not a codec plugin
141 struct MFXGenericPlugin : MFXPlugin
142 {
143     virtual mfxStatus Init(mfxVideoParam *par) = 0;
144     virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out) = 0;
145     virtual mfxStatus Submit(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) = 0;
146 };
147 
148 //decoder plugins may only support this interface
149 struct MFXDecoderPlugin : MFXCodecPlugin
150 {
151     virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) = 0;
152     virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) = 0;
153     virtual mfxStatus DecodeFrameSubmit(mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out,  mfxThreadTask *task) = 0;
154 };
155 
156 //audio decoder plugins may only support this interface
157 struct MFXAudioDecoderPlugin : MFXAudioCodecPlugin
158 {
159     virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxAudioParam *par) = 0;
160 //    virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) = 0;
161     virtual mfxStatus DecodeFrameSubmit(mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task) = 0;
162 };
163 
164 //encoder plugins may only support this interface
165 struct MFXEncoderPlugin : MFXCodecPlugin
166 {
167     virtual mfxStatus EncodeFrameSubmit(mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task) = 0;
168 };
169 
170 //audio encoder plugins may only support this interface
171 struct MFXAudioEncoderPlugin : MFXAudioCodecPlugin
172 {
173     virtual mfxStatus EncodeFrameSubmit(mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task) = 0;
174 };
175 
176 //vpp plugins may only support this interface
177 struct MFXVPPPlugin : MFXCodecPlugin
178 {
179     virtual mfxStatus VPPFrameSubmit(mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_out, mfxExtVppAuxData *aux, mfxThreadTask *task) = 0;
180     virtual mfxStatus VPPFrameSubmitEx(mfxFrameSurface1 *in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) = 0;
181 };
182 
183 struct MFXEncPlugin : MFXCodecPlugin
184 {
185     virtual mfxStatus EncFrameSubmit(mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task) = 0;
186 };
187 
188 
189 
190 
191 class MFXCoreInterface
192 {
193 protected:
194     mfxCoreInterface m_core;
195 public:
196 
MFXCoreInterface()197     MFXCoreInterface()
198         : m_core() {
199     }
MFXCoreInterface(const mfxCoreInterface & pCore)200     MFXCoreInterface(const mfxCoreInterface & pCore)
201         : m_core(pCore) {
202     }
203 
MFXCoreInterface(const MFXCoreInterface & that)204     MFXCoreInterface(const MFXCoreInterface & that)
205         : m_core(that.m_core) {
206     }
207     MFXCoreInterface &operator = (const MFXCoreInterface & that)
208     {
209         m_core = that.m_core;
210         return *this;
211     }
IsCoreSet()212     bool IsCoreSet() {
213         return m_core.pthis != 0;
214     }
GetCoreParam(mfxCoreParam * par)215     mfxStatus GetCoreParam(mfxCoreParam *par) {
216         if (!IsCoreSet()) {
217             return MFX_ERR_NULL_PTR;
218         }
219         return m_core.GetCoreParam(m_core.pthis, par);
220     }
GetHandle(mfxHandleType type,mfxHDL * handle)221     mfxStatus GetHandle (mfxHandleType type, mfxHDL *handle) {
222         if (!IsCoreSet()) {
223             return MFX_ERR_NULL_PTR;
224         }
225         return m_core.GetHandle(m_core.pthis, type, handle);
226     }
IncreaseReference(mfxFrameData * fd)227     mfxStatus IncreaseReference (mfxFrameData *fd) {
228         if (!IsCoreSet()) {
229             return MFX_ERR_NULL_PTR;
230         }
231         return m_core.IncreaseReference(m_core.pthis, fd);
232     }
DecreaseReference(mfxFrameData * fd)233     mfxStatus DecreaseReference (mfxFrameData *fd) {
234         if (!IsCoreSet()) {
235             return MFX_ERR_NULL_PTR;
236         }
237         return m_core.DecreaseReference(m_core.pthis, fd);
238     }
CopyFrame(mfxFrameSurface1 * dst,mfxFrameSurface1 * src)239     mfxStatus CopyFrame (mfxFrameSurface1 *dst, mfxFrameSurface1 *src) {
240         if (!IsCoreSet()) {
241             return MFX_ERR_NULL_PTR;
242         }
243         return m_core.CopyFrame(m_core.pthis, dst, src);
244     }
CopyBuffer(mfxU8 * dst,mfxU32 size,mfxFrameSurface1 * src)245     mfxStatus CopyBuffer(mfxU8 *dst, mfxU32 size, mfxFrameSurface1 *src) {
246         if (!IsCoreSet()) {
247             return MFX_ERR_NULL_PTR;
248         }
249         return m_core.CopyBuffer(m_core.pthis, dst, size, src);
250     }
MapOpaqueSurface(mfxU32 num,mfxU32 type,mfxFrameSurface1 ** op_surf)251     mfxStatus MapOpaqueSurface(mfxU32  num, mfxU32  type, mfxFrameSurface1 **op_surf) {
252         if (!IsCoreSet()) {
253             return MFX_ERR_NULL_PTR;
254         }
255         return m_core.MapOpaqueSurface(m_core.pthis, num, type, op_surf);
256     }
UnmapOpaqueSurface(mfxU32 num,mfxU32 type,mfxFrameSurface1 ** op_surf)257     mfxStatus UnmapOpaqueSurface(mfxU32  num, mfxU32  type, mfxFrameSurface1 **op_surf) {
258         if (!IsCoreSet()) {
259             return MFX_ERR_NULL_PTR;
260         }
261         return m_core.UnmapOpaqueSurface(m_core.pthis, num, type, op_surf);
262     }
GetRealSurface(mfxFrameSurface1 * op_surf,mfxFrameSurface1 ** surf)263     mfxStatus GetRealSurface(mfxFrameSurface1 *op_surf, mfxFrameSurface1 **surf) {
264         if (!IsCoreSet()) {
265             return MFX_ERR_NULL_PTR;
266         }
267         return m_core.GetRealSurface(m_core.pthis, op_surf, surf);
268     }
GetOpaqueSurface(mfxFrameSurface1 * surf,mfxFrameSurface1 ** op_surf)269     mfxStatus GetOpaqueSurface(mfxFrameSurface1 *surf, mfxFrameSurface1 **op_surf) {
270         if (!IsCoreSet()) {
271             return MFX_ERR_NULL_PTR;
272         }
273         return m_core.GetOpaqueSurface(m_core.pthis, surf, op_surf);
274     }
CreateAccelerationDevice(mfxHandleType type,mfxHDL * handle)275     mfxStatus CreateAccelerationDevice(mfxHandleType type, mfxHDL *handle) {
276         if (!IsCoreSet()) {
277             return MFX_ERR_NULL_PTR;
278         }
279         return m_core.CreateAccelerationDevice(m_core.pthis, type, handle);
280     }
FrameAllocator()281     mfxFrameAllocator & FrameAllocator() {
282         return m_core.FrameAllocator;
283     }
GetFrameHandle(mfxFrameData * fd,mfxHDL * handle)284     mfxStatus GetFrameHandle(mfxFrameData *fd, mfxHDL *handle) {
285         if (!IsCoreSet()) {
286             return MFX_ERR_NULL_PTR;
287         }
288         return m_core.GetFrameHandle(m_core.pthis, fd, handle);
289     }
QueryPlatform(mfxPlatform * platform)290     mfxStatus QueryPlatform(mfxPlatform *platform) {
291         if (!IsCoreSet()) {
292             return MFX_ERR_NULL_PTR;
293         }
294         return m_core.QueryPlatform(m_core.pthis, platform);
295     }
296 } ;
297 
298 /* Class adapter between "C" structure mfxPlugin and C++ interface MFXPlugin */
299 
300 namespace detail
301 {
302     template <class T>
303     class MFXPluginAdapterBase
304     {
305     protected:
306         mfxPlugin m_mfxAPI;
307     public:
308         MFXPluginAdapterBase( T *plugin, mfxVideoCodecPlugin *pCodec = NULL)
m_mfxAPI()309             : m_mfxAPI()
310         {
311             SetupCallbacks(plugin, pCodec);
312         }
313 
MFXPluginAdapterBase(T * plugin,mfxAudioCodecPlugin * pCodec)314         MFXPluginAdapterBase( T *plugin, mfxAudioCodecPlugin *pCodec)
315             : m_mfxAPI()
316         {
317             SetupCallbacks(plugin, pCodec);
318         }
319 
mfxPlugin()320         operator  mfxPlugin () const {
321             return m_mfxAPI;
322         }
SetupCallbacks(T * plugin)323         void SetupCallbacks(T *plugin) {
324             m_mfxAPI.pthis = plugin;
325             m_mfxAPI.PluginInit = _PluginInit;
326             m_mfxAPI.PluginClose = _PluginClose;
327             m_mfxAPI.GetPluginParam = _GetPluginParam;
328             m_mfxAPI.Submit = 0;
329             m_mfxAPI.Execute = _Execute;
330             m_mfxAPI.FreeResources = _FreeResources;
331         }
332 
SetupCallbacks(T * plugin,mfxVideoCodecPlugin * pCodec)333         void SetupCallbacks( T *plugin, mfxVideoCodecPlugin *pCodec) {
334             SetupCallbacks(plugin);
335             m_mfxAPI.Video = pCodec;
336         }
337 
SetupCallbacks(T * plugin,mfxAudioCodecPlugin * pCodec)338         void SetupCallbacks( T *plugin, mfxAudioCodecPlugin *pCodec) {
339             SetupCallbacks(plugin);
340             m_mfxAPI.Audio = pCodec;
341         }
342     private:
343 
_PluginInit(mfxHDL pthis,mfxCoreInterface * core)344         static mfxStatus _PluginInit(mfxHDL pthis, mfxCoreInterface *core) {
345             return reinterpret_cast<T*>(pthis)->PluginInit(core);
346         }
_PluginClose(mfxHDL pthis)347         static mfxStatus _PluginClose(mfxHDL pthis) {
348             return reinterpret_cast<T*>(pthis)->PluginClose();
349         }
_GetPluginParam(mfxHDL pthis,mfxPluginParam * par)350         static mfxStatus _GetPluginParam(mfxHDL pthis, mfxPluginParam *par) {
351             return reinterpret_cast<T*>(pthis)->GetPluginParam(par);
352         }
_Execute(mfxHDL pthis,mfxThreadTask task,mfxU32 thread_id,mfxU32 call_count)353         static mfxStatus _Execute(mfxHDL pthis, mfxThreadTask task, mfxU32 thread_id, mfxU32 call_count) {
354             return reinterpret_cast<T*>(pthis)->Execute(task, thread_id, call_count);
355         }
_FreeResources(mfxHDL pthis,mfxThreadTask task,mfxStatus sts)356         static mfxStatus _FreeResources(mfxHDL pthis, mfxThreadTask task, mfxStatus sts) {
357             return reinterpret_cast<T*>(pthis)->FreeResources(task, sts);
358         }
359     };
360 
361     template<class T>
362     class MFXCodecPluginAdapterBase : public MFXPluginAdapterBase<T>
363     {
364     protected:
365         //stub to feed mediasdk plugin API
366         mfxVideoCodecPlugin   m_codecPlg;
367     public:
MFXCodecPluginAdapterBase(T * pCodecPlg)368         MFXCodecPluginAdapterBase(T * pCodecPlg)
369             : MFXPluginAdapterBase<T>(pCodecPlg, &m_codecPlg)
370             , m_codecPlg()
371         {
372             m_codecPlg.Query = _Query;
373             m_codecPlg.QueryIOSurf = _QueryIOSurf ;
374             m_codecPlg.Init = _Init;
375             m_codecPlg.Reset = _Reset;
376             m_codecPlg.Close = _Close;
377             m_codecPlg.GetVideoParam = _GetVideoParam;
378         }
MFXCodecPluginAdapterBase(const MFXCodecPluginAdapterBase<T> & that)379         MFXCodecPluginAdapterBase(const MFXCodecPluginAdapterBase<T> & that)
380             : MFXPluginAdapterBase<T>(reinterpret_cast<T*>(that.m_mfxAPI.pthis), &m_codecPlg)
381             , m_codecPlg() {
382             SetupCallbacks();
383         }
384         MFXCodecPluginAdapterBase<T>& operator = (const MFXCodecPluginAdapterBase<T> & that) {
385             MFXPluginAdapterBase<T> :: SetupCallbacks(reinterpret_cast<T*>(that.m_mfxAPI.pthis), &m_codecPlg);
386             SetupCallbacks();
387             return *this;
388         }
389 
390     private:
SetupCallbacks()391         void SetupCallbacks() {
392             m_codecPlg.Query = _Query;
393             m_codecPlg.QueryIOSurf = _QueryIOSurf ;
394             m_codecPlg.Init = _Init;
395             m_codecPlg.Reset = _Reset;
396             m_codecPlg.Close = _Close;
397             m_codecPlg.GetVideoParam = _GetVideoParam;
398         }
_Query(mfxHDL pthis,mfxVideoParam * in,mfxVideoParam * out)399         static mfxStatus _Query(mfxHDL pthis, mfxVideoParam *in, mfxVideoParam *out) {
400             return reinterpret_cast<T*>(pthis)->Query(in, out);
401         }
_QueryIOSurf(mfxHDL pthis,mfxVideoParam * par,mfxFrameAllocRequest * in,mfxFrameAllocRequest * out)402         static mfxStatus _QueryIOSurf(mfxHDL pthis, mfxVideoParam *par, mfxFrameAllocRequest *in,  mfxFrameAllocRequest *out){
403             return reinterpret_cast<T*>(pthis)->QueryIOSurf(par, in, out);
404         }
_Init(mfxHDL pthis,mfxVideoParam * par)405         static mfxStatus _Init(mfxHDL pthis, mfxVideoParam *par){
406             return reinterpret_cast<T*>(pthis)->Init(par);
407         }
_Reset(mfxHDL pthis,mfxVideoParam * par)408         static mfxStatus _Reset(mfxHDL pthis, mfxVideoParam *par){
409             return reinterpret_cast<T*>(pthis)->Reset(par);
410         }
_Close(mfxHDL pthis)411         static mfxStatus _Close(mfxHDL pthis) {
412             return reinterpret_cast<T*>(pthis)->Close();
413         }
_GetVideoParam(mfxHDL pthis,mfxVideoParam * par)414         static mfxStatus _GetVideoParam(mfxHDL pthis, mfxVideoParam *par) {
415             return reinterpret_cast<T*>(pthis)->GetVideoParam(par);
416         }
417     };
418 
419     template<class T>
420     class MFXAudioCodecPluginAdapterBase : public MFXPluginAdapterBase<T>
421     {
422     protected:
423         //stub to feed mediasdk plugin API
424         mfxAudioCodecPlugin   m_codecPlg;
425     public:
MFXAudioCodecPluginAdapterBase(T * pCodecPlg)426         MFXAudioCodecPluginAdapterBase(T * pCodecPlg)
427             : MFXPluginAdapterBase<T>(pCodecPlg, &m_codecPlg)
428             , m_codecPlg()
429         {
430             m_codecPlg.Query = _Query;
431             m_codecPlg.QueryIOSize = _QueryIOSize ;
432             m_codecPlg.Init = _Init;
433             m_codecPlg.Reset = _Reset;
434             m_codecPlg.Close = _Close;
435             m_codecPlg.GetAudioParam = _GetAudioParam;
436         }
MFXAudioCodecPluginAdapterBase(const MFXCodecPluginAdapterBase<T> & that)437         MFXAudioCodecPluginAdapterBase(const MFXCodecPluginAdapterBase<T> & that)
438             : MFXPluginAdapterBase<T>(reinterpret_cast<T*>(that.m_mfxAPI.pthis), &m_codecPlg)
439             , m_codecPlg() {
440             SetupCallbacks();
441         }
442         MFXAudioCodecPluginAdapterBase<T>& operator = (const MFXAudioCodecPluginAdapterBase<T> & that) {
443             MFXPluginAdapterBase<T> :: SetupCallbacks(reinterpret_cast<T*>(that.m_mfxAPI.pthis), &m_codecPlg);
444             SetupCallbacks();
445             return *this;
446         }
447 
448     private:
SetupCallbacks()449         void SetupCallbacks() {
450             m_codecPlg.Query = _Query;
451             m_codecPlg.QueryIOSize = _QueryIOSize;
452             m_codecPlg.Init = _Init;
453             m_codecPlg.Reset = _Reset;
454             m_codecPlg.Close = _Close;
455             m_codecPlg.GetAudioParam = _GetAudioParam;
456         }
_Query(mfxHDL pthis,mfxAudioParam * in,mfxAudioParam * out)457         static mfxStatus _Query(mfxHDL pthis, mfxAudioParam *in, mfxAudioParam *out) {
458             return reinterpret_cast<T*>(pthis)->Query(in, out);
459         }
_QueryIOSize(mfxHDL pthis,mfxAudioParam * par,mfxAudioAllocRequest * request)460         static mfxStatus _QueryIOSize(mfxHDL pthis, mfxAudioParam *par, mfxAudioAllocRequest *request){
461             return reinterpret_cast<T*>(pthis)->QueryIOSize(par, request);
462         }
_Init(mfxHDL pthis,mfxAudioParam * par)463         static mfxStatus _Init(mfxHDL pthis, mfxAudioParam *par){
464             return reinterpret_cast<T*>(pthis)->Init(par);
465         }
_Reset(mfxHDL pthis,mfxAudioParam * par)466         static mfxStatus _Reset(mfxHDL pthis, mfxAudioParam *par){
467             return reinterpret_cast<T*>(pthis)->Reset(par);
468         }
_Close(mfxHDL pthis)469         static mfxStatus _Close(mfxHDL pthis) {
470             return reinterpret_cast<T*>(pthis)->Close();
471         }
_GetAudioParam(mfxHDL pthis,mfxAudioParam * par)472         static mfxStatus _GetAudioParam(mfxHDL pthis, mfxAudioParam *par) {
473             return reinterpret_cast<T*>(pthis)->GetAudioParam(par);
474         }
475     };
476 
477     template <class T>
478     struct MFXPluginAdapterInternal{};
479     template<>
480     class MFXPluginAdapterInternal<MFXGenericPlugin> : public MFXPluginAdapterBase<MFXGenericPlugin>
481     {
482     public:
MFXPluginAdapterInternal(MFXGenericPlugin * pPlugin)483         MFXPluginAdapterInternal(MFXGenericPlugin *pPlugin)
484             : MFXPluginAdapterBase<MFXGenericPlugin>(pPlugin)
485         {
486             m_mfxAPI.Submit = _Submit;
487         }
MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)488         MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that )
489             : MFXPluginAdapterBase<MFXGenericPlugin>(that) {
490             m_mfxAPI.Submit = that._Submit;
491         }
492         MFXPluginAdapterInternal<MFXGenericPlugin>& operator = (const MFXPluginAdapterInternal<MFXGenericPlugin> & that) {
493             MFXPluginAdapterBase<MFXGenericPlugin>::operator=(that);
494             m_mfxAPI.Submit = that._Submit;
495             return *this;
496         }
497 
498     private:
_Submit(mfxHDL pthis,const mfxHDL * in,mfxU32 in_num,const mfxHDL * out,mfxU32 out_num,mfxThreadTask * task)499         static mfxStatus _Submit(mfxHDL pthis, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) {
500             return reinterpret_cast<MFXGenericPlugin*>(pthis)->Submit(in, in_num, out, out_num, task);
501         }
502     };
503 
504     template<>
505     class MFXPluginAdapterInternal<MFXDecoderPlugin> : public MFXCodecPluginAdapterBase<MFXDecoderPlugin>
506     {
507     public:
MFXPluginAdapterInternal(MFXDecoderPlugin * pPlugin)508         MFXPluginAdapterInternal(MFXDecoderPlugin *pPlugin)
509             : MFXCodecPluginAdapterBase<MFXDecoderPlugin>(pPlugin)
510         {
511             SetupCallbacks();
512         }
513 
MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)514         MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
515         : MFXCodecPluginAdapterBase<MFXDecoderPlugin>(that) {
516             SetupCallbacks();
517         }
518 
519         MFXPluginAdapterInternal<MFXDecoderPlugin>& operator = (const MFXPluginAdapterInternal<MFXDecoderPlugin> & that) {
520             MFXCodecPluginAdapterBase<MFXDecoderPlugin>::operator=(that);
521             SetupCallbacks();
522             return *this;
523         }
524 
525     private:
SetupCallbacks()526         void SetupCallbacks() {
527             m_codecPlg.DecodeHeader = _DecodeHeader;
528             m_codecPlg.GetPayload = _GetPayload;
529             m_codecPlg.DecodeFrameSubmit = _DecodeFrameSubmit;
530         }
_DecodeHeader(mfxHDL pthis,mfxBitstream * bs,mfxVideoParam * par)531         static mfxStatus _DecodeHeader(mfxHDL pthis, mfxBitstream *bs, mfxVideoParam *par) {
532             return reinterpret_cast<MFXDecoderPlugin*>(pthis)->DecodeHeader(bs, par);
533         }
_GetPayload(mfxHDL pthis,mfxU64 * ts,mfxPayload * payload)534         static mfxStatus _GetPayload(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload) {
535             return reinterpret_cast<MFXDecoderPlugin*>(pthis)->GetPayload(ts, payload);
536         }
_DecodeFrameSubmit(mfxHDL pthis,mfxBitstream * bs,mfxFrameSurface1 * surface_work,mfxFrameSurface1 ** surface_out,mfxThreadTask * task)537         static mfxStatus _DecodeFrameSubmit(mfxHDL pthis, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out,  mfxThreadTask *task) {
538             return reinterpret_cast<MFXDecoderPlugin*>(pthis)->DecodeFrameSubmit(bs, surface_work, surface_out, task);
539         }
540     };
541 
542     template<>
543     class MFXPluginAdapterInternal<MFXAudioDecoderPlugin> : public MFXAudioCodecPluginAdapterBase<MFXAudioDecoderPlugin>
544     {
545     public:
MFXPluginAdapterInternal(MFXAudioDecoderPlugin * pPlugin)546         MFXPluginAdapterInternal(MFXAudioDecoderPlugin *pPlugin)
547             : MFXAudioCodecPluginAdapterBase<MFXAudioDecoderPlugin>(pPlugin)
548         {
549             SetupCallbacks();
550         }
551 
MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)552         MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
553         : MFXAudioCodecPluginAdapterBase<MFXAudioDecoderPlugin>(that) {
554             SetupCallbacks();
555         }
556 
557         MFXPluginAdapterInternal<MFXAudioDecoderPlugin>& operator = (const MFXPluginAdapterInternal<MFXAudioDecoderPlugin> & that) {
558             MFXAudioCodecPluginAdapterBase<MFXAudioDecoderPlugin>::operator=(that);
559             SetupCallbacks();
560             return *this;
561         }
562 
563     private:
SetupCallbacks()564         void SetupCallbacks() {
565             m_codecPlg.DecodeHeader = _DecodeHeader;
566             m_codecPlg.DecodeFrameSubmit = _DecodeFrameSubmit;
567         }
_DecodeHeader(mfxHDL pthis,mfxBitstream * bs,mfxAudioParam * par)568         static mfxStatus _DecodeHeader(mfxHDL pthis, mfxBitstream *bs, mfxAudioParam *par) {
569             return reinterpret_cast<MFXAudioDecoderPlugin*>(pthis)->DecodeHeader(bs, par);
570         }
_DecodeFrameSubmit(mfxHDL pthis,mfxBitstream * in,mfxAudioFrame * out,mfxThreadTask * task)571         static mfxStatus _DecodeFrameSubmit(mfxHDL pthis, mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task) {
572             return reinterpret_cast<MFXAudioDecoderPlugin*>(pthis)->DecodeFrameSubmit(in, out, task);
573         }
574     };
575 
576     template<>
577     class MFXPluginAdapterInternal<MFXEncoderPlugin> : public MFXCodecPluginAdapterBase<MFXEncoderPlugin>
578     {
579     public:
MFXPluginAdapterInternal(MFXEncoderPlugin * pPlugin)580         MFXPluginAdapterInternal(MFXEncoderPlugin *pPlugin)
581             : MFXCodecPluginAdapterBase<MFXEncoderPlugin>(pPlugin)
582         {
583             m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit;
584         }
MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)585         MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
586             : MFXCodecPluginAdapterBase<MFXEncoderPlugin>(that) {
587             m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit;
588         }
589 
590         MFXPluginAdapterInternal<MFXEncoderPlugin>& operator = (const MFXPluginAdapterInternal<MFXEncoderPlugin> & that) {
591             MFXCodecPluginAdapterBase<MFXEncoderPlugin>::operator = (that);
592             m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit;
593             return *this;
594         }
595 
596     private:
_EncodeFrameSubmit(mfxHDL pthis,mfxEncodeCtrl * ctrl,mfxFrameSurface1 * surface,mfxBitstream * bs,mfxThreadTask * task)597         static mfxStatus _EncodeFrameSubmit(mfxHDL pthis, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task) {
598             return reinterpret_cast<MFXEncoderPlugin*>(pthis)->EncodeFrameSubmit(ctrl, surface, bs, task);
599         }
600     };
601 
602     template<>
603     class MFXPluginAdapterInternal<MFXAudioEncoderPlugin> : public MFXAudioCodecPluginAdapterBase<MFXAudioEncoderPlugin>
604     {
605     public:
MFXPluginAdapterInternal(MFXAudioEncoderPlugin * pPlugin)606         MFXPluginAdapterInternal(MFXAudioEncoderPlugin *pPlugin)
607             : MFXAudioCodecPluginAdapterBase<MFXAudioEncoderPlugin>(pPlugin)
608         {
609             SetupCallbacks();
610         }
611 
MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)612         MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
613         : MFXAudioCodecPluginAdapterBase<MFXAudioEncoderPlugin>(that) {
614             SetupCallbacks();
615         }
616 
617         MFXPluginAdapterInternal<MFXAudioEncoderPlugin>& operator = (const MFXPluginAdapterInternal<MFXAudioEncoderPlugin> & that) {
618             MFXAudioCodecPluginAdapterBase<MFXAudioEncoderPlugin>::operator=(that);
619             SetupCallbacks();
620             return *this;
621         }
622 
623     private:
SetupCallbacks()624         void SetupCallbacks() {
625             m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit;
626         }
_EncodeFrameSubmit(mfxHDL pthis,mfxAudioFrame * aFrame,mfxBitstream * out,mfxThreadTask * task)627         static mfxStatus _EncodeFrameSubmit(mfxHDL pthis, mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task) {
628             return reinterpret_cast<MFXAudioEncoderPlugin*>(pthis)->EncodeFrameSubmit(aFrame, out, task);
629         }
630     };
631 
632     template<>
633     class MFXPluginAdapterInternal<MFXEncPlugin> : public MFXCodecPluginAdapterBase<MFXEncPlugin>
634     {
635     public:
MFXPluginAdapterInternal(MFXEncPlugin * pPlugin)636         MFXPluginAdapterInternal(MFXEncPlugin *pPlugin)
637             : MFXCodecPluginAdapterBase<MFXEncPlugin>(pPlugin)
638         {
639             m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit;
640         }
MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)641         MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
642             : MFXCodecPluginAdapterBase<MFXEncPlugin>(that) {
643             m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit;
644         }
645 
646         MFXPluginAdapterInternal<MFXEncPlugin>& operator = (const MFXPluginAdapterInternal<MFXEncPlugin> & that) {
647             MFXCodecPluginAdapterBase<MFXEncPlugin>::operator = (that);
648             m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit;
649             return *this;
650         }
651 
652     private:
_ENCFrameSubmit(mfxHDL pthis,mfxENCInput * in,mfxENCOutput * out,mfxThreadTask * task)653         static mfxStatus _ENCFrameSubmit(mfxHDL pthis,mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task) {
654             return reinterpret_cast<MFXEncPlugin*>(pthis)->EncFrameSubmit(in, out, task);
655         }
656     };
657 
658 
659     template<>
660     class MFXPluginAdapterInternal<MFXVPPPlugin> : public MFXCodecPluginAdapterBase<MFXVPPPlugin>
661     {
662     public:
MFXPluginAdapterInternal(MFXVPPPlugin * pPlugin)663         MFXPluginAdapterInternal(MFXVPPPlugin *pPlugin)
664             : MFXCodecPluginAdapterBase<MFXVPPPlugin>(pPlugin)
665         {
666             SetupCallbacks();
667         }
MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)668         MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
669             : MFXCodecPluginAdapterBase<MFXVPPPlugin>(that) {
670             SetupCallbacks();
671         }
672 
673         MFXPluginAdapterInternal<MFXVPPPlugin>& operator = (const MFXPluginAdapterInternal<MFXVPPPlugin> & that) {
674             MFXCodecPluginAdapterBase<MFXVPPPlugin>::operator = (that);
675             SetupCallbacks();
676             return *this;
677         }
678 
679     private:
SetupCallbacks()680         void SetupCallbacks() {
681             m_codecPlg.VPPFrameSubmit = _VPPFrameSubmit;
682             m_codecPlg.VPPFrameSubmitEx = _VPPFrameSubmitEx;
683         }
_VPPFrameSubmit(mfxHDL pthis,mfxFrameSurface1 * surface_in,mfxFrameSurface1 * surface_out,mfxExtVppAuxData * aux,mfxThreadTask * task)684         static mfxStatus _VPPFrameSubmit(mfxHDL pthis, mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_out, mfxExtVppAuxData *aux, mfxThreadTask *task) {
685             return reinterpret_cast<MFXVPPPlugin*>(pthis)->VPPFrameSubmit(surface_in, surface_out, aux, task);
686         }
_VPPFrameSubmitEx(mfxHDL pthis,mfxFrameSurface1 * surface_in,mfxFrameSurface1 * surface_work,mfxFrameSurface1 ** surface_out,mfxThreadTask * task)687         static mfxStatus _VPPFrameSubmitEx(mfxHDL pthis, mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) {
688             return reinterpret_cast<MFXVPPPlugin*>(pthis)->VPPFrameSubmitEx(surface_in, surface_work, surface_out, task);
689         }
690     };
691 }
692 
693 /* adapter for particular plugin type*/
694 template<class T>
695 class MFXPluginAdapter
696 {
697 public:
698     detail::MFXPluginAdapterInternal<T> m_Adapter;
699 
mfxPlugin()700     operator  mfxPlugin () const {
701         return m_Adapter.operator mfxPlugin();
702     }
703 
704     MFXPluginAdapter(T* pPlugin = NULL)
m_Adapter(pPlugin)705         : m_Adapter(pPlugin)
706     {
707     }
708 };
709 
710 template<class T>
make_mfx_plugin_adapter(T * pPlugin)711 inline MFXPluginAdapter<T> make_mfx_plugin_adapter(T* pPlugin) {
712 
713     MFXPluginAdapter<T> adapt(pPlugin);
714     return adapt;
715 }
716 
717 #endif // __MFXPLUGINPLUSPLUS_H
718