/*
* Copyright (c) 2015-2021, 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.
*/
//! \file     media_libva_common.cpp
//! \brief    libva(and its extension) interface implemantation common functions
//!

#include "media_libva.h"
#include "media_libva_util.h"
#include "media_ddi_prot.h"
#include "mos_solo_generic.h"
#include "mos_interface.h"
#include "media_libva_caps.h"

static void* DdiMedia_GetVaContextFromHeap(PDDI_MEDIA_HEAP  mediaHeap, uint32_t index, PMEDIA_MUTEX_T mutex)
{
    PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT  vaCtxHeapElmt = nullptr;
    void                              *context = nullptr;

    DdiMediaUtil_LockMutex(mutex);
    if(nullptr == mediaHeap || index >= mediaHeap->uiAllocatedHeapElements)
    {
        DdiMediaUtil_UnLockMutex(mutex);
        return nullptr;
    }
    vaCtxHeapElmt  = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaHeap->pHeapBase;
    vaCtxHeapElmt += index;
    context        = vaCtxHeapElmt->pVaContext;
    DdiMediaUtil_UnLockMutex(mutex);

    return context;
}

void DdiMedia_MediaSurfaceToMosResource(DDI_MEDIA_SURFACE *mediaSurface, MOS_RESOURCE  *mosResource)
{
    DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface",);
    DDI_CHK_NULL(mosResource, "nullptr mosResource",);
    DDI_ASSERT(mosResource->bo);

    MosInterface::ConvertResourceFromDdi(mediaSurface, mosResource, OS_SPECIFIC_RESOURCE_SURFACE, 0);

    Mos_Solo_SetOsResource(mediaSurface->pGmmResourceInfo, mosResource);

    return;
}

void DdiMedia_MediaBufferToMosResource(DDI_MEDIA_BUFFER *mediaBuffer, MOS_RESOURCE *mosResource)
{
    DDI_CHK_NULL(mediaBuffer, "nullptr mediaBuffer",);
    DDI_CHK_NULL(mosResource, "nullptr mosResource",);
    DDI_ASSERT(mediaBuffer->bo);

    MosInterface::ConvertResourceFromDdi(mediaBuffer, mosResource, OS_SPECIFIC_RESOURCE_BUFFER, 0);

    Mos_Solo_SetOsResource(mediaBuffer->pGmmResourceInfo, mosResource);

    return;
}

void* DdiMedia_GetContextFromContextID (VADriverContextP ctx, VAContextID vaCtxID, uint32_t *ctxType)
{
    PDDI_MEDIA_CONTEXT       mediaCtx = nullptr;
    uint32_t                 index = 0;

    DDI_CHK_NULL(ctx, "nullptr ctx", nullptr);
    DDI_CHK_NULL(ctxType, "nullptr ctxType", nullptr);

    mediaCtx  = DdiMedia_GetMediaContext(ctx);
    index    = vaCtxID & DDI_MEDIA_MASK_VACONTEXTID;

    if (index >= DDI_MEDIA_MAX_INSTANCE_NUMBER)
        return nullptr;
    if ((vaCtxID&DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_PROT)
    {
        DDI_VERBOSEMESSAGE("Protected session detected: 0x%x", vaCtxID);
        *ctxType = DDI_MEDIA_CONTEXT_TYPE_PROTECTED;
        index = index & DDI_MEDIA_MASK_VAPROTECTEDSESSION_ID;
        return DdiMedia_GetVaContextFromHeap(mediaCtx->pProtCtxHeap, index, &mediaCtx->ProtMutex);
    }
    else if ((vaCtxID&DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_DECODER)
    {
        DDI_VERBOSEMESSAGE("Decode context detected: 0x%x", vaCtxID);
        *ctxType = DDI_MEDIA_CONTEXT_TYPE_DECODER;
        return DdiMedia_GetVaContextFromHeap(mediaCtx->pDecoderCtxHeap, index, &mediaCtx->DecoderMutex);
    }
    else if ((vaCtxID&DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_ENCODER)
    {
        *ctxType = DDI_MEDIA_CONTEXT_TYPE_ENCODER;
        return DdiMedia_GetVaContextFromHeap(mediaCtx->pEncoderCtxHeap, index, &mediaCtx->EncoderMutex);
    }
    else if ((vaCtxID & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_VP)
    {
        *ctxType = DDI_MEDIA_CONTEXT_TYPE_VP;
        return DdiMedia_GetVaContextFromHeap(mediaCtx->pVpCtxHeap, index, &mediaCtx->VpMutex);
    }
    else if ((vaCtxID & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_CM)
    {
        *ctxType = DDI_MEDIA_CONTEXT_TYPE_CM;
        return DdiMedia_GetVaContextFromHeap(mediaCtx->pCmCtxHeap, index, &mediaCtx->CmMutex);
    }
    else if ((vaCtxID & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_MFE)
    {
        *ctxType = DDI_MEDIA_CONTEXT_TYPE_MFE;
        return DdiMedia_GetVaContextFromHeap(mediaCtx->pMfeCtxHeap, index, &mediaCtx->MfeMutex);
    }
    else
    {
        DDI_ASSERTMESSAGE("Invalid context: 0x%x", vaCtxID);
        *ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
        return nullptr;
    }

}

DDI_MEDIA_SURFACE* DdiMedia_GetSurfaceFromVASurfaceID (PDDI_MEDIA_CONTEXT mediaCtx, VASurfaceID surfaceID)
{
    uint32_t                         i = 0;
    PDDI_MEDIA_SURFACE_HEAP_ELEMENT  surfaceElement = nullptr;
    PDDI_MEDIA_SURFACE               surface = nullptr;

    DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", nullptr);

    i                = (uint32_t)surfaceID;
    bool validSurface = (i != VA_INVALID_SURFACE);
    if(validSurface)
    {
        DDI_CHK_LESS(i, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "invalid surface id", nullptr);
        DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
        surfaceElement  = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)mediaCtx->pSurfaceHeap->pHeapBase;
        surfaceElement += i;
        surface         = surfaceElement->pSurface;
        DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
    }

    return surface;
}

VASurfaceID DdiMedia_GetVASurfaceIDFromSurface(PDDI_MEDIA_SURFACE surface)
{
    DDI_CHK_NULL(surface, "nullptr surface", VA_INVALID_SURFACE);

    PDDI_MEDIA_SURFACE_HEAP_ELEMENT  surfaceElement = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surface->pMediaCtx->pSurfaceHeap->pHeapBase;
    for(uint32_t i = 0; i < surface->pMediaCtx->pSurfaceHeap->uiAllocatedHeapElements; i ++)
    {
        if(surface == surfaceElement->pSurface)
        {
            return surfaceElement->uiVaSurfaceID;
        }
        surfaceElement ++;
    }
    return VA_INVALID_SURFACE;
}

PDDI_MEDIA_SURFACE DdiMedia_ReplaceSurfaceWithNewFormat(PDDI_MEDIA_SURFACE surface, DDI_MEDIA_FORMAT expectedFormat)
{
    DDI_CHK_NULL(surface, "nullptr surface", nullptr);

    PDDI_MEDIA_SURFACE_HEAP_ELEMENT  surfaceElement = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surface->pMediaCtx->pSurfaceHeap->pHeapBase;
    PDDI_MEDIA_CONTEXT mediaCtx = surface->pMediaCtx;

    //check some conditions
    if(expectedFormat == surface->format)
    {
        return surface;
    }
    //create new dst surface and copy the structure
    PDDI_MEDIA_SURFACE dstSurface = (DDI_MEDIA_SURFACE *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE));
    if (nullptr == surfaceElement)
    {
        MOS_FreeMemory(dstSurface);
        return nullptr;
    }

    MOS_SecureMemcpy(dstSurface,sizeof(DDI_MEDIA_SURFACE),surface,sizeof(DDI_MEDIA_SURFACE));
    DDI_CHK_NULL(dstSurface, "nullptr dstSurface", nullptr);
    dstSurface->format = expectedFormat;
    dstSurface->uiLockedBufID = VA_INVALID_ID;
    dstSurface->uiLockedImageID = VA_INVALID_ID;
    dstSurface->pSurfDesc = nullptr;
    //lock surface heap
    DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
    uint32_t i;
    //get current element heap and index
    for(i = 0; i < mediaCtx->pSurfaceHeap->uiAllocatedHeapElements; i ++)
    {
        if(surface == surfaceElement->pSurface)
        {
            break;
        }
        surfaceElement ++;
    }
    //if cant find
    if(i == surface->pMediaCtx->pSurfaceHeap->uiAllocatedHeapElements)
    {
        DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
        MOS_FreeMemory(dstSurface);
        return nullptr;
    }
    //FreeSurface
    DdiMediaUtil_FreeSurface(surface);
    MOS_FreeMemory(surface);
    //CreateNewSurface
    DdiMediaUtil_CreateSurface(dstSurface,mediaCtx);
    surfaceElement->pSurface = dstSurface;

    DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);

    return dstSurface;
}

PDDI_MEDIA_SURFACE DdiMedia_ReplaceSurfaceWithVariant(PDDI_MEDIA_SURFACE surface, VAEntrypoint entrypoint)
{
    DDI_CHK_NULL(surface, "nullptr surface", nullptr);

    PDDI_MEDIA_CONTEXT mediaCtx = surface->pMediaCtx;
    uint32_t aligned_width, aligned_height;
    DDI_MEDIA_FORMAT aligned_format;

    //check some conditions
    if(surface->uiVariantFlag)
    {
        return surface;
    }

    VASurfaceID vaID = DdiMedia_GetVASurfaceIDFromSurface(surface);
    if(VA_INVALID_SURFACE == vaID)
    {
        return nullptr;
    }
    PDDI_MEDIA_SURFACE_HEAP_ELEMENT  surfaceElement = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surface->pMediaCtx->pSurfaceHeap->pHeapBase;
    if (nullptr == surfaceElement)
    {
        return nullptr;
    }
    surfaceElement += vaID;
    aligned_format = surface->format;
    switch (surface->format)
    {
        case Media_Format_AYUV:
            aligned_width = MOS_ALIGN_CEIL(surface->iWidth, 128);
            aligned_height = MOS_ALIGN_CEIL(surface->iHeight * 3 / 4, 64);
            break;
        case Media_Format_Y410:
            aligned_width = MOS_ALIGN_CEIL(surface->iWidth, 64);
            aligned_height = MOS_ALIGN_CEIL(surface->iHeight * 3 / 2, 64);
            break;
        case Media_Format_Y216:
#if VA_CHECK_VERSION(1, 9, 0)
        case Media_Format_Y212:
#endif
        case Media_Format_Y210:
            aligned_width = (surface->iWidth + 1) >> 1;
            aligned_height = surface->iHeight * 2;
            aligned_format = Media_Format_Y216;
            break;
        case Media_Format_YUY2:
            aligned_width = (surface->iWidth + 1) >> 1;
            aligned_height = surface->iHeight * 2;
            break;
        case Media_Format_P016:
        case Media_Format_P012:
        case Media_Format_P010:
            aligned_height = surface->iHeight;
            aligned_width = surface->iWidth;
            if(entrypoint == VAEntrypointEncSlice)
            {
                aligned_width = surface->iWidth * 2;
                aligned_format = Media_Format_NV12;
            }
            else
            {
                aligned_format = Media_Format_P016;
            }
            break;
        default:
            return surface;
       }

    //create new dst surface and copy the structure
    PDDI_MEDIA_SURFACE dstSurface = (DDI_MEDIA_SURFACE *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE));

    MOS_SecureMemcpy(dstSurface,sizeof(DDI_MEDIA_SURFACE),surface,sizeof(DDI_MEDIA_SURFACE));
    DDI_CHK_NULL(dstSurface, "nullptr dstSurface", nullptr);

    dstSurface->uiVariantFlag = 1;
    dstSurface->format = aligned_format;
    dstSurface->iWidth = aligned_width;
    dstSurface->iHeight = aligned_height;
   //CreateNewSurface
    if(DdiMediaUtil_CreateSurface(dstSurface,mediaCtx) != VA_STATUS_SUCCESS)
    {
        MOS_FreeMemory(dstSurface);
        return surface;
    }
    //replace the surface
    surfaceElement->pSurface = dstSurface;
    //FreeSurface
    DdiMediaUtil_FreeSurface(surface);
    MOS_FreeMemory(surface);

    return dstSurface;
}

DDI_MEDIA_BUFFER* DdiMedia_GetBufferFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
{
    uint32_t                       i = 0;
    PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement = nullptr;
    PDDI_MEDIA_BUFFER              buf = nullptr;

    i                = (uint32_t)bufferID;
    DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", nullptr);
    DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
    bufHeapElement  = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase;
    bufHeapElement += i;
    buf             = bufHeapElement->pBuffer;
    DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);

    return buf;
}

bool DdiMedia_DestroyBufFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
{
    DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
    DdiMediaUtil_ReleasePMediaBufferFromHeap(mediaCtx->pBufferHeap, bufferID);
    mediaCtx->uiNumBufs--;
    DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
    return true;
}

void* DdiMedia_GetContextFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
{
    uint32_t                       i;
    PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement;
    void *                         ctx;

    i                = (uint32_t)bufferID;
    DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", nullptr);
    DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
    bufHeapElement  = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase;
    bufHeapElement += bufferID;
    ctx            = bufHeapElement->pCtx;
    DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);

    return ctx;
}

int32_t DdiMedia_GetGpuPriority (VADriverContextP ctx, VABufferID *buffers, int32_t numBuffers, bool *updatePriority, int32_t *priority)
{
    void *        data;
    uint32_t      updateSessionPriority  = 0;
    uint32_t      priorityValue          = 0;
    int32_t       priorityIndexInBuf     = -1;

    DDI_CHK_NULL(ctx, "nullptr context in DdiMedia_GetGpuPriority!", -1);

    PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
    DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", -1);
#if VA_CHECK_VERSION(1, 10, 0)
    for (int32_t i = 0; i < numBuffers; i++)
    {
        DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffers[i]);
        DDI_CHK_NULL(buf, "Invalid buffer.", -1);

        if((int32_t)buf->uiType == VAContextParameterUpdateBufferType)
        {
            //Read the priority from the VAContextParameterUpdateBuffer
            DdiMedia_MapBuffer(ctx, buffers[i], &data);
            DDI_CHK_NULL(data, "nullptr data.", -1);

            VAContextParameterUpdateBuffer *ContextParamBuf = (VAContextParameterUpdateBuffer *)data;
            DDI_CHK_NULL(ContextParamBuf, "nullptr ContextParamBuf.", -1);

            updateSessionPriority   = ContextParamBuf->flags.bits.context_priority_update;
            priorityValue           = ContextParamBuf->context_priority.bits.priority;

            if (updateSessionPriority)
            {
                *updatePriority = true;
                if(priorityValue >= 0 && priorityValue <= CONTEXT_PRIORITY_MAX)
                {
                    *priority = priorityValue - CONTEXT_PRIORITY_MAX/2;
                }
                else
                {
                    *priority = 0;
                }
            }
            else
            {
                *updatePriority = false;
                *priority = 0;
            }

            DdiMedia_UnmapBuffer(ctx, buffers[i]);
            priorityIndexInBuf = i;
            break;
        }
    }
#endif
    return priorityIndexInBuf;
}

//Move the priority bufferID to the end of buffers 
void MovePriorityBufferIdToEnd (VABufferID *buffers, int32_t priorityIndexInBuf, int32_t numBuffers)
{
    VABufferID    vaBufferID = 0;
    if( (numBuffers > 1) && (priorityIndexInBuf < numBuffers -1) )
    {
        vaBufferID = buffers[priorityIndexInBuf];
        while(priorityIndexInBuf < (numBuffers - 1) )
        {
            buffers[priorityIndexInBuf] = buffers[priorityIndexInBuf+1];
            priorityIndexInBuf++;
        }
        buffers[numBuffers -1] = vaBufferID;
    }
}

