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; chId<pObj->inQueInfo->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; winId<pChObj->numWindows; 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);
}
时间: 2024-11-12 21:15:14

DM8168 OSD Algorithm (DSP side)的相关文章

DSP与FPGA通信调试笔记——通过GPMC接口用EDMA传送

硬件:TI达芬奇TMS320DM8168(以下简称DSP).EP4CE6E22C8N(以下简称FPGA) 软件:linux-2.6.37 作者:Aadtech 杭州超距科技 近期项目需要实现DSP与FPGA之间的高速数据交换,用到了DM8168的GPMC接口.这部分的中文资料网上还是比较少的,于是苦苦研究芯片的数据手册和参考指南,最近终于有所成果,在Linux下调用GPMC驱动函数调通了GPMC接口,因此发出调试过程与大家分享.目前以DSP端可以通过GPMC用EDMA的方式读取FPGA端的数据,

DM8168添加DSP音频编解码算法--集成现有voice或audio codec

本文根据"How to integrate audio/voice in RPE in EZSDK.pdf"整理,建议读者直接下载,参考原文件.原文件下载链接: http://download.csdn.net/detail/guo8113/8122945 ps:本文只是参考文档进行定制补充,但目前笔者没有完成移植,仅供参考.转载请注明:http://blog.csdn.net/guo8113/article/details/40820897 DVR_RDK RPE添加其他音频编码 D

【转】DM8168添加DSP音频编解码算法--集成现有voice或audio codec

本文根据“How to integrate audio/voice in RPE in EZSDK.pdf”整理,建议读者直接下载,参考原文件.原文件下载链接: http://download.csdn.net/detail/guo8113/8122945 ps:本文只是参考文档进行定制补充,但目前笔者没有完成移植,仅供参考. 转载请注明:http://blog.csdn.net/guo8113/article/details/40820897 DVR_RDK RPE添加其他音频编码 DM816

DM816x算法详解--之OSD

简介: 本文介绍DM8168 DVRRDK中传入DSP内部的视频格式以及大概的处理流程. 背景: 可能有很多人为了加快研发的速度.降低难度,选择在DVRRDk已有的OSD内添加自己的DSP算法.今天我打算将自己的算法加入进去,发现不管是隔行采集的视频和逐行采集的视频都是可以支持的.那么内部怎么实现的呢? 详述: DVR_RDK_McFW_Link_API_Training.pdf中写道: 可见算法支持隔行(Interlaced)或逐行(progressive)的扫描格式,支持YUV420.YUV

DM8168 DVRRDK软件框架研究

转载注明:http://blog.csdn.net/guo8113/article/details/41120491 Netra(DM8168)处理器是个多核处理器,每个核之间相互独立却又相互关联,如何高效简洁地利用每个核完成一套系统功能是非常关键的,RDK这套软件平台就是针对这种多核平台设计的一套多通道视频应用方案,主要用于DVR.NVR.IPNC之类的产品. 这个软件框架结构允许用户创建不同的多路数据流来实现视频的采集.视频处理(DEI.Noise Filter.Encode.Decode.

DSP开发资源总结,经典书籍,论坛

OMAP4开发资源总结: 一.TI OMAP4官网介绍: http://www.ti.com.cn/general/cn/docs/wtbu/wtbuproductcontent.tsp?templateId=6123&navigationId=12843&contentId=53243 二.OMAPpedia.org,This site has information on various projects in the communityaround OMAP platforms ht

嵌入式开发之davinci--- 8148 中dsp在dsp_drv.c中的processdata()加算法出现下边缘条纹问题

(1)问题原因 dsp在alglink_priv.c中做灰度处理发现,下面出现条纹,后面发现是cache 缓存没及时写进内存问题 (2)解决办法 for(frameId=0; frameId<frameList.numFrames; frameId++) { pFrame = frameList.frames[frameId]; if(pFrame->channelNum >= pObj->inQueInfo.numCh) continue; // do SW OSD if (pO

基于TI Davinci架构的多核/双核开发高速扫盲(以OMAP L138为例),dm8168多核开发參考以及达芬奇系列资料user guide整理

基于TI Davinci架构的双核嵌入式应用处理器OMAPL138开发入门 原文转自http://blog.csdn.net/wangpengqi/article/details/8115614 感谢wangpengqi的共享. 一.简单介绍 TI的达芬奇架构嵌入式应用处理器使用DSP与ARM结合的非对称多核结构,当然如今也有管脚全兼容的单核.本文要介绍的就是当中的一款低功耗处理器OMAP L138. OMAP L138包含一个主频300M的ARM9处理器内核和一个300M的C6748DSP内核

关于DM8168中移植算法速度慢、效率低的新发现

有不少的朋友,特别是刚刚接触DSP的朋友.基于DVRRDK编写C代码发现执行速度特别慢,我在上面简单的对每一个像素的UV分量赋值=0x80,这样就成了灰度图像.对1080P图像进行操作,发现处理每帧要耗时10-20ms,真是慢的不可思议. 近期将SWOSD的完整代码看了一遍发现了玄机. 主要问题是在DDR中读写数据拖慢了速度. 经測试SWOSD进行一帧D1的叠加仅须要400us(叠加大小大概208*32*3个窗体): 细致分析.其内部使用了基于内部 IALG_DARAM0(双通片上数据存储)的乒