/*############################################################################
  # Copyright (C) 2007 Intel Corporation
  #
  # SPDX-License-Identifier: MIT
  ############################################################################*/

#ifndef __MFXPLUGIN_H__
#define __MFXPLUGIN_H__
#include "mfxaudio.h"
#include "mfxdeprecated.h"
#include "vpl/mfxvideo.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

MFX_PACK_BEGIN_USUAL_STRUCT()
typedef struct {
    mfxU8 Data[16];
} mfxPluginUID;
MFX_PACK_END()

static const mfxPluginUID MFX_PLUGINID_HEVCD_SW      = { { 0x15,
                                                           0xdd,
                                                           0x93,
                                                           0x68,
                                                           0x25,
                                                           0xad,
                                                           0x47,
                                                           0x5e,
                                                           0xa3,
                                                           0x4e,
                                                           0x35,
                                                           0xf3,
                                                           0xf5,
                                                           0x42,
                                                           0x17,
                                                           0xa6 } };
static const mfxPluginUID MFX_PLUGINID_HEVCD_HW      = { { 0x33,
                                                           0xa6,
                                                           0x1c,
                                                           0x0b,
                                                           0x4c,
                                                           0x27,
                                                           0x45,
                                                           0x4c,
                                                           0xa8,
                                                           0xd8,
                                                           0x5d,
                                                           0xde,
                                                           0x75,
                                                           0x7c,
                                                           0x6f,
                                                           0x8e } };
static const mfxPluginUID MFX_PLUGINID_HEVCE_SW      = { { 0x2f,
                                                           0xca,
                                                           0x99,
                                                           0x74,
                                                           0x9f,
                                                           0xdb,
                                                           0x49,
                                                           0xae,
                                                           0xb1,
                                                           0x21,
                                                           0xa5,
                                                           0xb6,
                                                           0x3e,
                                                           0xf5,
                                                           0x68,
                                                           0xf7 } };
static const mfxPluginUID MFX_PLUGINID_HEVCE_GACC    = { { 0xe5,
                                                           0x40,
                                                           0x0a,
                                                           0x06,
                                                           0xc7,
                                                           0x4d,
                                                           0x41,
                                                           0xf5,
                                                           0xb1,
                                                           0x2d,
                                                           0x43,
                                                           0x0b,
                                                           0xba,
                                                           0xa2,
                                                           0x3d,
                                                           0x0b } };
static const mfxPluginUID MFX_PLUGINID_HEVCE_DP_GACC = { { 0x2b,
                                                           0xad,
                                                           0x6f,
                                                           0x9d,
                                                           0x77,
                                                           0x54,
                                                           0x41,
                                                           0x2d,
                                                           0xbf,
                                                           0x63,
                                                           0x03,
                                                           0xed,
                                                           0x4b,
                                                           0xb5,
                                                           0x09,
                                                           0x68 } };
static const mfxPluginUID MFX_PLUGINID_HEVCE_HW      = { { 0x6f,
                                                           0xad,
                                                           0xc7,
                                                           0x91,
                                                           0xa0,
                                                           0xc2,
                                                           0xeb,
                                                           0x47,
                                                           0x9a,
                                                           0xb6,
                                                           0xdc,
                                                           0xd5,
                                                           0xea,
                                                           0x9d,
                                                           0xa3,
                                                           0x47 } };
static const mfxPluginUID MFX_PLUGINID_VP8D_HW       = { { 0xf6,
                                                           0x22,
                                                           0x39,
                                                           0x4d,
                                                           0x8d,
                                                           0x87,
                                                           0x45,
                                                           0x2f,
                                                           0x87,
                                                           0x8c,
                                                           0x51,
                                                           0xf2,
                                                           0xfc,
                                                           0x9b,
                                                           0x41,
                                                           0x31 } };
static const mfxPluginUID MFX_PLUGINID_VP8E_HW       = { { 0xbf,
                                                           0xfc,
                                                           0x51,
                                                           0x8c,
                                                           0xde,
                                                           0x13,
                                                           0x4d,
                                                           0xf9,
                                                           0x8a,
                                                           0x96,
                                                           0xf4,
                                                           0xcf,
                                                           0x81,
                                                           0x6c,
                                                           0x0f,
                                                           0xac } };
static const mfxPluginUID MFX_PLUGINID_VP9E_HW       = { { 0xce,
                                                           0x44,
                                                           0xef,
                                                           0x6f,
                                                           0x1a,
                                                           0x6d,
                                                           0x22,
                                                           0x46,
                                                           0xb4,
                                                           0x12,
                                                           0xbb,
                                                           0x38,
                                                           0xd6,
                                                           0xe4,
                                                           0x51,
                                                           0x82 } };
static const mfxPluginUID MFX_PLUGINID_VP9D_HW       = { { 0xa9,
                                                           0x22,
                                                           0x39,
                                                           0x4d,
                                                           0x8d,
                                                           0x87,
                                                           0x45,
                                                           0x2f,
                                                           0x87,
                                                           0x8c,
                                                           0x51,
                                                           0xf2,
                                                           0xfc,
                                                           0x9b,
                                                           0x41,
                                                           0x31 } };
static const mfxPluginUID MFX_PLUGINID_CAMERA_HW     = { { 0x54,
                                                           0x54,
                                                           0x26,
                                                           0x16,
                                                           0x24,
                                                           0x33,
                                                           0x41,
                                                           0xe6,
                                                           0x93,
                                                           0xae,
                                                           0x89,
                                                           0x99,
                                                           0x42,
                                                           0xce,
                                                           0x73,
                                                           0x55 } };
static const mfxPluginUID MFX_PLUGINID_CAPTURE_HW    = { { 0x22,
                                                           0xd6,
                                                           0x2c,
                                                           0x07,
                                                           0xe6,
                                                           0x72,
                                                           0x40,
                                                           0x8f,
                                                           0xbb,
                                                           0x4c,
                                                           0xc2,
                                                           0x0e,
                                                           0xd7,
                                                           0xa0,
                                                           0x53,
                                                           0xe4 } };
static const mfxPluginUID MFX_PLUGINID_ITELECINE_HW  = { { 0xe7,
                                                           0x44,
                                                           0x75,
                                                           0x3a,
                                                           0xcd,
                                                           0x74,
                                                           0x40,
                                                           0x2e,
                                                           0x89,
                                                           0xa2,
                                                           0xee,
                                                           0x06,
                                                           0x35,
                                                           0x49,
                                                           0x61,
                                                           0x79 } };
static const mfxPluginUID MFX_PLUGINID_H264LA_HW     = { { 0x58,
                                                           0x8f,
                                                           0x11,
                                                           0x85,
                                                           0xd4,
                                                           0x7b,
                                                           0x42,
                                                           0x96,
                                                           0x8d,
                                                           0xea,
                                                           0x37,
                                                           0x7b,
                                                           0xb5,
                                                           0xd0,
                                                           0xdc,
                                                           0xb4 } };
static const mfxPluginUID MFX_PLUGINID_AACD          = { { 0xe9,
                                                           0x34,
                                                           0x67,
                                                           0x25,
                                                           0xac,
                                                           0x2f,
                                                           0x4c,
                                                           0x93,
                                                           0xaa,
                                                           0x58,
                                                           0x5c,
                                                           0x11,
                                                           0xc7,
                                                           0x08,
                                                           0x7c,
                                                           0xf4 } };
static const mfxPluginUID MFX_PLUGINID_AACE          = { { 0xb2,
                                                           0xa2,
                                                           0xa0,
                                                           0x5a,
                                                           0x4e,
                                                           0xac,
                                                           0x46,
                                                           0xbf,
                                                           0xa9,
                                                           0xde,
                                                           0x7e,
                                                           0x80,
                                                           0xc9,
                                                           0x8d,
                                                           0x2e,
                                                           0x18 } };
static const mfxPluginUID MFX_PLUGINID_HEVCE_FEI_HW  = { { 0x87,
                                                           0xe0,
                                                           0xe8,
                                                           0x02,
                                                           0x07,
                                                           0x37,
                                                           0x52,
                                                           0x40,
                                                           0x85,
                                                           0x25,
                                                           0x15,
                                                           0xcf,
                                                           0x4a,
                                                           0x5e,
                                                           0xdd,
                                                           0xe6 } };
#if (MFX_VERSION >= 1027)
static const mfxPluginUID MFX_PLUGINID_HEVC_FEI_ENCODE = { { 0x54,
                                                             0x18,
                                                             0xa7,
                                                             0x06,
                                                             0x66,
                                                             0xf9,
                                                             0x4d,
                                                             0x5c,
                                                             0xb4,
                                                             0xf7,
                                                             0xb1,
                                                             0xca,
                                                             0xee,
                                                             0x86,
                                                             0x33,
                                                             0x9b } };
#endif

typedef enum {
    MFX_PLUGINTYPE_VIDEO_GENERAL = 0,
    MFX_PLUGINTYPE_VIDEO_DECODE  = 1,
    MFX_PLUGINTYPE_VIDEO_ENCODE  = 2,
    MFX_PLUGINTYPE_VIDEO_VPP     = 3,
    MFX_PLUGINTYPE_VIDEO_ENC     = 4,
    MFX_PLUGINTYPE_AUDIO_DECODE  = 5,
    MFX_PLUGINTYPE_AUDIO_ENCODE  = 6
} mfxPluginType;

typedef enum { MFX_THREADPOLICY_SERIAL = 0, MFX_THREADPOLICY_PARALLEL = 1 } mfxThreadPolicy;

MFX_PACK_BEGIN_USUAL_STRUCT()
typedef struct mfxPluginParam {
    mfxU32 reserved[6];
    mfxU16 reserved1;
    mfxU16 PluginVersion;
    mfxVersion APIVersion;
    mfxPluginUID PluginUID;
    mfxU32 Type;
    mfxU32 CodecId;
    mfxThreadPolicy ThreadPolicy;
    mfxU32 MaxThreadNum;
} mfxPluginParam;
MFX_PACK_END()

MFX_PACK_BEGIN_USUAL_STRUCT()
typedef struct mfxCoreParam {
    mfxU32 reserved[13];
    mfxIMPL Impl;
    mfxVersion Version;
    mfxU32 NumWorkingThread;
} mfxCoreParam;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
typedef struct mfxCoreInterface {
    mfxHDL pthis;

    mfxHDL reserved1[2];
    mfxFrameAllocator FrameAllocator;
    //mfxBufferAllocator reserved3;

    mfxStatus(MFX_CDECL* GetCoreParam)(mfxHDL pthis, mfxCoreParam* par);
    mfxStatus(MFX_CDECL* GetHandle)(mfxHDL pthis, mfxHandleType type, mfxHDL* handle);
    mfxStatus(MFX_CDECL* IncreaseReference)(mfxHDL pthis, mfxFrameData* fd);
    mfxStatus(MFX_CDECL* DecreaseReference)(mfxHDL pthis, mfxFrameData* fd);
    mfxStatus(MFX_CDECL* CopyFrame)(mfxHDL pthis, mfxFrameSurface1* dst, mfxFrameSurface1* src);
    mfxStatus(MFX_CDECL* CopyBuffer)(mfxHDL pthis, mfxU8* dst, mfxU32 size, mfxFrameSurface1* src);

    mfxStatus(MFX_CDECL* MapOpaqueSurface)(mfxHDL pthis,
                                           mfxU32 num,
                                           mfxU32 type,
                                           mfxFrameSurface1** op_surf);
    mfxStatus(MFX_CDECL* UnmapOpaqueSurface)(mfxHDL pthis,
                                             mfxU32 num,
                                             mfxU32 type,
                                             mfxFrameSurface1** op_surf);

    mfxStatus(MFX_CDECL* GetRealSurface)(mfxHDL pthis,
                                         mfxFrameSurface1* op_surf,
                                         mfxFrameSurface1** surf);
    mfxStatus(MFX_CDECL* GetOpaqueSurface)(mfxHDL pthis,
                                           mfxFrameSurface1* surf,
                                           mfxFrameSurface1** op_surf);

    mfxStatus(MFX_CDECL* CreateAccelerationDevice)(mfxHDL pthis,
                                                   mfxHandleType type,
                                                   mfxHDL* handle);
    mfxStatus(MFX_CDECL* GetFrameHandle)(mfxHDL pthis, mfxFrameData* fd, mfxHDL* handle);
    mfxStatus(MFX_CDECL* QueryPlatform)(mfxHDL pthis, mfxPlatform* platform);

    mfxHDL reserved4[1];
} mfxCoreInterface;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
/* video codec plugin extension */
typedef struct _mfxENCInput mfxENCInput;
typedef struct _mfxENCOutput mfxENCOutput;
typedef struct mfxVideoCodecPlugin {
    mfxStatus(MFX_CDECL* Query)(mfxHDL pthis, mfxVideoParam* in, mfxVideoParam* out);
    mfxStatus(MFX_CDECL* QueryIOSurf)(mfxHDL pthis,
                                      mfxVideoParam* par,
                                      mfxFrameAllocRequest* in,
                                      mfxFrameAllocRequest* out);
    mfxStatus(MFX_CDECL* Init)(mfxHDL pthis, mfxVideoParam* par);
    mfxStatus(MFX_CDECL* Reset)(mfxHDL pthis, mfxVideoParam* par);
    mfxStatus(MFX_CDECL* Close)(mfxHDL pthis);
    mfxStatus(MFX_CDECL* GetVideoParam)(mfxHDL pthis, mfxVideoParam* par);

    mfxStatus(MFX_CDECL* EncodeFrameSubmit)(mfxHDL pthis,
                                            mfxEncodeCtrl* ctrl,
                                            mfxFrameSurface1* surface,
                                            mfxBitstream* bs,
                                            mfxThreadTask* task);

    mfxStatus(MFX_CDECL* DecodeHeader)(mfxHDL pthis, mfxBitstream* bs, mfxVideoParam* par);
    mfxStatus(MFX_CDECL* GetPayload)(mfxHDL pthis, mfxU64* ts, mfxPayload* payload);
    mfxStatus(MFX_CDECL* DecodeFrameSubmit)(mfxHDL pthis,
                                            mfxBitstream* bs,
                                            mfxFrameSurface1* surface_work,
                                            mfxFrameSurface1** surface_out,
                                            mfxThreadTask* task);

    mfxStatus(MFX_CDECL* VPPFrameSubmit)(mfxHDL pthis,
                                         mfxFrameSurface1* in,
                                         mfxFrameSurface1* out,
                                         mfxExtVppAuxData* aux,
                                         mfxThreadTask* task);
    mfxStatus(MFX_CDECL* VPPFrameSubmitEx)(mfxHDL pthis,
                                           mfxFrameSurface1* in,
                                           mfxFrameSurface1* surface_work,
                                           mfxFrameSurface1** surface_out,
                                           mfxThreadTask* task);

    mfxStatus(MFX_CDECL* ENCFrameSubmit)(mfxHDL pthis,
                                         mfxENCInput* in,
                                         mfxENCOutput* out,
                                         mfxThreadTask* task);

    mfxHDL reserved1[3];
    mfxU32 reserved2[8];
} mfxVideoCodecPlugin;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
typedef struct mfxAudioCodecPlugin {
    mfxStatus(MFX_CDECL* Query)(mfxHDL pthis, mfxAudioParam* in, mfxAudioParam* out);
    mfxStatus(MFX_CDECL* QueryIOSize)(mfxHDL pthis,
                                      mfxAudioParam* par,
                                      mfxAudioAllocRequest* request);
    mfxStatus(MFX_CDECL* Init)(mfxHDL pthis, mfxAudioParam* par);
    mfxStatus(MFX_CDECL* Reset)(mfxHDL pthis, mfxAudioParam* par);
    mfxStatus(MFX_CDECL* Close)(mfxHDL pthis);
    mfxStatus(MFX_CDECL* GetAudioParam)(mfxHDL pthis, mfxAudioParam* par);

    mfxStatus(MFX_CDECL* EncodeFrameSubmit)(mfxHDL pthis,
                                            mfxAudioFrame* aFrame,
                                            mfxBitstream* out,
                                            mfxThreadTask* task);

    mfxStatus(MFX_CDECL* DecodeHeader)(mfxHDL pthis, mfxBitstream* bs, mfxAudioParam* par);
    //    mfxStatus (MFX_CDECL *GetPayload)(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload);
    mfxStatus(MFX_CDECL* DecodeFrameSubmit)(mfxHDL pthis,
                                            mfxBitstream* in,
                                            mfxAudioFrame* out,
                                            mfxThreadTask* task);

    mfxHDL reserved1[6];
    mfxU32 reserved2[8];
} mfxAudioCodecPlugin;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
typedef struct mfxPlugin {
    mfxHDL pthis;

    mfxStatus(MFX_CDECL* PluginInit)(mfxHDL pthis, mfxCoreInterface* core);
    mfxStatus(MFX_CDECL* PluginClose)(mfxHDL pthis);

    mfxStatus(MFX_CDECL* GetPluginParam)(mfxHDL pthis, mfxPluginParam* par);

    mfxStatus(MFX_CDECL* Submit)(mfxHDL pthis,
                                 const mfxHDL* in,
                                 mfxU32 in_num,
                                 const mfxHDL* out,
                                 mfxU32 out_num,
                                 mfxThreadTask* task);
    mfxStatus(MFX_CDECL* Execute)(mfxHDL pthis, mfxThreadTask task, mfxU32 uid_p, mfxU32 uid_a);
    mfxStatus(MFX_CDECL* FreeResources)(mfxHDL pthis, mfxThreadTask task, mfxStatus sts);

    union {
        mfxVideoCodecPlugin* Video;
        mfxAudioCodecPlugin* Audio;
    };

    mfxHDL reserved[8];
} mfxPlugin;
MFX_PACK_END()

mfxStatus MFX_CDECL MFXVideoUSER_Register(mfxSession session, mfxU32 type, const mfxPlugin* par);
mfxStatus MFX_CDECL MFXVideoUSER_Unregister(mfxSession session, mfxU32 type);
mfxStatus MFX_CDECL MFXVideoUSER_GetPlugin(mfxSession session, mfxU32 type, mfxPlugin* par);
mfxStatus MFX_CDECL MFXVideoUSER_ProcessFrameAsync(mfxSession session,
                                                   const mfxHDL* in,
                                                   mfxU32 in_num,
                                                   const mfxHDL* out,
                                                   mfxU32 out_num,
                                                   mfxSyncPoint* syncp);

mfxStatus MFX_CDECL MFXVideoUSER_Load(mfxSession session, const mfxPluginUID* uid, mfxU32 version);
mfxStatus MFX_CDECL MFXVideoUSER_LoadByPath(mfxSession session,
                                            const mfxPluginUID* uid,
                                            mfxU32 version,
                                            const mfxChar* path,
                                            mfxU32 len);
mfxStatus MFX_CDECL MFXVideoUSER_UnLoad(mfxSession session, const mfxPluginUID* uid);

mfxStatus MFX_CDECL MFXAudioUSER_Register(mfxSession session, mfxU32 type, const mfxPlugin* par);
mfxStatus MFX_CDECL MFXAudioUSER_Unregister(mfxSession session, mfxU32 type);
mfxStatus MFX_CDECL MFXAudioUSER_ProcessFrameAsync(mfxSession session,
                                                   const mfxHDL* in,
                                                   mfxU32 in_num,
                                                   const mfxHDL* out,
                                                   mfxU32 out_num,
                                                   mfxSyncPoint* syncp);

mfxStatus MFX_CDECL MFXAudioUSER_Load(mfxSession session, const mfxPluginUID* uid, mfxU32 version);
mfxStatus MFX_CDECL MFXAudioUSER_UnLoad(mfxSession session, const mfxPluginUID* uid);

#ifdef __cplusplus
} // extern "C"
#endif /* __cplusplus */

#endif /* __MFXPLUGIN_H__ */
