DM8168 OSD Algorithm (DSP side)

osdLink_alg.c:

/*******************************************************************************
 *                                                                             *
 * Copyright (c) 2009 Texas Instruments Incorporated - http://www.ti.com/      *
 *                        ALL RIGHTS RESERVED                                  *
 *                                                                             *
 ******************************************************************************/

#include "osdLink_priv.h"


Int32 AlgLink_OsdalgCreate(AlgLink_OsdObj * pObj)
{
    Int32 status, chId;
    SWOSD_OpenPrm algCreatePrm;
    AlgLink_OsdChObj *pChObj;
    SWOSD_Obj *pSwOsdObj;
    AlgLink_OsdChWinParams *pChWinPrm;


    algCreatePrm.maxWidth =
        pObj->osdChCreateParams[0].maxWidth;
    algCreatePrm.maxHeight =
        pObj->osdChCreateParams[0].maxHeight;
    algCreatePrm.osdFormat    =
        pObj->osdChCreateParams[0].osdFormat; 
    /* Create algorithm instance and get algo handle  */
    status = SWOSD_open(&pObj->osdObj, &algCreatePrm);

    UTILS_assert(status == 0);

    for(chId=0; chIdinQueInfo->numCh; chId++)
    {
        pChObj = &pObj->chObj[chId];

        pChWinPrm = &pObj->osdChCreateParams[chId].chDefaultParams;

        pSwOsdObj = &pChObj->osdObj;


        pChWinPrm->chId = chId;

        status = AlgLink_OsdalgSetChOsdWinPrm(pObj, pChWinPrm);

        UTILS_assert(status==0);

        pSwOsdObj->algHndl = pObj->osdObj.algHndl;

        pSwOsdObj->openPrm = pObj->osdObj.openPrm;

        if(pObj->inQueInfo->chInfo[chId].dataFormat == SYSTEM_DF_YUV422I_YUYV)
        {
            pSwOsdObj->videoWindowPrm.format = SWOSD_FORMAT_YUV422i;
        }
        else if(pObj->inQueInfo->chInfo[chId].dataFormat == SYSTEM_DF_YUV420SP_UV)
        {
            pSwOsdObj->videoWindowPrm.format = SWOSD_FORMAT_YUV420sp;
        }
        else if(pObj->inQueInfo->chInfo[chId].dataFormat == SYSTEM_DF_RGB24_888)
        {
            pSwOsdObj->videoWindowPrm.format = SWOSD_FORMAT_RGB888;
        }
        else
        {
            pSwOsdObj->videoWindowPrm.format = -1;
        }

        pSwOsdObj->videoWindowPrm.startX = pObj->inQueInfo->chInfo[chId].startX;
        pSwOsdObj->videoWindowPrm.startY = pObj->inQueInfo->chInfo[chId].startY;
        pSwOsdObj->videoWindowPrm.width  = pObj->inQueInfo->chInfo[chId].width;
        pSwOsdObj->videoWindowPrm.height = pObj->inQueInfo->chInfo[chId].height;
        pSwOsdObj->videoWindowPrm.lineOffset = pObj->inQueInfo->chInfo[chId].pitch[0];
        pSwOsdObj->graphicsWindowPrm.format = -1;
        pChObj->colorKey[0] = 0xFF; /* Y */
        pChObj->colorKey[1] = 0xFF; /* U */
        pChObj->colorKey[2] = 0xFF; /* V */
    }

	return FVID2_SOK;
}

Int32 AlgLink_OsdalgDelete(AlgLink_OsdObj * pObj)
{
    SWOSD_close(&pObj->osdObj);

	return FVID2_SOK;
}

/*
    Returns 32-bit color key thats needs to be programmed to the SW OSD algorithm

    colorKey[0] = Y color Key
    colorKey[1] = U color Key
    colorKey[2] = V color Key

    dataFormat - SWOSD_FORMAT_YUV422i or SWOSD_FORMAT_YUV420sp

    place: 0 - Y plane, 1: C plane
*/
Int32 AlgLink_OsdalgGetColorKey(UInt32 *colorKey, UInt32 dataFormat, UInt32 plane)
{
    UInt32 colorKeyY;
    UInt32 colorKeyU;
    UInt32 colorKeyV;
    UInt32 value;

    colorKeyY = (UInt8)colorKey[0];
    colorKeyU = (UInt8)colorKey[1];
    colorKeyV = (UInt8)colorKey[2];

    if(dataFormat == SWOSD_FORMAT_YUV422i)
    {
        value =
             (colorKeyY <<0)
            |(colorKeyU <<8)
            |(colorKeyY <<16)
            |(colorKeyV <<24)
            ;
    }
    else if(dataFormat == SWOSD_FORMAT_RGB888)
    {
        value =
             (colorKeyY <<0)
            |(colorKeyU <<8)
            |(colorKeyV <<16)
            ;
    }
    else
    {
        if(plane==0)
        {
            value =
                 (colorKeyY <<0)
                |(colorKeyY <<8)
                |(colorKeyY <<16)
                |(colorKeyY <<24)
                ;
        }
        else
        {
            value =
                 (colorKeyU <<0)
                |(colorKeyV <<8)
                |(colorKeyU <<16)
                |(colorKeyV <<24)
                ;
        }
    }

    return value;
}

void AlgLink_OsdalgPrintInfo(SWOSD_Obj *pSwOsdObj, FVID2_Frame *pFrame)
{
    Vps_printf(" SWOSD: CH%d: VID: addr=0x%X start=%d,%d %dx%d, pitch=%d Format %d; GRPX: start=%d,%d %dx%d, pitch=%d Format %d\n",
        pFrame->channelNum,
        pSwOsdObj->videoWindowAddr,
        pSwOsdObj->videoWindowPrm.startX,
        pSwOsdObj->videoWindowPrm.startY,
        pSwOsdObj->videoWindowPrm.width,
        pSwOsdObj->videoWindowPrm.height,
        pSwOsdObj->videoWindowPrm.lineOffset,
        pSwOsdObj->videoWindowPrm.format,
        pSwOsdObj->graphicsWindowPrm.startX,
        pSwOsdObj->graphicsWindowPrm.startY,
        pSwOsdObj->graphicsWindowPrm.width,
        pSwOsdObj->graphicsWindowPrm.height,
        pSwOsdObj->graphicsWindowPrm.lineOffset,
        pSwOsdObj->graphicsWindowPrm.format
    );
}

Int32 AlgLink_OsdalgProcessFrame(AlgLink_OsdObj * pObj, FVID2_Frame *pFrame)
{
    UInt32 winId, fid, scaleX, divY, scaleStartX;
    AlgLink_OsdChObj *pChObj;
    SWOSD_Obj *pSwOsdObj;
    System_FrameInfo *pFrameInfo;
    UInt32 algColorKey[2];
    Bool isInterlaced, isTiled;

    isInterlaced    = FALSE;
    isTiled         = FALSE;
    fid             = 0;
    scaleX          = 1; /* Video frame Scale X */
    scaleStartX     = 1; /* Scale graphics X */
    divY            = 1;

    pChObj = &pObj->chObj[pFrame->channelNum];

    pSwOsdObj = &pChObj->osdObj;


    if(pObj->inQueInfo->chInfo[pFrame->channelNum].scanFormat == SYSTEM_SF_INTERLACED)
        isInterlaced = TRUE;

    if(SYSTEM_MT_TILEDMEM == pObj->inQueInfo->chInfo[pFrame->channelNum].memType)
        isTiled = TRUE;

    if(isInterlaced)
    {
        /* OSD plane is always progressive
           Input can be interlaced in this case we need to skip alternate lines in OSD plane
           and feed for blending
        */
        if(pFrame->fid==1)
            fid = 1;

        /* this will half the processing height */
        divY = 2;
    }

    if(pSwOsdObj->graphicsWindowPrm.format == SWOSD_FORMAT_YUV422i)
        scaleX = 2;/* Pixel offset multiplier, 2 as in 422p format each pixel is of 2 bytes.*/

    if(pSwOsdObj->graphicsWindowPrm.format == SWOSD_FORMAT_RGB888)
    {
        scaleX       = 3; /* Pixel offset multiplier, 3 as in RGB format each pixel is of 3 bytes.*/
        if(pChObj->osdObj.videoWindowPrm.format == SWOSD_FORMAT_YUV422i)
           scaleStartX  = 2; /* Pixel offset multiplier, 2 as in 422p format each pixel is of 2 bytes.*/
    }
    algColorKey[0] = AlgLink_OsdalgGetColorKey(
                        pChObj->colorKey,
                        pSwOsdObj->graphicsWindowPrm.format,
                        0
                     );

    algColorKey[1] = 0;

    if(pSwOsdObj->graphicsWindowPrm.format == SWOSD_FORMAT_YUV420sp)
    {
        algColorKey[1] = AlgLink_OsdalgGetColorKey(
                        pChObj->colorKey,
                        pSwOsdObj->graphicsWindowPrm.format,
                        1
                      );
    }

    /* NOT SUPPORTED */
    pSwOsdObj->alphaWindowAddr = NULL;

    pFrameInfo = (System_FrameInfo*)pFrame->appData;
       
    UTILS_assert(pFrameInfo!=NULL);

    if(pFrameInfo->rtChInfoUpdate)
    {
        /* Need to comment this as we dont update this when we update frameInfo in IPCFrameIn*/
//        pSwOsdObj->videoWindowPrm.format = pFrameInfo->rtChInfo.dataFormat;
        pSwOsdObj->videoWindowPrm.startX = pFrameInfo->rtChInfo.startX;
        pSwOsdObj->videoWindowPrm.startY = pFrameInfo->rtChInfo.startY;
        pSwOsdObj->videoWindowPrm.width  = pFrameInfo->rtChInfo.width;
        pSwOsdObj->videoWindowPrm.height = pFrameInfo->rtChInfo.height;
        pSwOsdObj->videoWindowPrm.lineOffset = pFrameInfo->rtChInfo.pitch[0];
    }

    for(winId=0; winIdnumWindows; winId++)
    {
        if(!pChObj->osdWinObj[winId].enableWin)
            continue;

        /* YUV422i or YUV420SP - Y-plane processing */

        pSwOsdObj->videoWindowAddr = pFrame->addr[0][0];

        if (isTiled)
        {
            pSwOsdObj->videoWindowAddr =
                (Ptr)Utils_tilerAddr2CpuAddr((UInt32)pFrame->addr[0][0]);
            pSwOsdObj->videoWindowPrm.lineOffset =  VPSUTILS_TILER_CNT_8BIT_PITCH;
        }

        pSwOsdObj->globalPrm.globalAlpha        = pChObj->osdWinObj[winId].globalAlpha;
        pSwOsdObj->globalPrm.transperencyEnable = pChObj->osdWinObj[winId].transperencyEnable;
        pSwOsdObj->globalPrm.transperencyColor32= algColorKey[0];
        pSwOsdObj->graphicsWindowPrm            = pChObj->osdWinObj[winId].osdWinPrm;
        pSwOsdObj->graphicsWindowAddr           =
                     pChObj->osdWinObj[winId].addr[0][0] + fid*pSwOsdObj->graphicsWindowPrm.lineOffset*scaleX;

        /* Hori.(X) startX offset in a frame, Gpx will start from this offset */
        if(pSwOsdObj->graphicsWindowPrm.format == SWOSD_FORMAT_RGB888)
             pSwOsdObj->graphicsWindowPrm.startX *= scaleStartX;
        else
             pSwOsdObj->graphicsWindowPrm.startX *= scaleX;

        pSwOsdObj->graphicsWindowPrm.startY     /= divY;
        pSwOsdObj->graphicsWindowPrm.width  *= scaleX;

        pSwOsdObj->graphicsWindowPrm.height     /= divY;
        pSwOsdObj->graphicsWindowPrm.lineOffset *= (scaleX * divY); // double line offset
        
        pSwOsdObj->videoWindowPrm.dataPlane = SWOSD_DATAPLANE_LUMA;
        #if 0
        AlgLink_OsdalgPrintInfo(pSwOsdObj, pFrame);
        #endif

        SWOSD_blendWindow(pSwOsdObj);

        /* YUV420SP - C -plane processing */
        if(pSwOsdObj->graphicsWindowPrm.format == SWOSD_FORMAT_YUV420sp)
        {
            pSwOsdObj->videoWindowAddr = pFrame->addr[0][1];
            if (isTiled)
            {
                pSwOsdObj->videoWindowAddr =
                    (Ptr)Utils_tilerAddr2CpuAddr((UInt32)pFrame->addr[0][1]);
                pSwOsdObj->videoWindowPrm.lineOffset =  VPSUTILS_TILER_CNT_16BIT_PITCH;
            }

            pSwOsdObj->graphicsWindowAddr           =
                        pChObj->osdWinObj[winId].addr[0][1] + fid*pSwOsdObj->graphicsWindowPrm.lineOffset*scaleX;

            pSwOsdObj->graphicsWindowPrm.startY /= 2;    // half width  for C plane
            pSwOsdObj->graphicsWindowPrm.height /= 2;    // half height for C plane

            pSwOsdObj->globalPrm.transperencyColor32= algColorKey[1];
            pSwOsdObj->videoWindowPrm.dataPlane = SWOSD_DATAPLANE_CHROMA;
            #if 0
            AlgLink_OsdalgPrintInfo(pSwOsdObj, pFrame);
            #endif

            SWOSD_blendWindow(pSwOsdObj);
        }        
        /* YUV420SP Frame - C -plane processing */
        if((pSwOsdObj->graphicsWindowPrm.format == SWOSD_FORMAT_RGB888) && 
               (pChObj->osdObj.videoWindowPrm.format == SWOSD_FORMAT_YUV420sp))
        {
            pSwOsdObj->videoWindowAddr = pFrame->addr[0][1];
            if (isTiled)
            {
                pSwOsdObj->videoWindowAddr =
                    (Ptr)Utils_tilerAddr2CpuAddr((UInt32)pFrame->addr[0][1]);
                pSwOsdObj->videoWindowPrm.lineOffset =  VPSUTILS_TILER_CNT_16BIT_PITCH;
            }

            pSwOsdObj->graphicsWindowAddr           =
                        pChObj->osdWinObj[winId].addr[0][0] + fid*pSwOsdObj->graphicsWindowPrm.lineOffset*scaleX;

            pSwOsdObj->graphicsWindowPrm.startY /= 2;    // half width  for C plane
            pSwOsdObj->graphicsWindowPrm.height /= 2;    // half height for C plane

            pSwOsdObj->graphicsWindowPrm.lineOffset *= 2; // Double line offset of RGB888
            pSwOsdObj->globalPrm.transperencyColor32= algColorKey[0];
            pSwOsdObj->videoWindowPrm.dataPlane = SWOSD_DATAPLANE_CHROMA;
            #if 0
            AlgLink_OsdalgPrintInfo(pSwOsdObj, pFrame);
            #endif

            SWOSD_blendWindow(pSwOsdObj);
        }

    }

    return 0;
}


Int32 AlgLink_OsdalgSetChOsdWinPrm(AlgLink_OsdObj * pObj,
                            AlgLink_OsdChWinParams * params)
{
    Int32 status = 0;
    AlgLink_OsdChObj *pChObj;
    UInt32 i, chId;
    SWOSD_Obj *pSwOsdObj;

    if(params->chId >= pObj->inQueInfo->numCh)
        return -1;
    chId = params->chId;

    pChObj = &pObj->chObj[chId];
    pSwOsdObj = &pChObj->osdObj;


    pChObj->numWindows         = params->numWindows;

    for(i = 0; i < params->numWindows; i++)
    {
        AlgLink_OsdWinObj *osdWinObj = &pChObj->osdWinObj[i];

        osdWinObj->enableWin          = params->winPrm[i].enableWin;
        osdWinObj->transperencyEnable = params->winPrm[i].transperencyEnable;
        osdWinObj->globalAlpha        = params->winPrm[i].globalAlpha;


        osdWinObj->addr[0][0] = params->winPrm[i].addr[0][0];
        osdWinObj->addr[0][1] = params->winPrm[i].addr[0][1];

        if(params->winPrm[i].format == SYSTEM_DF_YUV422I_YUYV)
        {
          osdWinObj->osdWinPrm.format = SWOSD_FORMAT_YUV422i;
        }
        else if(params->winPrm[i].format == SYSTEM_DF_YUV420SP_UV)
        {
          osdWinObj->osdWinPrm.format = SWOSD_FORMAT_YUV420sp;
        }
        else if(params->winPrm[i].format == SYSTEM_DF_RGB24_888)
        {
          osdWinObj->osdWinPrm.format = SWOSD_FORMAT_RGB888;
        }
        else
        {
          osdWinObj->osdWinPrm.format = -1;
        }

        osdWinObj->osdWinPrm.startX     = params->winPrm[i].startX;
        osdWinObj->osdWinPrm.startY     = params->winPrm[i].startY;
        osdWinObj->osdWinPrm.width      = params->winPrm[i].width;
        osdWinObj->osdWinPrm.height     = params->winPrm[i].height;
        osdWinObj->osdWinPrm.lineOffset = params->winPrm[i].lineOffset;

        pChObj->colorKey[0] = params->colorKey[0];
        pChObj->colorKey[1] = params->colorKey[1];
        pChObj->colorKey[2] = params->colorKey[2];

        if(pObj->inQueInfo->chInfo[chId].dataFormat == SYSTEM_DF_YUV422I_YUYV)
        {
            pSwOsdObj->videoWindowPrm.format = SWOSD_FORMAT_YUV422i;
        }
        else if(pObj->inQueInfo->chInfo[chId].dataFormat == SYSTEM_DF_YUV420SP_UV)
        {
            pSwOsdObj->videoWindowPrm.format = SWOSD_FORMAT_YUV420sp;
        }
        else if(pObj->inQueInfo->chInfo[chId].dataFormat == SYSTEM_DF_RGB24_888)
        {
            pSwOsdObj->videoWindowPrm.format = SWOSD_FORMAT_RGB888;
        }
        else
        {
            pSwOsdObj->videoWindowPrm.format = -1;
        }

    }
    pSwOsdObj->graphicsWindowPrm            = pChObj->osdWinObj[0].osdWinPrm;
 return (status);
}

你可能感兴趣的:(DM8168 OSD Algorithm (DSP side))