// Copyright (c) 2018-2019 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 __MFXFEIHEVC_H__
#define __MFXFEIHEVC_H__
#include "mfxcommon.h"

#ifdef __cplusplus
extern "C"
{
#endif

#if (MFX_VERSION >= 1027)

MFX_PACK_BEGIN_USUAL_STRUCT()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer Header;

    mfxU16  SearchPath;
    mfxU16  LenSP;
    mfxU16  RefWidth;
    mfxU16  RefHeight;
    mfxU16  SearchWindow;

    mfxU16  NumMvPredictors[2]; /* 0 for L0 and 1 for L1 */
    mfxU16  MultiPred[2];       /* 0 for L0 and 1 for L1 */

    mfxU16  SubPelMode;
    mfxU16  AdaptiveSearch;
    mfxU16  MVPredictor;

    mfxU16  PerCuQp;
    mfxU16  PerCtuInput;
    mfxU16  ForceCtuSplit;
    mfxU16  NumFramePartitions;
    mfxU16  FastIntraMode;

    mfxU16  reserved0[107];
} mfxExtFeiHevcEncFrameCtrl;
MFX_PACK_END()

MFX_PACK_BEGIN_USUAL_STRUCT()
MFX_DEPRECATED typedef struct {
    struct {
        mfxU8   RefL0 : 4;
        mfxU8   RefL1 : 4;
    } RefIdx[4]; /* index is predictor number */

    mfxU32     BlockSize : 2;
    mfxU32     reserved0 : 30;

    mfxI16Pair MV[4][2]; /* first index is predictor number, second is 0 for L0 and 1 for L1 */
} mfxFeiHevcEncMVPredictors;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer  Header;
    mfxU32        VaBufferID;
    mfxU32        Pitch;
    mfxU32        Height;
    mfxU16        reserved0[54];

    mfxFeiHevcEncMVPredictors *Data;
} mfxExtFeiHevcEncMVPredictors;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer  Header;
    mfxU32        VaBufferID;
    mfxU32        Pitch;
    mfxU32        Height;
    mfxU16        reserved[6];

    mfxU8    *Data;
} mfxExtFeiHevcEncQP;
MFX_PACK_END()

MFX_PACK_BEGIN_USUAL_STRUCT()
MFX_DEPRECATED typedef struct {
    mfxU32  ForceToIntra    : 1;
    mfxU32  ForceToInter    : 1;
    mfxU32  reserved0       : 30;

    mfxU32  reserved1[3];
} mfxFeiHevcEncCtuCtrl;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer Header;
    mfxU32  VaBufferID;
    mfxU32  Pitch;
    mfxU32  Height;
    mfxU16  reserved0[54];

    mfxFeiHevcEncCtuCtrl *Data;
} mfxExtFeiHevcEncCtuCtrl;
MFX_PACK_END()

MFX_PACK_BEGIN_USUAL_STRUCT()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer    Header;
    mfxU32      MaxFrameSize; /* in bytes */
    mfxU32      NumPasses;    /* up to 8 */
    mfxU16      reserved[8];
    mfxU8       DeltaQP[8];   /* list of delta QPs, only positive values */
} mfxExtFeiHevcRepackCtrl;
MFX_PACK_END()

MFX_PACK_BEGIN_USUAL_STRUCT()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer    Header;
    mfxU32          NumPasses;
    mfxU16          reserved[58];
} mfxExtFeiHevcRepackStat;
MFX_PACK_END()

#if MFX_VERSION >= MFX_VERSION_NEXT
MFX_PACK_BEGIN_USUAL_STRUCT()
MFX_DEPRECATED typedef struct  {
    /* DWORD 0 */
    mfxU32    reserved0;

    /* DWORD 1 */
    mfxU32    SplitLevel2Part0       : 4;
    mfxU32    SplitLevel2Part1       : 4;
    mfxU32    SplitLevel2Part2       : 4;
    mfxU32    SplitLevel2Part3       : 4;
    mfxU32    SplitLevel1            : 4;
    mfxU32    SplitLevel0            : 1;
    mfxU32    reserved10             : 3;
    mfxU32    CuCountMinus1          : 6;
    mfxU32    LastCtuOfTileFlag      : 1;
    mfxU32    LastCtuOfSliceFlag     : 1;


    /* DWORD 2 */
    mfxU32    CtuAddrX               : 16;
    mfxU32    CtuAddrY               : 16;

    /* DWORD 3 */
    mfxU32    reserved3;
} mfxFeiHevcPakCtuRecordV0;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer  Header;
    mfxU32        VaBufferID;
    mfxU32        Pitch;
    mfxU32        Height;
    mfxU16        reserved0[54];

    mfxFeiHevcPakCtuRecordV0 *Data;
} mfxExtFeiHevcPakCtuRecordV0;
MFX_PACK_END()

MFX_PACK_BEGIN_USUAL_STRUCT()
MFX_DEPRECATED typedef struct  {
    /* DWORD 0 */
    mfxU32    CuSize               : 2;
    mfxU32    PredMode             : 1;
    mfxU32    TransquantBypass     : 1;
    mfxU32    PartMode             : 3;
    mfxU32    IpcmEnable           : 1;
    mfxU32    IntraChromaMode      : 3;
    mfxU32    ZeroOutCoeffs        : 1;
    mfxU32    reserved00           : 4;
    mfxU32    Qp                   : 7;
    mfxU32    QpSign               : 1;
    mfxU32    InterpredIdc         : 8;


    /* DWORD 1 */
    mfxU32    IntraMode0           : 6;
    mfxU32    reserved10           : 2;
    mfxU32    IntraMode1           : 6;
    mfxU32    reserved11           : 2;
    mfxU32    IntraMode2           : 6;
    mfxU32    reserved12           : 2;
    mfxU32    IntraMode3           : 6;
    mfxU32    reserved13           : 2;


    /* DWORD 2-9 */
    struct {
        mfxI16 x[4];
        mfxI16 y[4];
    } MVs[2]; /* 0-L0, 1-L1 */


    /* DWORD 10 */
    struct{
        mfxU16   Ref0 : 4;
        mfxU16   Ref1 : 4;
        mfxU16   Ref2 : 4;
        mfxU16   Ref3 : 4;
    } RefIdx[2]; /* 0-L0, 1-L1 */


    /* DWORD 11 */
    mfxU32    TuSize;


    /* DWORD 12 */
    mfxU32    TransformSkipY       : 16;
    mfxU32    reserved120          : 12;
    mfxU32    TuCountM1            : 4;


    /* DWORD 13 */
    mfxU32    TransformSkipU       : 16;
    mfxU32    TransformSkipV       : 16;
} mfxFeiHevcPakCuRecordV0;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer  Header;
    mfxU32        VaBufferID;
    mfxU32        Pitch;
    mfxU32        Height;
    mfxU16        reserved0[54];

    mfxFeiHevcPakCuRecordV0 *Data;
} mfxExtFeiHevcPakCuRecordV0;
MFX_PACK_END()

MFX_PACK_BEGIN_USUAL_STRUCT()
MFX_DEPRECATED typedef struct {
    mfxU32        BestDistortion;
    mfxU32        ColocatedCtuDistortion;
} mfxFeiHevcDistortionCtu;
MFX_PACK_END()

MFX_PACK_BEGIN_STRUCT_W_PTR()
MFX_DEPRECATED typedef struct {
    mfxExtBuffer  Header;
    mfxU32        VaBufferID;
    mfxU32        Pitch;
    mfxU32        Height;
    mfxU16        reserved[6];

    mfxFeiHevcDistortionCtu *Data;
} mfxExtFeiHevcDistortion;
MFX_PACK_END()
#endif


enum {
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_ENC_CTRL)       = MFX_MAKEFOURCC('F','H','C','T'),
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_ENC_MV_PRED)    = MFX_MAKEFOURCC('F','H','P','D'),
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_ENC_QP)         = MFX_MAKEFOURCC('F','H','Q','P'),
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_ENC_CTU_CTRL)   = MFX_MAKEFOURCC('F','H','E','C'),
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_REPACK_CTRL)    = MFX_MAKEFOURCC('F','H','R','P'),
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_REPACK_STAT)    = MFX_MAKEFOURCC('F','H','R','S'),

#if MFX_VERSION >= MFX_VERSION_NEXT
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_PAK_CTU_REC)    = MFX_MAKEFOURCC('F','H','T','B'),
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_PAK_CU_REC)     = MFX_MAKEFOURCC('F','H','C','U'),
    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_HEVCFEI_ENC_DIST)       = MFX_MAKEFOURCC('F','H','D','S')
#endif
};

MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_ENC_CTRL);
MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_ENC_MV_PRED);
MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_ENC_QP);
MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_ENC_CTU_CTRL);
MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_REPACK_CTRL);
MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_REPACK_STAT);

#if MFX_VERSION >= MFX_VERSION_NEXT
    MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_PAK_CTU_REC);
    MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_PAK_CU_REC);
    MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(MFX_EXTBUFF_HEVCFEI_ENC_DIST);
#endif

#endif // MFX_VERSION

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


#endif // __MFXFEIHEVC_H__
