DM8168 OSD Algorithm (DSP side)
2019-07-13 16:27发布
生成海报
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
",
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);
}
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮