// Copyright (c) 2017-2020 Intel Corporation // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __MFXPLUGINPLUSPLUS_H #define __MFXPLUGINPLUSPLUS_H #include "mfxplugin.h" // base class for MFXVideoUSER/MFXAudioUSER API class MFXBaseUSER { public: explicit MFXBaseUSER(mfxSession session = NULL) : m_session(session){} virtual ~MFXBaseUSER() {} virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) = 0; virtual mfxStatus Unregister(mfxU32 type) = 0; virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) = 0; protected: mfxSession m_session; }; //c++ wrapper over only 3 exposed functions from MFXVideoUSER module class MFXVideoUSER: public MFXBaseUSER { public: explicit MFXVideoUSER(mfxSession session = NULL) : MFXBaseUSER(session){} virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) { return MFXVideoUSER_Register(m_session, type, par); } virtual mfxStatus Unregister(mfxU32 type) { return MFXVideoUSER_Unregister(m_session, type); } virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) { return MFXVideoUSER_ProcessFrameAsync(m_session, in, in_num, out, out_num, syncp); } }; //c++ wrapper over only 3 exposed functions from MFXAudioUSER module class MFXAudioUSER: public MFXBaseUSER { public: explicit MFXAudioUSER(mfxSession session = NULL) : MFXBaseUSER(session){} virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) { return MFXAudioUSER_Register(m_session, type, par); } virtual mfxStatus Unregister(mfxU32 type) { return MFXAudioUSER_Unregister(m_session, type); } virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) { return MFXAudioUSER_ProcessFrameAsync(m_session, in, in_num, out, out_num, syncp); } }; //initialize mfxPlugin struct class MFXPluginParam { mfxPluginParam m_param; public: MFXPluginParam(mfxU32 CodecId, mfxU32 Type, mfxPluginUID uid, mfxThreadPolicy ThreadPolicy = MFX_THREADPOLICY_SERIAL, mfxU32 MaxThreadNum = 1) : m_param() { m_param.PluginUID = uid; m_param.Type = Type; m_param.CodecId = CodecId; m_param.MaxThreadNum = MaxThreadNum; m_param.ThreadPolicy = ThreadPolicy; } operator const mfxPluginParam& () const { return m_param; } operator mfxPluginParam& () { return m_param; } }; //common interface part for every plugin: decoder/encoder and generic struct MFXPlugin { virtual ~MFXPlugin() {}; //init function always required for any transform or codec plugins, for codec plugins it maps to callback from MediaSDK //for generic plugin application should call it //MediaSDK mfxPlugin API mapping virtual mfxStatus PluginInit(mfxCoreInterface *core) = 0; //release CoreInterface, and destroy plugin state, not destroy plugin instance virtual mfxStatus PluginClose() = 0; virtual mfxStatus GetPluginParam(mfxPluginParam *par) = 0; virtual mfxStatus Execute(mfxThreadTask task, mfxU32 uid_p, mfxU32 uid_a) = 0; virtual mfxStatus FreeResources(mfxThreadTask task, mfxStatus sts) = 0; //destroy plugin due to shared module distribution model plugin wont support virtual destructor virtual void Release() = 0; //release resources associated with current instance of plugin, but do not release CoreInterface related resource set in pluginInit virtual mfxStatus Close() = 0; //communication protocol between particular version of plugin and application virtual mfxStatus SetAuxParams(void* auxParam, int auxParamSize) = 0; }; //common extension interface that codec plugins should expose additionally to MFXPlugin struct MFXCodecPlugin : MFXPlugin { virtual mfxStatus Init(mfxVideoParam *par) = 0; virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out) = 0; virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) =0; virtual mfxStatus Reset(mfxVideoParam *par) = 0; virtual mfxStatus GetVideoParam(mfxVideoParam *par) = 0; }; //common extension interface that audio codec plugins should expose additionally to MFXPlugin struct MFXAudioCodecPlugin : MFXPlugin { virtual mfxStatus Init(mfxAudioParam *par) = 0; virtual mfxStatus Query(mfxAudioParam *in, mfxAudioParam *out) =0; virtual mfxStatus QueryIOSize(mfxAudioParam *par, mfxAudioAllocRequest *request) = 0; virtual mfxStatus Reset(mfxAudioParam *par) = 0; virtual mfxStatus GetAudioParam(mfxAudioParam *par) = 0; }; //general purpose transform plugin interface, not a codec plugin struct MFXGenericPlugin : MFXPlugin { virtual mfxStatus Init(mfxVideoParam *par) = 0; virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out) = 0; virtual mfxStatus Submit(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) = 0; }; //decoder plugins may only support this interface struct MFXDecoderPlugin : MFXCodecPlugin { virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) = 0; virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) = 0; virtual mfxStatus DecodeFrameSubmit(mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) = 0; }; //audio decoder plugins may only support this interface struct MFXAudioDecoderPlugin : MFXAudioCodecPlugin { virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxAudioParam *par) = 0; // virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) = 0; virtual mfxStatus DecodeFrameSubmit(mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task) = 0; }; //encoder plugins may only support this interface struct MFXEncoderPlugin : MFXCodecPlugin { virtual mfxStatus EncodeFrameSubmit(mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task) = 0; }; //audio encoder plugins may only support this interface struct MFXAudioEncoderPlugin : MFXAudioCodecPlugin { virtual mfxStatus EncodeFrameSubmit(mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task) = 0; }; //vpp plugins may only support this interface struct MFXVPPPlugin : MFXCodecPlugin { virtual mfxStatus VPPFrameSubmit(mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_out, mfxExtVppAuxData *aux, mfxThreadTask *task) = 0; virtual mfxStatus VPPFrameSubmitEx(mfxFrameSurface1 *in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) = 0; }; struct MFXEncPlugin : MFXCodecPlugin { virtual mfxStatus EncFrameSubmit(mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task) = 0; }; class MFXCoreInterface { protected: mfxCoreInterface m_core; public: MFXCoreInterface() : m_core() { } MFXCoreInterface(const mfxCoreInterface & pCore) : m_core(pCore) { } MFXCoreInterface(const MFXCoreInterface & that) : m_core(that.m_core) { } MFXCoreInterface &operator = (const MFXCoreInterface & that) { m_core = that.m_core; return *this; } bool IsCoreSet() { return m_core.pthis != 0; } mfxStatus GetCoreParam(mfxCoreParam *par) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.GetCoreParam(m_core.pthis, par); } mfxStatus GetHandle (mfxHandleType type, mfxHDL *handle) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.GetHandle(m_core.pthis, type, handle); } mfxStatus IncreaseReference (mfxFrameData *fd) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.IncreaseReference(m_core.pthis, fd); } mfxStatus DecreaseReference (mfxFrameData *fd) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.DecreaseReference(m_core.pthis, fd); } mfxStatus CopyFrame (mfxFrameSurface1 *dst, mfxFrameSurface1 *src) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.CopyFrame(m_core.pthis, dst, src); } mfxStatus CopyBuffer(mfxU8 *dst, mfxU32 size, mfxFrameSurface1 *src) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.CopyBuffer(m_core.pthis, dst, size, src); } mfxStatus MapOpaqueSurface(mfxU32 num, mfxU32 type, mfxFrameSurface1 **op_surf) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.MapOpaqueSurface(m_core.pthis, num, type, op_surf); } mfxStatus UnmapOpaqueSurface(mfxU32 num, mfxU32 type, mfxFrameSurface1 **op_surf) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.UnmapOpaqueSurface(m_core.pthis, num, type, op_surf); } mfxStatus GetRealSurface(mfxFrameSurface1 *op_surf, mfxFrameSurface1 **surf) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.GetRealSurface(m_core.pthis, op_surf, surf); } mfxStatus GetOpaqueSurface(mfxFrameSurface1 *surf, mfxFrameSurface1 **op_surf) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.GetOpaqueSurface(m_core.pthis, surf, op_surf); } mfxStatus CreateAccelerationDevice(mfxHandleType type, mfxHDL *handle) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.CreateAccelerationDevice(m_core.pthis, type, handle); } mfxFrameAllocator & FrameAllocator() { return m_core.FrameAllocator; } mfxStatus GetFrameHandle(mfxFrameData *fd, mfxHDL *handle) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.GetFrameHandle(m_core.pthis, fd, handle); } mfxStatus QueryPlatform(mfxPlatform *platform) { if (!IsCoreSet()) { return MFX_ERR_NULL_PTR; } return m_core.QueryPlatform(m_core.pthis, platform); } } ; /* Class adapter between "C" structure mfxPlugin and C++ interface MFXPlugin */ namespace detail { template class MFXPluginAdapterBase { protected: mfxPlugin m_mfxAPI; public: MFXPluginAdapterBase( T *plugin, mfxVideoCodecPlugin *pCodec = NULL) : m_mfxAPI() { SetupCallbacks(plugin, pCodec); } MFXPluginAdapterBase( T *plugin, mfxAudioCodecPlugin *pCodec) : m_mfxAPI() { SetupCallbacks(plugin, pCodec); } operator mfxPlugin () const { return m_mfxAPI; } void SetupCallbacks(T *plugin) { m_mfxAPI.pthis = plugin; m_mfxAPI.PluginInit = _PluginInit; m_mfxAPI.PluginClose = _PluginClose; m_mfxAPI.GetPluginParam = _GetPluginParam; m_mfxAPI.Submit = 0; m_mfxAPI.Execute = _Execute; m_mfxAPI.FreeResources = _FreeResources; } void SetupCallbacks( T *plugin, mfxVideoCodecPlugin *pCodec) { SetupCallbacks(plugin); m_mfxAPI.Video = pCodec; } void SetupCallbacks( T *plugin, mfxAudioCodecPlugin *pCodec) { SetupCallbacks(plugin); m_mfxAPI.Audio = pCodec; } private: static mfxStatus _PluginInit(mfxHDL pthis, mfxCoreInterface *core) { return reinterpret_cast(pthis)->PluginInit(core); } static mfxStatus _PluginClose(mfxHDL pthis) { return reinterpret_cast(pthis)->PluginClose(); } static mfxStatus _GetPluginParam(mfxHDL pthis, mfxPluginParam *par) { return reinterpret_cast(pthis)->GetPluginParam(par); } static mfxStatus _Execute(mfxHDL pthis, mfxThreadTask task, mfxU32 thread_id, mfxU32 call_count) { return reinterpret_cast(pthis)->Execute(task, thread_id, call_count); } static mfxStatus _FreeResources(mfxHDL pthis, mfxThreadTask task, mfxStatus sts) { return reinterpret_cast(pthis)->FreeResources(task, sts); } }; template class MFXCodecPluginAdapterBase : public MFXPluginAdapterBase { protected: //stub to feed mediasdk plugin API mfxVideoCodecPlugin m_codecPlg; public: MFXCodecPluginAdapterBase(T * pCodecPlg) : MFXPluginAdapterBase(pCodecPlg, &m_codecPlg) , m_codecPlg() { m_codecPlg.Query = _Query; m_codecPlg.QueryIOSurf = _QueryIOSurf ; m_codecPlg.Init = _Init; m_codecPlg.Reset = _Reset; m_codecPlg.Close = _Close; m_codecPlg.GetVideoParam = _GetVideoParam; } MFXCodecPluginAdapterBase(const MFXCodecPluginAdapterBase & that) : MFXPluginAdapterBase(reinterpret_cast(that.m_mfxAPI.pthis), &m_codecPlg) , m_codecPlg() { SetupCallbacks(); } MFXCodecPluginAdapterBase& operator = (const MFXCodecPluginAdapterBase & that) { MFXPluginAdapterBase :: SetupCallbacks(reinterpret_cast(that.m_mfxAPI.pthis), &m_codecPlg); SetupCallbacks(); return *this; } private: void SetupCallbacks() { m_codecPlg.Query = _Query; m_codecPlg.QueryIOSurf = _QueryIOSurf ; m_codecPlg.Init = _Init; m_codecPlg.Reset = _Reset; m_codecPlg.Close = _Close; m_codecPlg.GetVideoParam = _GetVideoParam; } static mfxStatus _Query(mfxHDL pthis, mfxVideoParam *in, mfxVideoParam *out) { return reinterpret_cast(pthis)->Query(in, out); } static mfxStatus _QueryIOSurf(mfxHDL pthis, mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out){ return reinterpret_cast(pthis)->QueryIOSurf(par, in, out); } static mfxStatus _Init(mfxHDL pthis, mfxVideoParam *par){ return reinterpret_cast(pthis)->Init(par); } static mfxStatus _Reset(mfxHDL pthis, mfxVideoParam *par){ return reinterpret_cast(pthis)->Reset(par); } static mfxStatus _Close(mfxHDL pthis) { return reinterpret_cast(pthis)->Close(); } static mfxStatus _GetVideoParam(mfxHDL pthis, mfxVideoParam *par) { return reinterpret_cast(pthis)->GetVideoParam(par); } }; template class MFXAudioCodecPluginAdapterBase : public MFXPluginAdapterBase { protected: //stub to feed mediasdk plugin API mfxAudioCodecPlugin m_codecPlg; public: MFXAudioCodecPluginAdapterBase(T * pCodecPlg) : MFXPluginAdapterBase(pCodecPlg, &m_codecPlg) , m_codecPlg() { m_codecPlg.Query = _Query; m_codecPlg.QueryIOSize = _QueryIOSize ; m_codecPlg.Init = _Init; m_codecPlg.Reset = _Reset; m_codecPlg.Close = _Close; m_codecPlg.GetAudioParam = _GetAudioParam; } MFXAudioCodecPluginAdapterBase(const MFXCodecPluginAdapterBase & that) : MFXPluginAdapterBase(reinterpret_cast(that.m_mfxAPI.pthis), &m_codecPlg) , m_codecPlg() { SetupCallbacks(); } MFXAudioCodecPluginAdapterBase& operator = (const MFXAudioCodecPluginAdapterBase & that) { MFXPluginAdapterBase :: SetupCallbacks(reinterpret_cast(that.m_mfxAPI.pthis), &m_codecPlg); SetupCallbacks(); return *this; } private: void SetupCallbacks() { m_codecPlg.Query = _Query; m_codecPlg.QueryIOSize = _QueryIOSize; m_codecPlg.Init = _Init; m_codecPlg.Reset = _Reset; m_codecPlg.Close = _Close; m_codecPlg.GetAudioParam = _GetAudioParam; } static mfxStatus _Query(mfxHDL pthis, mfxAudioParam *in, mfxAudioParam *out) { return reinterpret_cast(pthis)->Query(in, out); } static mfxStatus _QueryIOSize(mfxHDL pthis, mfxAudioParam *par, mfxAudioAllocRequest *request){ return reinterpret_cast(pthis)->QueryIOSize(par, request); } static mfxStatus _Init(mfxHDL pthis, mfxAudioParam *par){ return reinterpret_cast(pthis)->Init(par); } static mfxStatus _Reset(mfxHDL pthis, mfxAudioParam *par){ return reinterpret_cast(pthis)->Reset(par); } static mfxStatus _Close(mfxHDL pthis) { return reinterpret_cast(pthis)->Close(); } static mfxStatus _GetAudioParam(mfxHDL pthis, mfxAudioParam *par) { return reinterpret_cast(pthis)->GetAudioParam(par); } }; template struct MFXPluginAdapterInternal{}; template<> class MFXPluginAdapterInternal : public MFXPluginAdapterBase { public: MFXPluginAdapterInternal(MFXGenericPlugin *pPlugin) : MFXPluginAdapterBase(pPlugin) { m_mfxAPI.Submit = _Submit; } MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that ) : MFXPluginAdapterBase(that) { m_mfxAPI.Submit = that._Submit; } MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { MFXPluginAdapterBase::operator=(that); m_mfxAPI.Submit = that._Submit; return *this; } private: static mfxStatus _Submit(mfxHDL pthis, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) { return reinterpret_cast(pthis)->Submit(in, in_num, out, out_num, task); } }; template<> class MFXPluginAdapterInternal : public MFXCodecPluginAdapterBase { public: MFXPluginAdapterInternal(MFXDecoderPlugin *pPlugin) : MFXCodecPluginAdapterBase(pPlugin) { SetupCallbacks(); } MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) : MFXCodecPluginAdapterBase(that) { SetupCallbacks(); } MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { MFXCodecPluginAdapterBase::operator=(that); SetupCallbacks(); return *this; } private: void SetupCallbacks() { m_codecPlg.DecodeHeader = _DecodeHeader; m_codecPlg.GetPayload = _GetPayload; m_codecPlg.DecodeFrameSubmit = _DecodeFrameSubmit; } static mfxStatus _DecodeHeader(mfxHDL pthis, mfxBitstream *bs, mfxVideoParam *par) { return reinterpret_cast(pthis)->DecodeHeader(bs, par); } static mfxStatus _GetPayload(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload) { return reinterpret_cast(pthis)->GetPayload(ts, payload); } static mfxStatus _DecodeFrameSubmit(mfxHDL pthis, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) { return reinterpret_cast(pthis)->DecodeFrameSubmit(bs, surface_work, surface_out, task); } }; template<> class MFXPluginAdapterInternal : public MFXAudioCodecPluginAdapterBase { public: MFXPluginAdapterInternal(MFXAudioDecoderPlugin *pPlugin) : MFXAudioCodecPluginAdapterBase(pPlugin) { SetupCallbacks(); } MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) : MFXAudioCodecPluginAdapterBase(that) { SetupCallbacks(); } MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { MFXAudioCodecPluginAdapterBase::operator=(that); SetupCallbacks(); return *this; } private: void SetupCallbacks() { m_codecPlg.DecodeHeader = _DecodeHeader; m_codecPlg.DecodeFrameSubmit = _DecodeFrameSubmit; } static mfxStatus _DecodeHeader(mfxHDL pthis, mfxBitstream *bs, mfxAudioParam *par) { return reinterpret_cast(pthis)->DecodeHeader(bs, par); } static mfxStatus _DecodeFrameSubmit(mfxHDL pthis, mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task) { return reinterpret_cast(pthis)->DecodeFrameSubmit(in, out, task); } }; template<> class MFXPluginAdapterInternal : public MFXCodecPluginAdapterBase { public: MFXPluginAdapterInternal(MFXEncoderPlugin *pPlugin) : MFXCodecPluginAdapterBase(pPlugin) { m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit; } MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) : MFXCodecPluginAdapterBase(that) { m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit; } MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { MFXCodecPluginAdapterBase::operator = (that); m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit; return *this; } private: static mfxStatus _EncodeFrameSubmit(mfxHDL pthis, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task) { return reinterpret_cast(pthis)->EncodeFrameSubmit(ctrl, surface, bs, task); } }; template<> class MFXPluginAdapterInternal : public MFXAudioCodecPluginAdapterBase { public: MFXPluginAdapterInternal(MFXAudioEncoderPlugin *pPlugin) : MFXAudioCodecPluginAdapterBase(pPlugin) { SetupCallbacks(); } MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) : MFXAudioCodecPluginAdapterBase(that) { SetupCallbacks(); } MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { MFXAudioCodecPluginAdapterBase::operator=(that); SetupCallbacks(); return *this; } private: void SetupCallbacks() { m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit; } static mfxStatus _EncodeFrameSubmit(mfxHDL pthis, mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task) { return reinterpret_cast(pthis)->EncodeFrameSubmit(aFrame, out, task); } }; template<> class MFXPluginAdapterInternal : public MFXCodecPluginAdapterBase { public: MFXPluginAdapterInternal(MFXEncPlugin *pPlugin) : MFXCodecPluginAdapterBase(pPlugin) { m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit; } MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) : MFXCodecPluginAdapterBase(that) { m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit; } MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { MFXCodecPluginAdapterBase::operator = (that); m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit; return *this; } private: static mfxStatus _ENCFrameSubmit(mfxHDL pthis,mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task) { return reinterpret_cast(pthis)->EncFrameSubmit(in, out, task); } }; template<> class MFXPluginAdapterInternal : public MFXCodecPluginAdapterBase { public: MFXPluginAdapterInternal(MFXVPPPlugin *pPlugin) : MFXCodecPluginAdapterBase(pPlugin) { SetupCallbacks(); } MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) : MFXCodecPluginAdapterBase(that) { SetupCallbacks(); } MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { MFXCodecPluginAdapterBase::operator = (that); SetupCallbacks(); return *this; } private: void SetupCallbacks() { m_codecPlg.VPPFrameSubmit = _VPPFrameSubmit; m_codecPlg.VPPFrameSubmitEx = _VPPFrameSubmitEx; } static mfxStatus _VPPFrameSubmit(mfxHDL pthis, mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_out, mfxExtVppAuxData *aux, mfxThreadTask *task) { return reinterpret_cast(pthis)->VPPFrameSubmit(surface_in, surface_out, aux, task); } static mfxStatus _VPPFrameSubmitEx(mfxHDL pthis, mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) { return reinterpret_cast(pthis)->VPPFrameSubmitEx(surface_in, surface_work, surface_out, task); } }; } /* adapter for particular plugin type*/ template class MFXPluginAdapter { public: detail::MFXPluginAdapterInternal m_Adapter; operator mfxPlugin () const { return m_Adapter.operator mfxPlugin(); } MFXPluginAdapter(T* pPlugin = NULL) : m_Adapter(pPlugin) { } }; template inline MFXPluginAdapter make_mfx_plugin_adapter(T* pPlugin) { MFXPluginAdapter adapt(pPlugin); return adapt; } #endif // __MFXPLUGINPLUSPLUS_H