/* 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$
 * $Date$
 * $RCSfile: venc_if.h,v $
 * $Revision$
 *
 *---------------------------------------------------------------------------*/

/** @file venc_if.h
 *  Public interface of software program stream demux driver
 */


#ifndef VENC_UTIL_H
#define VENC_UTIL_H

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------

#include "drv_common.h"
#include "x_common.h"
#include "x_typedef.h"
#include "x_timer.h"
#include "x_assert.h"
#include "x_os.h"
#include "x_bim.h"
#include "x_clksrc.h"
#include "x_hal_5381.h"
#include "x_hal_926.h"
#include "venc_if.h"
#include "venc_drvif.h"

//-----------------------------------------------------------------------------
// resizer util
//-----------------------------------------------------------------------------
typedef struct _VENC_REZ_OBJ_T
{
    UINT8 type;
    UINT32 u4SrcW;
    UINT32 u4SrcH;
    UINT32 u4SrcPitch;
    UINT32 u4TgW;
    UINT32 u4TgH;
    UINT32 u4TgPitch;
    VENC_PIX_FMT_T  ePixFmt;
    UINT32 (*Init)  (struct _VENC_REZ_OBJ_T *);
    UINT32 (*Resize)(struct _VENC_REZ_OBJ_T *,UINT32, UINT32);
    VOID  *Members;
} VENC_REZ_OBJ_T;


VENC_REZ_OBJ_T *VencCreateRezObject(void);
VOID VencDeleteRezObject(VENC_REZ_OBJ_T *pObj);
VOID VencRezSrc(VENC_OBJECT_T *this, VENC_IN_PIC_T *ptIn);

//-----------------------------------------------------------------------------
// get thumbnail util
//-----------------------------------------------------------------------------

BOOL VencGetThumbnail(VENC_OBJECT_T *this, VENC_IN_PIC_T *ptIn, UPTR u4YUV420, UPTR u4ARGB);


//-----------------------------------------------------------------------------
// buffer manager util
//-----------------------------------------------------------------------------

#define VENC_BUFMGR_WAIT        1
#define VENC_BUFMGR_NOWAIT      2
#define VENC_BUFMGR_WAIT_30ms   3


#define VENC_BUFMGR_OK        0
#define VENC_BUFMGR_EMPTY     1
#define VENC_BUFMGR_FULL      2
#define VENC_BUFMGR_INV_ARG   3
#define VENC_BUFMGR_FAIL      4
#define VENC_BUFMGR_TIMEOUT   5


#define VENC_BUFMGR_BASE_MEMBERS                                         \
    HANDLE_T hCntSem;                                                    \
    UINT8    u1Size;                                                     \
    UINT8    u1MaxSize;                                                  \
    UINT8    u1StackNs;                                                  \
    UINT8    u1MemSize;                                                  \
    UINT32 (*Get)   (struct _VENC_BUFMGR_BASE_T *, VOID *, UINT32);      \
    UINT32 (*Free)  (struct _VENC_BUFMGR_BASE_T *, VOID *);              \


typedef struct _VENC_BUFMGR_BASE_T
{
    VENC_BUFMGR_BASE_MEMBERS
} VENC_BUFMGR_BASE_T;

UINT32 _BUFMGR_OBJ_Get    (VENC_BUFMGR_BASE_T *, VOID *, UINT32);
UINT32 _BUFMGR_OBJ_Free  (VENC_BUFMGR_BASE_T *, VOID *);
UINT32 _BUFMGR_OBJ_Add   (VENC_BUFMGR_BASE_T *, VOID *);
VOID   _BUFMGR_OBJ_Reset(VENC_BUFMGR_BASE_T *);


#define VENC_BUFMGR_T(mod)   VENC_BUFMGR_##mod##OBJ_T

#define VENC_BUFMGR_DECLARE(mod,type,size)                               \
    typedef struct                                                       \
    {                                                                    \
        VENC_BUFMGR_BASE_MEMBERS                                         \
        UINT32 auStack[size];                                            \
        type   atData[size];                                             \
    } VENC_BUFMGR_T(mod);                                                \
                                                                         \
    /*constructor*/                                                      \
    static VENC_BUFMGR_T(mod) *_BUFMGR_##mod##OBJ_constructor(void)      \
    {                                                                    \
        VENC_BUFMGR_T(mod) *__##mod##Obj;                        \
        __##mod##Obj = x_mem_alloc(sizeof(VENC_BUFMGR_T(mod)));          \
        if(NULL == __##mod##Obj) return NULL;                           \
        /*static VENC_BUFMGR_T(mod) *__##mod##Obj = (VENC_BUFMGR_T(mod) *) x_mem_alloc(sizeof(VENC_BUFMGR_T(mod)));      */                    \
        __##mod##Obj->Get        = _BUFMGR_OBJ_Get;                       \
        __##mod##Obj->Free       = _BUFMGR_OBJ_Free;                      \
        __##mod##Obj->u1Size     = 0;                                     \
        __##mod##Obj->u1MaxSize  = size;                                  \
        __##mod##Obj->u1StackNs  = 0;                                     \
        __##mod##Obj->u1MemSize  = sizeof(type);                          \
        /* create semaphore*/                                              \
        VERIFY(x_sema_create(&(__##mod##Obj->hCntSem),                    \
                             X_SEMA_TYPE_COUNTING,                       \
                             size) == OSR_OK);                           \
        return __##mod##Obj;                                            \
    }                                                                    \
    /*destructor*/                                                         \
    static VOID _BUFMGR_##mod##OBJ_destructor(VENC_BUFMGR_T(mod) *pObj)  \
    {                                                                    \
        if(NULL == pObj) return  ;                                   \
        VERIFY(x_sema_delete(pObj->hCntSem) == OSR_OK);                  \
        x_mem_free(pObj);                                                \
        pObj = NULL;                                                     \
    }                                                                    \


#define VENC_MEMBER_OFFSET(type, member)  ((UPTR)(&(((type*)0)->member)))


#define VENC_BUFMGR_OBJ_CREATE(mod)  _BUFMGR_##mod##OBJ_constructor()


#define VENC_BUFMGR_OBJ_DELETE(mod,pO) _BUFMGR_##mod##OBJ_destructor(pO)



//VENC filter
typedef struct _VENC_FILTER_T
{
    UINT32 u4PtsDelta;
    UINT32 u4NextPts;
} VENC_FILTER_T;

#ifdef VENC_FRAME_CTRL_BY_DRV
VOID _VENC_Filter_Init     (VENC_FILTER_T *, UINT32);
BOOL _VENC_Filter_Do      (VENC_FILTER_T *, UINT32);
VOID _VENC_Filter_Reset(VENC_FILTER_T *);
VOID _VENC_Filter_Update(VENC_FILTER_T *);
#endif

/**
 * release input buffer's resource (scpip ...)
 * only async mode uses this function,
 * in sync mode, caller will release @prIn
 */
VOID vVencReleaseInputBuffer(VENC_OBJECT_T *prObject, VENC_BUFMGR_BASE_T *prBufMgr, VENC_IN_PIC_T *prIn);

#endif // VENC_UTIL_H


