This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM8168 rotation used tiler API

Hi,

I am using the platform of DM8168.

I want to implement the image 90 degree rotation.

I found some API function as follow:

    UInt32 Utils_tilerGetOriAddr(UInt32 tilerAddr, UInt32 cntMode, UInt32 oriFlag, UInt32 width, UInt32 height)

    UInt32 Utils_tilerAddr2CpuAddr(UInt32 tilerAddr)

And I found some information about the tiler for rotation on http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/p/251642/880297.aspx#880297

and Badri Narayanan said it can be realized though it will complexed.

Now, I want to know if it can be reliazed 90 degree rotation with the API function as I mentioned, and how should I do?

I thought the steps will be as follow:

1, I alloc tiler memory used SystemTiler_alloc for the Y data and CbCr data, the frame dataformat is YUV420SP

2, calculate the oriaddress used Utils_tilerGetOriAddr.

3, transfer the oriaddress to cpu virtual address used Utils_tilerAddr2CpuAddr.

I thought it will have some further steps, what should I do at the next steps?

And more , I just want to reliaze the rotation and don't care the codec and display. For example the original image resolution is 2432*2048, when rotation, the resolution will be 2048*2432, furthermore, I can resize the resolution to 1920*1080 used the mpsclr link.

Thanks,

Tianxing

  • Anyone will help me!!!

  • Attached is patch to implement rotation using tiler in SwMs link.You can refer it to understand the changes required to implement rotation.Following rotation are possible, flipX,flipY,swapXY . The patch should be applied on top of DVR RDK 4.1

    diff --git a/demos/mcfw_api_demos/mcfw_demo/demo_display.c b/demos/mcfw_api_demos/mcfw_demo/demo_display.c
    index 8c9ab3f..2da5472 100755
    --- a/demos/mcfw_api_demos/mcfw_demo/demo_display.c
    +++ b/demos/mcfw_api_demos/mcfw_demo/demo_display.c
    @@ -39,6 +39,7 @@ char gDemo_displaySettingsMenu[] = {
         "\r\n u: Change CPROC setting"
     #endif
         "\r\n t: Get Video Time Stamp Info"
    +    "\r\n v: Rotate Video (ONLY when input to SwMs is tiled)"
         "\r\n"
         "\r\n p: Previous Menu"
         "\r\n"
    @@ -1872,6 +1873,18 @@ int Demo_displaySettings(int demoId)
                     cprocCfg = Demo_getIntValue("CPROC color temperature", 0, 17, 0);
                     Vdis_setCprocConfig(cprocCfg);
                     break;
    +            case 'v':
    +            {
    +                UInt32 flipX,flipY,swapXY;
    +
    +                devId = VDIS_DEV_HDMI;
    +                chId = Demo_getChId("DISPLAY", gDemo_info.maxVdisChannels);
    +                flipX = Demo_getIntValue("SWMS Rotate : FlipX (0 - FALSE/1 - TRUE)",0,1,0);
    +                flipY = Demo_getIntValue("SWMS Rotate : FlipY (0 - FALSE/1 - TRUE)",0,1,0);
    +                swapXY = Demo_getIntValue("SWMS Rotate : SwapX-Y (0 - FALSE/1 - TRUE)",0,1,0);
    +                Vdis_setRotateConfig(devId, chId, flipX,flipY,swapXY);
    +                break;
    +            }
     #endif
                 }
         }
    diff --git a/mcfw/interfaces/link_api/swMsLink.h b/mcfw/interfaces/link_api/swMsLink.h
    index d20e89f..ccd5f1a 100755
    --- a/mcfw/interfaces/link_api/swMsLink.h
    +++ b/mcfw/interfaces/link_api/swMsLink.h
    @@ -184,6 +184,12 @@
     */
     #define SYSTEM_SW_MS_LINK_CMD_GET_TIME_INFO_OF_DISP_CH     (0x800B)
     
    +/**
    +    \brief SWMS cmd to rotate the image.Possible only when input is tiled.
    +    \param  SwMsLink_ChRotateParams * [IN] Channel rotate parameters.
    +*/
    +#define SYSTEM_SW_MS_LINK_CMD_IMAGE_ROTATE_CMD     (0x800C)
    +
     /* @} */
     
     /**
    @@ -456,6 +462,31 @@ typedef struct SwMsLink_ChTimeParams
         /**< PTS is valid only if this flag is 1 */
     
     } SwMsLink_ChTimeParams;
    +
    +
    +/**
    +    \brief SwMs Link channel rotate params
    +
    +    Defines SwMs channel image rotate parameters that can be changed dynamically
    +    on a per channel basis
    +    Rotation is done via tiler and is applicable only when input for the specified
    +    channel is in tiled format.
    +*/
    +typedef struct SwMsLink_ChRotateParams
    +{
    +    UInt32 chId;
    +    /**< SwMs channel number */
    +
    +    UInt32 flipX;
    +    /**< Flag indicating if X coordinate should be flipped (Vertical mirror) */
    +
    +    UInt32 flipY;
    +    /**< Flag indicating if Y coordinate should be flipped (Horizontal mirror)  */
    +
    +    UInt32 swapXY;
    +    /**< Flag indicating if X and Y coordinate should be swapped  */
    +} SwMsLink_ChRotateParams;
    +
     /**
     *   \brief SWMS link register and init
     
    diff --git a/mcfw/interfaces/ti_vdis.h b/mcfw/interfaces/ti_vdis.h
    index 28b6a06..13bb455 100755
    --- a/mcfw/interfaces/ti_vdis.h
    +++ b/mcfw/interfaces/ti_vdis.h
    @@ -1265,6 +1265,26 @@ Int32 Vdis_setEdeStrength(int edeStrength);
      */
     Int32 Vdis_setCprocConfig(int cprocConfig);
     
    +
    +/**
    + * \brief:
    + *      Function to configure video frame rotation using tiler
    + * \input:
    + *      vdDevId             -- Display id
    + *      chId                -- channel Id
    + *      flipX               -- Flip image on X-direction (TRUE/FALSE)
    + *      flipY               -- Flip image on Y-direction (TRUE/FALSE)
    + *      swapXY              -- Swap X,Y cordiates (TRUE/FALSE)
    + *
    + * \output:
    + *      NA
    + * \return
    +*       TI_MEDIA_SUCCESS    --  while success
    +*       ERROR_CODE          --  refer for err defination
    +*/
    +Int32 Vdis_setRotateConfig(VDIS_DEV vdDevId, UInt32 chId,UInt32 flipX,UInt32 flipY,UInt32 swapXY);
    +
    +
     #ifdef __cplusplus
     }
     #endif /* __cplusplus */
    diff --git a/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_drv.c b/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_drv.c
    index 1a05f21..287a6b1 100755
    --- a/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_drv.c
    +++ b/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_drv.c
    @@ -830,6 +830,15 @@ Int32 SwMsLink_drvModifyFramePointer(SwMsLink_Obj * pObj, SwMsLink_DrvObj *pDrvO
                 offset[1] = rtChannelInfo->pitch[1]*rtChannelInfo->startY/2  +
                                            rtChannelInfo->startX*bytesPerPixel;
     
    +            if ((rtChannelInfo->memType == VPS_VPDMA_MT_TILEDMEM)
    +                &&
    +                (UTILS_TILER_ORI_XY_SWAP & pObj->chObj[pObj->layoutParams.winInfo[windId].channelNum].rotateMask))
    +            {
    +                offset[0] = (UTILS_TILER_CNT_8BIT_PITCH_XY_SWAP*rtChannelInfo->startX)    +
    +                                           rtChannelInfo->startY*bytesPerPixel;
    +                offset[1] = (UTILS_TILER_CNT_16BIT_PITCH_XY_SWAP*rtChannelInfo->startX)/2  +
    +                                           rtChannelInfo->startY*bytesPerPixel;
    +            }
                 if(addOffset == FALSE)
                 {
                     offset[0] = -offset[0];
    @@ -858,6 +867,27 @@ Int32 SwMsLink_drvModifyFramePointer(SwMsLink_Obj * pObj, SwMsLink_DrvObj *pDrvO
                           (Ptr) ((Int32)pDrvObj->inFrameList.frames[frameId]->addr[0][0] + offset[0]);
                        pDrvObj->inFrameList.frames[frameId]->addr[0][1] =
                             (Ptr) ((Int32)pDrvObj->inFrameList.frames[frameId]->addr[0][1] + offset[1]);
    +                   if ((rtChannelInfo->memType == VPS_VPDMA_MT_TILEDMEM)
    +                       &&
    +                       (pObj->chObj[pObj->layoutParams.winInfo[windId].channelNum].rotateMask != UTILS_TILER_ORI_NONE))
    +                   {
    +                       if (addOffset)
    +                       {
    +                           UInt32 rotateMask = pObj->chObj[pObj->layoutParams.winInfo[windId].channelNum].rotateMask;
    +
    +                           pDrvObj->inFrameList.frames[frameId]->addr[0][0] =
    +                             (Ptr) (Utils_tilerGetOriAddr((UInt32)pDrvObj->inFrameList.frames[frameId]->addr[0][0],UTILS_TILER_CNT_8BIT,rotateMask,rtChannelInfo->width,rtChannelInfo->height));
    +                           pDrvObj->inFrameList.frames[frameId]->addr[0][1] =
    +                             (Ptr) (Utils_tilerGetOriAddr(((UInt32)pDrvObj->inFrameList.frames[frameId]->addr[0][1]),UTILS_TILER_CNT_16BIT,rotateMask,rtChannelInfo->width,rtChannelInfo->height/2));
    +                       }
    +                       else
    +                       {
    +                           pDrvObj->inFrameList.frames[frameId]->addr[0][0] =
    +                             (Ptr) (Utils_tilerGetNaturalAddr((UInt32)pDrvObj->inFrameList.frames[frameId]->addr[0][0]));
    +                           pDrvObj->inFrameList.frames[frameId]->addr[0][1] =
    +                             (Ptr) (Utils_tilerGetNaturalAddr((UInt32)pDrvObj->inFrameList.frames[frameId]->addr[0][1]));
    +                       }
    +                   }
                    }
                 }
     
    @@ -1427,6 +1457,19 @@ Int32 SwMsLink_drvSwitchLayout(SwMsLink_Obj * pObj,
                 pWinObj->scRtInFrmPrm.dataFormat = pChInfo->dataFormat;
     
                 pObj->chObj[chNum].displayStarted = FALSE;
    +            if ((pChInfo->memType == VPS_VPDMA_MT_TILEDMEM) &&
    +                (UTILS_TILER_ORI_XY_SWAP & pObj->chObj[chNum].rotateMask))
    +            {
    +                UInt32 tempWidth = pWinObj->scRtInFrmPrm.width;
    +                UInt32 tempCropWidth = pWinObj->scRtCropCfg.cropWidth;
    +
    +                pWinObj->scRtInFrmPrm.width =   pWinObj->scRtInFrmPrm.height;
    +                pWinObj->scRtInFrmPrm.height =  tempWidth;
    +                pWinObj->scRtCropCfg.cropWidth = pWinObj->scRtCropCfg.cropHeight;
    +                pWinObj->scRtCropCfg.cropHeight = tempCropWidth;
    +                pWinObj->scRtInFrmPrm.pitch[0] = UTILS_TILER_CNT_8BIT_PITCH_XY_SWAP;
    +                pWinObj->scRtInFrmPrm.pitch[1] = UTILS_TILER_CNT_16BIT_PITCH_XY_SWAP;
    +            }
     
             }
     
    @@ -1460,12 +1503,12 @@ Int32 SwMsLink_drvSwitchLayout(SwMsLink_Obj * pObj,
                                 * make S/W mosaic. This is sometimes needed due to SC
                                * performance. */
                     if ((FVID2_SF_PROGRESSIVE ==
    -                     pObj->inQueInfo.chInfo[chNum].scanFormat)
    +                        pObj->rtChannelInfo[chNum].scanFormat)
                                 &&
                         pObj->layoutParams.winInfo[winId].bypass
                                 &&
                         VPS_VPDMA_MT_NONTILEDMEM ==
    -                            pObj->inQueInfo.chInfo[chNum].memType
    +                            pObj->rtChannelInfo[chNum].memType
                         )
                     {
                         pWinObj->scRtCropCfg.cropStartY /= 2;
    @@ -1491,10 +1534,10 @@ Int32 SwMsLink_drvSwitchLayout(SwMsLink_Obj * pObj,
                           * make S/W mosaic. This is sometimes needed due to SC
                           * performance. */
                 if ((FVID2_SF_PROGRESSIVE ==
    -                 pObj->inQueInfo.chInfo[chNum].scanFormat) &&
    +                    pObj->rtChannelInfo[chNum].scanFormat) &&
                     pObj->layoutParams.winInfo[winId].bypass   &&
                     VPS_VPDMA_MT_NONTILEDMEM ==
    -                            pObj->inQueInfo.chInfo[chNum].memType)
    +                        pObj->rtChannelInfo[chNum].memType)
                 {
                     pWinObj->scRtCropCfg.cropStartY /= 2;
                     pWinObj->scRtCropCfg.cropHeight /= 2;
    @@ -1664,7 +1707,7 @@ Int32 SwMsLink_drvCreateChannelObj(SwMsLink_Obj * pObj)
             pObj->chObj[i].displayStarted = FALSE;
             pObj->chObj[i].doFrameSkip = FALSE;
             pObj->chObj[i].hmpCrop.enableHMPCropFlag = FALSE;
    -
    +        pObj->chObj[i].rotateMask = UTILS_TILER_ORI_NONE;
         }
         pObj->lastOutBufPtr = NULL;
         pObj->lastDisplayCBTS = 0;
    @@ -3610,6 +3653,8 @@ Int32 SwMsLink_drvMakeFrameLists(SwMsLink_Obj * pObj, FVID2_Frame * pOutFrame)
                         {
                             rtChannelInfo->scanFormat =
                                 pFrameInfo->rtChInfo.scanFormat;
    +                        pObj->inQueInfo.chInfo[pInFrame->channelNum].scanFormat =
    +                            pFrameInfo->rtChInfo.scanFormat;
                             rtParamUpdatePerFrame = TRUE;
                             Vps_printf(" SWMS: ch:%d ScanFormat changed to %s....***\n",
                                 pInFrame->channelNum, 
    @@ -3628,6 +3673,8 @@ Int32 SwMsLink_drvMakeFrameLists(SwMsLink_Obj * pObj, FVID2_Frame * pOutFrame)
                         {
                             rtChannelInfo->memType =
                                 pFrameInfo->rtChInfo.memType;
    +                        pObj->inQueInfo.chInfo[pInFrame->channelNum].memType =
    +                            pFrameInfo->rtChInfo.memType;
                             rtParamUpdatePerFrame = TRUE;
                         }
                         pFrameInfo->isDataTypeChange = FALSE;
    @@ -4808,3 +4855,41 @@ Int32 SwMsLink_drvGetInputChTimeInfo(SwMsLink_Obj *pObj, SwMsLink_ChTimeParams *
         return FVID2_SOK;
     }
     
    +Int32 SwMsLink_drvSetRotateParams(SwMsLink_Obj *pObj, SwMsLink_ChRotateParams *chRotateParams)
    +{
    +    UTILS_assert(chRotateParams != NULL);
    +
    +    SwMsLink_drvLock(pObj);
    +
    +    if (chRotateParams->chId < pObj->inQueInfo.numCh)
    +    {
    +        UInt32 prevMask = pObj->chObj[chRotateParams->chId].rotateMask;
    +
    +        pObj->chObj[chRotateParams->chId].rotateMask = UTILS_TILER_ORI_NONE;
    +
    +        if (chRotateParams->flipX)
    +        {
    +            pObj->chObj[chRotateParams->chId].rotateMask |= UTILS_TILER_ORI_X_FLIP;
    +        }
    +        if (chRotateParams->flipY)
    +        {
    +            pObj->chObj[chRotateParams->chId].rotateMask |= UTILS_TILER_ORI_Y_FLIP;
    +        }
    +        if (chRotateParams->swapXY)
    +        {
    +            pObj->chObj[chRotateParams->chId].rotateMask |= UTILS_TILER_ORI_XY_SWAP;
    +        }
    +        if ((prevMask & UTILS_TILER_ORI_XY_SWAP) ^ (pObj->chObj[chRotateParams->chId].rotateMask & UTILS_TILER_ORI_XY_SWAP))
    +        {
    +            Vps_printf("%d:SWMS:Ch [%d] Changes in X-Y orientation from %d to %d",
    +                       Utils_getCurTimeInMsec(),
    +                       chRotateParams->chId,
    +                       (prevMask & UTILS_TILER_ORI_XY_SWAP),
    +                       (pObj->chObj[chRotateParams->chId].rotateMask & UTILS_TILER_ORI_XY_SWAP));
    +            pObj->scChMapRtParamUpdate = TRUE;
    +        }
    +    }
    +    SwMsLink_drvUnlock(pObj);
    +    return FVID2_SOK;
    +}
    +
    diff --git a/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_priv.h b/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_priv.h
    index 14a008a..760a00b 100755
    --- a/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_priv.h
    +++ b/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_priv.h
    @@ -179,6 +179,7 @@ typedef struct SwMsLink_chObj
         Bool   displayStarted; 
         UInt64 firstPTS;
         UInt64 currPTS; 
    +    UInt32 rotateMask;
     } SwMsLink_chObj;
     
     
    @@ -436,6 +437,8 @@ Int32 SwMsLink_drvSetChannelMapParams(SwMsLink_Obj * pObj,
     
     Int32 SwMsLink_drvGetInputChTimeInfo(SwMsLink_Obj *pObj, SwMsLink_ChTimeParams *chParams);
     
    +Int32 SwMsLink_drvSetRotateParams(SwMsLink_Obj *pObj, SwMsLink_ChRotateParams *chRotateParams);
    +
     #endif
     
     
    diff --git a/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_tsk.c b/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_tsk.c
    index 2e81901..d4a940e 100755
    --- a/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_tsk.c
    +++ b/mcfw/src_bios6/links_m3vpss/swMs/swMsLink_tsk.c
    @@ -155,7 +155,11 @@ Int32 SwMsLink_tskRun(SwMsLink_Obj * pObj, Utils_TskHndl * pTsk,
                      status = SwMsLink_drvGetInputChTimeInfo(pObj, pPrm);
                      Utils_tskAckOrFreeMsg(pRunMsg, status);
                      break;
    -
    +            case SYSTEM_SW_MS_LINK_CMD_IMAGE_ROTATE_CMD:
    +                pPrm = Utils_msgGetPrm(pRunMsg);
    +                status = SwMsLink_drvSetRotateParams(pObj, pPrm);
    +                Utils_tskAckOrFreeMsg(pRunMsg, status);
    +                break;
                 default:
                     Utils_tskAckOrFreeMsg(pRunMsg, status);
                     break;
    diff --git a/mcfw/src_bios6/utils/src/utils_tiler.c b/mcfw/src_bios6/utils/src/utils_tiler.c
    index 241fe5d..4b7a5f9 100755
    --- a/mcfw/src_bios6/utils/src/utils_tiler.c
    +++ b/mcfw/src_bios6/utils/src/utils_tiler.c
    @@ -9,6 +9,37 @@
     #include <mcfw/interfaces/link_api/system_tiler.h>
     #include <mcfw/interfaces/link_api/system_debug.h>
     
    +
    +#define UTILS_TILER_VIRTADDR_NUMBITS              (27)
    +#define UTILS_TILER_VIRTADDR_X_COORDINATE_NUMBITS (14)
    +#define UTILS_TILER_VIRTADDR_Y_COORDINATE_NUMBITS (UTILS_TILER_VIRTADDR_NUMBITS - UTILS_TILER_VIRTADDR_X_COORDINATE_NUMBITS)
    +#define UTILS_TILER_MASK_XY_FLIP                  (UTILS_TILER_ORI_XY_SWAP << UTILS_TILER_ORI_MODE_SHIFT)
    +#define UTILS_TILER_MASK_Y_INVERT                 (UTILS_TILER_ORI_Y_FLIP  << UTILS_TILER_ORI_MODE_SHIFT)
    +#define UTILS_TILER_MASK_X_INVERT                 (UTILS_TILER_ORI_X_FLIP << UTILS_TILER_ORI_MODE_SHIFT)
    +#define UTILS_TILER_MASK(bits)                    ((1u << (bits)) - 1u)
    +#define UTILS_TILER_VIEW_SIZE                     (1u << (UTILS_TILER_VIRTADDR_NUMBITS))
    +#define UTILS_TILER_VIEW_MASK                     (UTILS_TILER_VIEW_SIZE - 1u)
    +/* create tsptr by adding view orientation and access mode */
    +#define UTILS_TILER_ADDR(x, orient, a)            ((UInt32) (x) | (orient) | ((a) << UTILS_TILER_VIRTADDR_NUMBITS))
    +
    +
    +typedef struct UtilsTilerGeometry_s
    +{
    +    UInt32 x_shift;
    +    UInt32 y_shift;
    +} UtilsTilerGeometry_s;
    +
    +UtilsTilerGeometry_s UtilsTilerGeometry[UTILS_TILER_CNT_MAX] =
    +{
    +  [UTILS_TILER_CNT_8BIT]  = {.x_shift =  0,
    +                             .y_shift = 0},
    +  [UTILS_TILER_CNT_16BIT] = {.x_shift =  0,
    +                             .y_shift = 1},
    +  [UTILS_TILER_CNT_32BIT] = {.x_shift =  1,
    +                             .y_shift = 1}
    +};
    +
    +
     UInt32 Utils_tilerAddr2CpuAddr(UInt32 tilerAddr)
     {
         UInt32 cpuAddr, cntMode;
    @@ -73,6 +104,66 @@ Int32 Utils_tilerGetMaxPitch(UInt32 cntMode, UInt32 * maxPitch)
         return 0;
     }
     
    +/* calculate the tiler space address of a pixel in a view orientation */
    +static
    +UInt32 Utils_tilerGetAddress(UInt32 oriFlag, UInt32  cntMode, UInt32 x, UInt32 y)
    +{
    +    UInt32 x_bits, y_bits, tmp, x_mask, y_mask, alignment;
    +
    +    x_bits = UTILS_TILER_VIRTADDR_X_COORDINATE_NUMBITS - UtilsTilerGeometry[cntMode].x_shift;
    +    y_bits = UTILS_TILER_VIRTADDR_Y_COORDINATE_NUMBITS - UtilsTilerGeometry[cntMode].y_shift;
    +    alignment = UtilsTilerGeometry[cntMode].x_shift + UtilsTilerGeometry[cntMode].y_shift;
    +
    +    /* validate coordinate */
    +    x_mask = UTILS_TILER_MASK(x_bits);
    +    y_mask = UTILS_TILER_MASK(y_bits);
    +
    +    /* account for mirroring */
    +    if (oriFlag & UTILS_TILER_MASK_X_INVERT)
    +        x ^= x_mask;
    +    if (oriFlag & UTILS_TILER_MASK_Y_INVERT)
    +        y ^= y_mask;
    +
    +    /* get coordinate address */
    +    if (oriFlag & UTILS_TILER_MASK_XY_FLIP)
    +        tmp = ((x << y_bits) + y);
    +    else
    +        tmp = ((y << x_bits) + x);
    +
    +    return UTILS_TILER_ADDR((tmp << alignment), oriFlag, cntMode);
    +}
    +
    +static
    +Void   Utils_tilerGetNaturalXY(UInt32 tilerAddr,
    +                               UInt32 *x,
    +                               UInt32 *y)
    +{
    +    UInt32 x_bits, y_bits, offset;
    +    UInt32 cntMode;
    +
    +    cntMode = UTILS_TILER_GET_CNT_MODE(tilerAddr);
    +
    +    x_bits = UTILS_TILER_VIRTADDR_X_COORDINATE_NUMBITS - UtilsTilerGeometry[cntMode].x_shift;
    +    y_bits = UTILS_TILER_VIRTADDR_Y_COORDINATE_NUMBITS - UtilsTilerGeometry[cntMode].y_shift;
    +    offset = (tilerAddr & UTILS_TILER_VIEW_MASK) >>
    +             (UtilsTilerGeometry[cntMode].x_shift + UtilsTilerGeometry[cntMode].y_shift);
    +
    +    /* separate coordinate bitfields based on view orientation */
    +    if (tilerAddr & UTILS_TILER_MASK_XY_FLIP) {
    +        *x = offset >> y_bits;
    +        *y = offset & UTILS_TILER_MASK(y_bits);
    +    } else {
    +        *x = offset & UTILS_TILER_MASK(x_bits);
    +        *y = offset >> x_bits;
    +    }
    +
    +    /* account for mirroring */
    +    if (tilerAddr & UTILS_TILER_MASK_X_INVERT)
    +        *x ^= UTILS_TILER_MASK(x_bits);
    +    if (tilerAddr & UTILS_TILER_MASK_Y_INVERT)
    +        *y ^= UTILS_TILER_MASK(y_bits);
    +}
    +
     UInt32 Utils_tilerGetOriAddr(UInt32 tilerAddr,
                                  UInt32 cntMode,
                                  UInt32 oriFlag, UInt32 width, UInt32 height)
    @@ -123,16 +214,32 @@ UInt32 Utils_tilerGetOriAddr(UInt32 tilerAddr,
             oriAddr += hOffset;
         }
     
    +    /* Set the container mode */
    +    oriAddr = UTILS_TILER_PUT_CNT_MODE(oriAddr, cntMode);
         /* Set the orientation modes */
         oriAddr &= ~UTILS_TILER_ORI_MODE_MASK;
    -    oriAddr |= (oriFlag << UTILS_TILER_ORI_MODE_SHIFT);
    +    if (oriFlag & UTILS_TILER_ORI_XY_SWAP)
    +    {
    +        UInt32 x,y;
     
    -    /* Set the container mode */
    -    oriAddr = UTILS_TILER_PUT_CNT_MODE(oriAddr, cntMode);
    +        Utils_tilerGetNaturalXY(oriAddr,&x,&y);
    +        oriAddr = Utils_tilerGetAddress(UTILS_TILER_MASK_XY_FLIP,cntMode,x,y);
    +    }
    +    oriAddr |= (oriFlag << UTILS_TILER_ORI_MODE_SHIFT);
     
         return (oriAddr);
     }
     
    +UInt32 Utils_tilerGetNaturalAddr(UInt32 tilerAddr)
    +{
    +    UInt32 x,y;
    +    UInt32 cntMode;
    +
    +    Utils_tilerGetNaturalXY(tilerAddr,&x,&y);
    +    cntMode = UTILS_TILER_GET_CNT_MODE(tilerAddr);
    +    return Utils_tilerGetAddress(UTILS_TILER_ORI_NONE,cntMode,x,y);
    +}
    +
     extern void System_memPrintHeapStatus();
     
     Int32 Utils_tilerFrameAlloc(FVID2_Format * pFormat,
    diff --git a/mcfw/src_bios6/utils/utils_tiler.h b/mcfw/src_bios6/utils/utils_tiler.h
    index 8733dca..a2364d7 100755
    --- a/mcfw/src_bios6/utils/utils_tiler.h
    +++ b/mcfw/src_bios6/utils/utils_tiler.h
    @@ -40,6 +40,13 @@
     #define UTILS_TILER_CNT_16BIT_MAX_LINES  (4096u)
     #define UTILS_TILER_CNT_32BIT_MAX_LINES  (4096u)
     
    +#define UTILS_TILER_CNT_8BIT_PITCH   (VPSUTILS_TILER_CNT_8BIT_PITCH)
    +#define UTILS_TILER_CNT_16BIT_PITCH  (VPSUTILS_TILER_CNT_16BIT_PITCH)
    +
    +#define UTILS_TILER_CNT_8BIT_PITCH_XY_SWAP  (8 * 1024)
    +#define UTILS_TILER_CNT_16BIT_PITCH_XY_SWAP (8 * 1024)
    +
    +
     #define UTILS_TILER_ORI_MODE_SHIFT   (29u)
     #define UTILS_TILER_ORI_MODE_MASK    (0x07u << UTILS_TILER_ORI_MODE_SHIFT)
     
    @@ -136,6 +143,15 @@ Int32 Utils_tilerFrameFree(FVID2_Format * pFormat,
     */
     UInt32 Utils_tilerCpuAddr2TilerAddr(UInt32 cpuAddr);
     
    +/**
    + *  \brief Get 0 degree natural tiler address for the given tiler addr
    + *
    + *  \param tilerAddr      [IN] Tiler address of any orientation
    + *
    + *  \return Natural View Tiler address for the given tiler Addr
    +*/
    +UInt32 Utils_tilerGetNaturalAddr(UInt32 tilerAddr);
    +
     #endif
     
     /* @} */
    diff --git a/mcfw/src_linux/mcfw_api/ti_vdis.c b/mcfw/src_linux/mcfw_api/ti_vdis.c
    index e68cfdc..b20b036 100755
    --- a/mcfw/src_linux/mcfw_api/ti_vdis.c
    +++ b/mcfw/src_linux/mcfw_api/ti_vdis.c
    @@ -3870,3 +3870,33 @@ Int32 Vdis_setCprocConfig(int config)
         return status;
     }
     
    +
    +Int32 Vdis_setRotateConfig(VDIS_DEV vdDevId, UInt32 chId,UInt32 flipX,UInt32 flipY,UInt32 swapXY)
    +{
    +    Int status = ERROR_NONE;
    +    SwMsLink_ChRotateParams chRotatePrms;
    +
    +    if ((Vdis_getDisplayContextIndex(vdDevId) < OSA_ARRAYSIZE(gVdisModuleContext.displayId)
    +        &&
    +        (SYSTEM_LINK_ID_INVALID != Vdis_getSwMsId(vdDevId))))
    +    {
    +        memset(&chRotatePrms,0,sizeof(chRotatePrms));
    +        chRotatePrms.chId =  chId;
    +        chRotatePrms.flipX = flipX;
    +        chRotatePrms.flipY = flipY;
    +        chRotatePrms.swapXY = swapXY;
    +        status =
    +        System_linkControl(Vdis_getSwMsId(vdDevId),
    +                           SYSTEM_SW_MS_LINK_CMD_IMAGE_ROTATE_CMD,
    +                           &chRotatePrms,
    +                           sizeof(chRotatePrms), TRUE);
    +    }
    +    else
    +    {
    +        status = ERROR_FAIL;
    +    }
    +
    +    return status;
    +}
    +
    +
    

  • Thanks for your  reply.

    1,

    Now, I used the DVR RDK 3.0, could I use function Utils_tilerGetNaturalXY and Utils_tilerGetAddress as your patch.

    I want to know if it have some differences the utils_tiler.c and utils_tiler.h between RDK3.0 and RDK 4.1.

    And, I used the tiler for the 90 degree rotation, and my chain as follow:

    capture --> mpsclr --> sclr -->nsf --> sclr --> nsf --> framesout ...

    the capture output: YUV420SP, 2592*1936, non-tilered memory

    the mpsclr output: YUV422I, 1920*1080, non-tilered memory

    the sclr1 output: YUV422I, 1024*960, non-tilered memory

    the nsf1 output:  YUV420SP, tilered memory (if  its resolution would be changed to 960*1024)

    the sclr2 input: YUV420SP, tilered memory (if  its resolution would be changed to 960*1024) 

    the sclr2 output: YUV422I, 1920*1080, non-tilered memory

    ...

    At sclr2 link, I modify the resolution first, and I write the register of tiler and translate the addr used by Utils_tilerGetOriAddr function on the function SclrLink_drvQueueFramesToChQue() as follow:

    *(volatile unsigned *)0x4E000224 = 0xE000;

    oriBufOffsetY = Utils_tilerGetOriAddr((Int32)(virFrame.addr[0][0]), 0, 6, width, height);
    oriBufOffsetC = Utils_tilerGetOriAddr((Int32)(virFrame.addr[0][1]), 1, 6, widthYC, heightYC);
    virFrame.addr[0][0] = (Ptr)Utils_tilerAddr2CpuAddr((Int32)oriBufOffsetY);
    virFrame.addr[0][1] = (Ptr)Utils_tilerAddr2CpuAddr((Int32)oriBufOffsetC);

    Could you give some advices about that. Mayby I must translate the address as your patch?

    2,

    I have a question about the pitch of Y and CbCr when I enable tiler.

    If I want to 90 degree rotation, the pitch of Y is 8192 and the pitch of CbCr is 8192?

    However, I found when I alloc tiler memory the pitch would by 16384 and 32768 at the NSF1 Link.

    Should I modfiy the pitch on it nextLink sclr2Link when the sclr2Link create the FvidHandle and MakeFrameList and so on?

    3,

    I have another question, could I enable the tiler at the captureLink, and the resolution of capture is 2592*1936, when I enable tiler, the fifo would be overflowed and reset the VIP port.

    4,

    I try build a chain as follow:

    capture --> nsf -->mpsclr ...

    And enable the tiler at the nsfLink, the capture resolution is 2592*1936, and the nsf input resolution is 2592*1936.

    The input resolution of NsfLink could be 2592*1936?

    Thanks,

    Tianxing

  • RDK 3.0 is not supported . You have to migrate to RDK 4.1 and apply the patch.

    tianxing hou said:

    At sclr2 link, I modify the resolution first, and I write the register of tiler and translate the addr used by Utils_tilerGetOriAddr function on the function SclrLink_drvQueueFramesToChQue() as follow:

    *(volatile unsigned *)0x4E000224 = 0xE000;

    oriBufOffsetY = Utils_tilerGetOriAddr((Int32)(virFrame.addr[0][0]), 0, 6, width, height);
    oriBufOffsetC = Utils_tilerGetOriAddr((Int32)(virFrame.addr[0][1]), 1, 6, widthYC, heightYC);
    virFrame.addr[0][0] = (Ptr)Utils_tilerAddr2CpuAddr((Int32)oriBufOffsetY);
    virFrame.addr[0][1] = (Ptr)Utils_tilerAddr2CpuAddr((Int32)oriBufOffsetC);

    Could you give some advices about that. Mayby I must translate the address as your patch?

    Changes are wrong. First don't write anything to any register. Second refer the changes in SwMs for the correct changes.

    To do rotation you have to do the following:

    1. COnvert natural address to rotated address by modifying the input buffer address as shown in the patch.

    2. Adjust width,height,pitch as shown in the patch

    3. Invoke FVID2_processCall.

    4. Restore address back to natural address before freeing the input frame after the FVID2_processCall.

    Don't invoke Utils_tilerAddr2CpuAddr. It has no meaning to translate to CPU address when using HDVPSS.

     

    tianxing hou said:

    2,

    I have a question about the pitch of Y and CbCr when I enable tiler.

    If I want to 90 degree rotation, the pitch of Y is 8192 and the pitch of CbCr is 8192?

    However, I found when I alloc tiler memory the pitch would by 16384 and 32768 at the NSF1 Link.

    Should I modfiy the pitch on it nextLink sclr2Link when the sclr2Link create the FvidHandle and MakeFrameList and so on?

    Refer the patch. Pitch is 8192,8192 in rotated view and should be set correctly in Sclr link before FVID2_process call. There is no need to change tiled allocation. Allocation is in natural view.

     

    tianxing hou said:

    3,

    I have another question, could I enable the tiler at the captureLink, and the resolution of capture is 2592*1936, when I enable tiler, the fifo would be overflowed and reset the VIP port.

    Yes enabling tiler on capture  port will result in VIP overflow when using a particular VIP port

     

    tianxing hou said:

    4,

    I try build a chain as follow:

    capture --> nsf -->mpsclr ...

    And enable the tiler at the nsfLink, the capture resolution is 2592*1936, and the nsf input resolution is 2592*1936.

    The input resolution of NsfLink could be 2592*1936?

    . This is a silicon issue.

     

    All HDVPSS links require support max input of 1920x1080 only so NSF cannot take input of 2592x1936 .It has not been tested.

  • Thanks for your reply, it help me resolved my problem. I have some pointers should be confirmed at for further.
    Thanks again, it is so critical for us.

    Regards,
    Tianxing

  • 1,

    I have another question about the sclr link.

    The normal image(no rotationed) as follow:


    However, when I rescale the image to 1920*1080 used the sclr2, the image would be deformed as follow:

    Now, I want to modify the chain as follow:
    capture --> mpsclr --> sclr -->nsf --> sclr --> nsf --> framesout ...

    the capture output: YUV420SP, 2592*1936, non-tilered memory

    the mpsclr output: YUV422I, 1920*1080, non-tilered memory

    the sclr1 output: YUV422I, 960*1024, non-tilered memory

    the nsf1 output: YUV420SP, tilered memory, resolution is 1024*960

    the sclr2 input: YUV420SP, tilered memory, resolution is 1024*960

    the sclr2 output: YUV422I, 1024*1920, non-tilered memory
    I have a question about the sclr link, its output resolution could be 1024*1920?

    2,

    I have a question about the deiLink.

    Could the deiLink input resolution be more than 1920*1080? For example, the input resolution is 2592*1936, and its prevLink is CaptureLink, I just enable the DEI_LINK_OUT_QUE_VIP_SC。

    I want to implement the chain as follow:

    capture --> dei1 -- > dei2 --> dup --> ...

    the parameters as follow:

    capture, output YUV420SP, non-tilered, 2592*1936

    dei1, input YUV420SP, non-tilered, 2592*1936

              output YUV420SP, tilered, 1936*2592

    dei2, input YUV420SP, tilered, 1936*2592

              output YUV420SP, non-tilered, 1936*2592

    Now, I have implemented the chain as follow:

    capture --> dei --> dup...

    When I implemented the capture --> dei --> dei --> dup, it would be errored! The message as follow:


    946:!!!SLAVE CORE [VPSS-M3] DOWN!!!
    SystemLink_copySlaveCoreExceptionContext:146
    mmap of [0xbe9e0000:36864]
    mmap virt addresss:0x4005a000
    munmap of [0x4005a000:36864]
    SystemLink_copySlaveCoreExceptionContext:153
    [m3vpss ] 12567: DEI : Loading Down-scaling Co-effs
    [m3vpss ] 12567: DEI : Co-effs Loading ... DONE !!!
    [m3vpss ] DEI:HEAPID:0 USED:64
    [m3vpss ] DEI:HEAPID:1 USED:4832
    [m3vpss ] 12567: DEI : Create Done !!!
    [m3vpss ] 12567: DEI : Create in progress !!!
    [m3vpss ] 12568: Assertion @ Line: 828 in links_m3vpss/dei/deiLink_drv.c: pObj->fvidHandle != NULL : failed !!!
    mmap base :a8000000
    pmapAddr =402cf000,errno 0 Success
    stream_cmd_process_thread start