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); }