/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*
*
* $Author: dtvbm11 $
* $Modtime: $
* $Revision: #1 $
*
*/

// *********************************************************************
// Memo
// *********************************************************************
/*
*/

#ifndef _VDEC_MOD_H_
#define _VDEC_MOD_H_

#include <x_rm.h>

#include "openmaxil_ioctl.h"
//fix89 #include "drv_vdec.h"
#include "drv_common.h"
#include "omx_vdec_vconv.h"

#define VDecOMX_OK                0
#define VDecOMX_ERR            (-1)
#define VDO_OMX_INV_PTS         ((UINT64)(-1))

#define VDO_COMP_MAX  1
#define VDO_INPUT_BUF_MAX  10
#define VDO_OUTPUT_BUF_MAX 10

typedef enum {
    VOMX_STOPPING_NONE,
    VOMX_STOPPING_VCONV,
    //VOMX_STOPPING_VDEC,
    VOMX_STOPPING_VPUSH,
    VOMX_STOPPING_MAX,
} VOMX_STOPPING_STATUS_T;

typedef enum {
    VOMX_FLUSHING_NONE,
    VOMX_FLUSHING_VCONV,
    VOMX_FLUSHING_VPUSH,
    VOMX_FLUSHING_MAX,
} VOMX_FLUSHING_STATUS_T;

typedef struct
{
   UINT32 u4CurDrmIndex;
   UINT32 u4CurUnitUnMovedSize;
   BOOL   fgUpDated;
   OMX_IMTK_ENC_INBAND_CMD_T rInbandCmd;
}VOMX_ENCRYPTDATA_INFO;

typedef struct _VDO_OMX_HANDLE_T VDO_OMX_HANDLE_T;

typedef struct {
    VDO_OMX_HANDLE_T    *pOwner;
    HANDLE_T             hBuffer; // handle for below buffer
    void                *pBufSA;
    UINT32               u4BufSize; // althrough buffer size is included in below header, keep this for error detection
    HANDLE_T             hHeader; // handle for below structure
    UINT32               u4FilledLen; // used on empty, keep this althrough duplicated
    UINT32               u4Offset; // used on empty, keep this althrough duplicated
    OMX_BUFFERHEADERTYPE rHeader; // client will read/write this area
    OMX_TICKS            nTimeStamp;
    UINT32               u4Reserved; // for error detection
}VDO_OMX_BUFFER_T;

struct _VDO_OMX_HANDLE_T
	{
    HANDLE_T       h_handle;
    BOOL              fgUsed;
    BOOL              fgEmptying;
    BOOL              fgFilling;
    BOOL              fgStopVConv;
    BOOL              fgStoppingVPush;
    BOOL              fgStoppingVConv;
    BOOL              fgStateTransing;
//    BOOL              fgInPortEnabled;
//    BOOL              fgOutPortEnabled;
//    BOOL              fgInPortTransing;
//    BOOL              fgOutPortTransing;
    BOOL              fgGotEOS;
    BOOL              fgSentEOS;
	BOOL              fgAppend;
	BOOL              fgCodecData;
	BOOL              fgEncrypt;
    UINT64            u8TimeStamp;
    UINT64			  u8TimeStampBase;
    UINT32            pid;
//	    HANDLE_T          hMainTask;
//	    HANDLE_T          hCommandQ;
    UINT32            u4EmptySize;
    UINT32            u4EmptyCounter;
    UINT32            u4EmptyWritePos;
    UINT32            u4EmptyReadPos;
    UINT32            u4FillCounter;
    UINT32            u4FillWritePos;
    UINT32            u4FillReadPos;
    OMX_TICKS         nOutputDelay;
    VDO_OMX_BUFFER_T *pEmptyQ[VDO_INPUT_BUF_MAX]; // always left aligned, -> 11OO0000
    VDO_OMX_BUFFER_T *pFillQ[VDO_OUTPUT_BUF_MAX];
    VDO_OMX_BUFFER_T  InputBufPool[VDO_INPUT_BUF_MAX];
    VDO_OMX_BUFFER_T  OutputBufPool[VDO_OUTPUT_BUF_MAX];
    OMX_COLOR_FORMATTYPE eColorFormatIndex0;
    VCodeC     eCodecType;
    OMX_STATETYPE     eState;
    OMX_STATETYPE     eStateTo;
    VOMX_STOPPING_STATUS_T   eStopStatus;
    VOMX_FLUSHING_STATUS_T   eFlushStatus;
    OMX_PTR           pAppData;
    MTVDEC_PFN_OMX_IL_CB  pEventHandler;
    MTVDEC_PFN_OMX_IL_CB  pEmptyBufferDone;
    MTVDEC_PFN_OMX_IL_CB  pFillBufferDone;
    void             *pFifoPntr;  // VFIFO SA for decoder
    UINT32            u4FifoSize; // VFIFO length for decoder
    void             *pFifoWptr;  // VFIFO Wptr for decoder
    BOOL		  fgFlush[2]; // input 0, output 1
    VOID       	*pVdecPush;	
	UCHAR     	 ucVdecId;
    VOMX_ENCRYPTDATA_INFO rEncryptDataInfo;
//		HANDLE_T hTaskExitMutex;
    OMX_BUFFERHEADERTYPE rCbHeader; //for jpeg thumbnail callback
};

typedef enum {
    VDO_OMX_CMD_SET_STATE,
    VDO_OMX_CMD_EMPTY_BUFFER,
    VDO_OMX_CMD_FILL_BUFFER,
    VDO_OMX_CMD_FLUSH,
    VDO_OMX_CMD_PORT_ENABLE,
    VDO_OMX_CMD_PORT_DISABLE,
    VDO_OMX_CMD_BUFFER_ALLOCATED,
    VDO_OMX_CMD_BUFFER_FREED,
    VDO_OMX_CMD_TERMINATE,
    VDO_OMX_CMD_MAX = 0x7FFFFFFF,
} VDO_OMX_CMD_T;

typedef struct {
    VDO_OMX_HANDLE_T *pHandle;
    VDO_OMX_CMD_T     eCmd;
    OMX_STATETYPE     eStateTo; // for VDO_OMX_CMD_SET_STATE
    HANDLE_T          hHeader;  // for VDO_OMX_CMD_EMPTY_BUFFER & VDO_OMX_CMD_FILL_BUFFER
    BOOL              fgInput;  // for VDO_OMX_CMD_FLUSH
    BOOL              fgOutput; // for VDO_OMX_CMD_FLUSH
} VDO_OMX_MSG_T;

typedef struct
{
    OMX_COMMAND	rOMXVDECCMD;
//    OMX_COMMAND_SEND rOMXVDECCMDSent;
    OMX_STATETYPE ePrevStateType;
} OMX_CMD_VDEC_T;

typedef struct
{
    UINT32 nPorts;             /**< The number of ports for this component */
    UINT32 nStartPortNumber;   /** first port number for this type of port */
}VDEC_PORT_PARAM_T;

typedef struct
{
    UINT32 nBufferCountActual;    /**< The actual number of buffers allocated on this port */
    UINT32 nBufferCountMin;       /**< The minimum number of buffers this port requires */
    UINT32 nBufferSize;           /**< Size, in bytes, for buffers to be used for this channel */
    UINT32 nFrameWidth;
    UINT32 nFrameHeight;
    UINT32 nStride;
}VDEC_PORT_DEFINITION_T;

typedef enum
{
OMX_EVENT_HANDLER=0,
OMX_EMPTY_BUFF_DONE,
OMX_FILL_BUFF_DONE,	
}OMX_VDEC_CB_COND_T;

typedef struct _OMX_VDEC_CB_DATA
{
    OMX_VDEC_CB_COND_T      e_nfy_cond;
    UINT32              ui4_data_1;
    UINT32              ui4_data_2;
}OMX_VDEC_CB_DATA;

typedef struct
{
OMX_CMD_VDEC_T rOMXVDECCMDALL;
VDEC_PORT_PARAM_T rPortParamType;
VDEC_PORT_DEFINITION_T rPortDefinitionPara;
}VDEC_OMX_INFO_T;



/* data passed with VDEC_NFY_FILL_BUF */
typedef struct
{
    UINT32          u4DataAdd;        
    UINT32          u4DataLen;   
    BOOL            fgFileEnd;
} VDEC_FILL_BUF_T;

extern VDO_OMX_HANDLE_T _prVDOOmxHandle[2]; // currently only support single instance

//	INT32 i4VDOOmxTaskSendCommand(VDO_OMX_HANDLE_T *pHandle, VDO_OMX_MSG_T *prMsg);
//	INT32 i4VDOOmxTaskDestroy(VDO_OMX_HANDLE_T *pHandle);
//	INT32 i4VDOOmxTaskCreate(VDO_OMX_HANDLE_T *pHandle);

INT32 i4VDOOmxTaskDestroy(void);
INT32 i4VDOOmxTaskCreate(void);
INT32 i4VDOOmxTaskSendCommand(VDO_OMX_MSG_T *prMsg);

void vVDOOmxBufferInit(void);
void vVDOOmxBufferUninit(void);

//	extern INT32 i4VDOOmxTaskSemInit(void);
//	extern INT32 i4VDOOmxTaskSemUninit(void);
//	extern INT32 i4VDOOmxTaskLockSem(void);
//	extern INT32 i4VDOOmxTaskUnlockSem(void);

//callback use
extern INT32 i4VDOOmxCompNotifyFillDone(VDO_OMX_HANDLE_T *pHandle, VDO_OMX_BUFFER_T *pBufFilled);
extern INT32 i4VDOOmxCompNotifyEvent(VDO_OMX_HANDLE_T *pHandle, PARAMETER_OMX_CB_EVENTHANDLER *pEventInfo);
extern INT32 i4VDOOmxCompNotifyEmptyDone(VDO_OMX_HANDLE_T *pHandle, VDO_OMX_BUFFER_T *pBufEmptied);

// ioctl use
INT32 i4VDOOmxCompInit(void);
INT32 i4VDOOmxCompUninit(void);

INT32 i4VDOOmxCompGetHandle(PARAMETER_OMX_GETHANDLE *prUArg, PARAMETER_OMX_CB *prOmxCb);
INT32 i4VDOOmxCompFreeHandle(PARAMETER_OMX_FREEHANDLE *prUArg);
INT32 i4VDOOmxCompAllocateBuffer(PARAMETER_OMX_ALLOCATEBUFFER *prUArg);
INT32 i4VDOOmxCompFreeBuffer(PARAMETER_OMX_FREEBUFFER *prUArg);
INT32 i4VDOOmxCompEmptyBuffer(PARAMETER_OMX_EMPTYTHISBUFFER *prUArg);
INT32 i4VDOOmxCompFillBuffer(PARAMETER_OMX_FILLTHISBUFFER *prUArg);
INT32 i4VDOOmxCompGetState(PARAMETER_OMX_GETSTATE *prUArg);
INT32 i4VDOOmxCompGetParamVideoInit(PARAMETER_OMX_PORT_PARAM_TYPE *prUArg);
INT32 i4VDOOmxCompParamPortDef(PARAMETER_OMX_PARAM_PORTDEFINITIONTYPE *prUArg);
INT32 i4VDOOmxCompSetState(VDO_OMX_HANDLE_T *pHandle, OMX_STATETYPE omxStateTo);
INT32 i4VDOOmxCompFlushAsync(PARAMETER_OMX_COMMAND_PORT *prUArg);
INT32 i4VDOOmxCompSetStateAsync(PARAMETER_OMX_COMMAND_STATESET *prUArg);
INT32 i4VDOOmxCompPortDisable(VDO_OMX_HANDLE_T *pHandle, BOOL fgInput, BOOL fgOutput);
INT32 i4VDOOmxCompPortDisableAsync(PARAMETER_OMX_COMMAND_PORT *prUArg);
INT32 i4VDOOmxCompPortEnable(VDO_OMX_HANDLE_T *pHandle, BOOL fgInput, BOOL fgOutput);
INT32 i4VDOOmxCompPortEnableAsync(PARAMETER_OMX_COMMAND_PORT *prUArg);
INT32 i4VDOOmxCompParamVideoProfileLevelQuerySupported(PARAMETER_OMX_VIDEO_PARAM_PROFILELEVELTYPE *prUArg);
INT32 i4VDOOmxCompParamVideoAvc(PARAMETER_OMX_VIDEO_PARAM_AVC *prUArg);
INT32 i4VDOOmxCompParamVideoRv(PARAMETER_OMX_VIDEO_PARAM_RV *prUArg);
INT32 i4VDOOmxCompParamVideoWmv(PARAMETER_OMX_VIDEO_PARAM_WMV *prUArg);
INT32 i4VDOOmxCompParamVideoPortFmt(PARAMETER_OMX_VIDEO_PARAM_PORTFORMATTYPE *prUArg);
INT32 i4VDOOmxCompParamVideoSeamlessFmt(PARAMETER_OMX_VIDEO_PARAM_SEAMLESSFORMATTYPE *prUArg);
INT32 i4VDOOmxCompParamVideo3DType(PARAMETER_OMX_VIDEO_PARAM_3DTYPE *prUArg); 
INT32 i4VDOOmxCompParamTimeScale(PARAMETER_OMX_TIME_CONFIG_SCALETYPE* prUArg);
INT32 i4VDOOmxCompConfigPictureMode(PARAMETER_OMX_IMAGE_MODE* prUArg);
INT32 i4VDOOmxCompConfigClearImageFrame(PARAMETER_OMX_IMAGE_PROCESSING* prUArg);
INT32 i4VDOOmxCompConfigCommonOutputSize(PARAMETER_OMX_FRAMESIZETYPE* prUArg);
INT32 i4VDOOmxCompConfigCommonRotate(PARAMETER_OMX_CONFIG_ROTATIONTYPE* prUArg);
INT32 i4VDOOmxCompConfigCommonScale(PARAMETER_OMX_CONFIG_SCALEFACTORTYPE* prUArg);
INT32 i4VDOOmxCompConfigCommonOutputPosition(PARAMETER_OMX_CONFIG_POINTTYPE* prUArg);
INT32 i4VDOOmxCompParamExpandedSize(PARAMETER_OMX_FRAMESIZETYPE* prUArg);
INT32 i4VDOOmxCompParamOriginalSize(PARAMETER_OMX_FRAMESIZETYPE* prUArg);
INT32 i4VDOOmxCompParamImageFreeBuffer(PARAMETER_OMX_PARAM_IMAGE_FREEBUFFER* prUArg);
INT32 i4VDOOmxCompParamImageUsrDefineData(PARAMETER_OMX_PARAM_IMAGE_USER_DEFINED* prUArg);


INT32 i4VDOOmxAllocInputBuf(VDO_OMX_HANDLE_T *pHandle, UINT32 u4Size, UINT32 u4Port, VDO_OMX_BUFFER_T **ppBufInfo);
INT32 i4VDOOmxFreeInputBuf(OMX_HANDLETYPE h_Handle, HANDLE_T hHeader);
INT32 i4VDOOmxAllocOutputBuf(VDO_OMX_HANDLE_T *pHandle,
    BOOL fgUseBuf, UINT32 u4BufSA,
    UINT32 u4Size, UINT32 u4Port, VDO_OMX_BUFFER_T **ppBufInfo);
INT32 i4VDOOmxFreeOutputBuf(OMX_HANDLETYPE h_Handle, HANDLE_T hHeader);
INT32 i4VDOOmxQueueEmptyBuf(VDO_OMX_HANDLE_T *pHandle, HANDLE_T hHeader);
INT32 i4VDOOmxQueueFillBuf(VDO_OMX_HANDLE_T *pHandle, HANDLE_T hHeader);
INT32 i4VDOOmxCompFlush(VDO_OMX_HANDLE_T *pHandle, BOOL fgInput, BOOL fgOutput);
INT32 i4VDOOmxCompCheckStateTransition(VDO_OMX_HANDLE_T *pHandle);
//INT32 i4VDOOmxDoEmptyBuf(VDO_OMX_HANDLE_T *pHandle);
INT32 i4VDOOmxDoEmptyBuf(VDO_OMX_HANDLE_T *pHandle, UINT32 u4Index);
//INT32 i4VDOOmxDoFillBuf(VDO_OMX_HANDLE_T *pHandle);
INT32 i4VDOOmxDoFillBuf(VDO_OMX_HANDLE_T *pHandle, UINT32 u4Index);

extern BOOL fgVDOOmxAllInputBufferAlloced(VDO_OMX_HANDLE_T *pHandle);
extern BOOL fgVDOOmxAllInputBufferFreed(VDO_OMX_HANDLE_T *pHandle);
extern INT32 i4VDOOmxForceAllBufEmptyDone(VDO_OMX_HANDLE_T *pHandle);
extern BOOL fgVDOOmxAllOutputBufferAlloced(VDO_OMX_HANDLE_T *pHandle);
extern BOOL fgVDOOmxAllOutputBufferFreed(VDO_OMX_HANDLE_T *pHandle);
extern INT32 i4VDOOmxForceAllBufFillDone(VDO_OMX_HANDLE_T *pHandle);
extern BOOL i4VDOOmxPrintStatus(UINT32 u4InstId);
extern BOOL i4VDOOmxSetInfo(UINT32 u4InstId, UINT32 u4Info, UINT32 u4Para1, UINT32 u4Para2, UINT32 u4Para3);

void vVDOOmxFillBufDone(VDO_OMX_HANDLE_T *pHandle);
void vVDOOmxEmptyBufDone(VDO_OMX_HANDLE_T *pHandle);
void vVDOOmxCompPicInfoChange(VDO_OMX_HANDLE_T *pHandle);

//INT32 i4VDOOmxCompImgFrmDone(VDO_OMX_HANDLE_T *pHandle, void* pvData);
BOOL i4VDOOmxCompImgFrmDone(UINT32 u4Tag, void* pvData);

/*thumbnail functions*/
void vVDOOmxSetThumbnailMode(UINT8 ucVdecId, int mode) ;
int vVDOOmxGetThumbnailMode(UINT8 ucVdecId) ;
INT32 i4VDOOmxCompParamSetThumbnailsMode(PARAMETER_OMX_PARAM_THUMBNAILS_MODE* prUArg);
int vVConv_ThumbnailConvert(PARAMETER_OMX_PARAM_THUMBNAILS_CONVERT *prUArg);
int vVconv_Copy_Done(PARAMETER_OMX_PARAM_CPY_DONE *prUArg);
int vVConv_Fbm_Set_Empty(PARAMETER_OMX_PARAM_FBM_SET_EMPTY *prUArg);

INT32 i4VDOOmxCompParamDecodeSize(PARAMETER_OMX_VIDEO_PARAM_DECODESIZE* prUArg);
INT32 i4VDOOmxCompParamHwId(PARAMETER_OMX_VIDEO_PARAM_HWID* prUArg);
INT32 i4VDOOmxCompParamAppType(PARAMETER_OMX_VIDEO_PARAM_APP_TYPE* prUArg);
INT32 i4VDOOmxCompParamPitchType(PARAMETER_OMX_VIDEO_PARAM_APP_TYPE* prUArg);
INT32 i4VDOOmxCompParamContainerType(PARAMETER_OMX_VIDEO_PARAM_CONTAINER_TYPE* prUArg);
INT32 i4VDOOmxCompConfigEncryptType(PARAMETER_OMX_CONFIG_ENCRYPT_INFO* prUArg);
INT32 i4VDOOmxCompParamEncryptDataInfo(PARAMETER_OMX_PARAM_ENCRYPTDATA_INFO* prUArg);
void i4VDOOmxCleanup(VDO_OMX_HANDLE_T * pHandle);
//	HANDLE_T i4VDOOmxBufGetOutputHeader(UINT32 u4BufIdx);
//	HANDLE_T i4VDOOmxBufGetInputHeader(UINT32 u4BufIdx);

#endif //#ifndef _VDEC_MOD_H_




