Home | History | Annotate | Download | only in src
      1 
      2 /*
      3  * Copyright (C) Texas Instruments - http://www.ti.com/
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Lesser General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2.1 of the License, or (at your option) any later version.
      9  *
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Lesser General Public License for more details.
     15  *
     16  *
     17  * You should have received a copy of the GNU Lesser General Public
     18  * License along with this library; if not, write to the Free Software
     19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     20  */
     21 /* ==============================================================================
     22 *             Texas Instruments OMAP (TM) Platform Software
     23 *  (c) Copyright Texas Instruments, Incorporated.  All Rights Reserved.
     24 *
     25 *  Use of this software is controlled by the terms and conditions found
     26 *  in the license agreement under which this software has been supplied.
     27 * ============================================================================ */
     28 /**
     29 * @file OMX_VPP_imgConv.c
     30 *
     31 * This file implements OMX Component for VPP that
     32 * is  compliant with the OMX khronos 1.0.
     33 *
     34 * @path  $(CSLPATH)\
     35 *
     36 * @rev  1.0
     37 */
     38 /* ----------------------------------------------------------------------------
     39 *!
     40 *! Revision History
     41 *! ===================================
     42 *! 17-april-2005 mf:  Initial Version. Change required per OMAPSWxxxxxxxxx
     43 *! to provide _________________.
     44 *!
     45 * ============================================================================= */
     46 #ifdef UNDER_CE
     47 #include <windows.h>
     48 #include <oaf_osal.h>
     49 #include <omx_core.h>
     50 #include <stdlib.h>
     51 #else
     52 #include <unistd.h>
     53 #include <sys/types.h>
     54 #include <malloc.h>
     55 #include <memory.h>
     56 #include <sys/types.h>
     57 #include <sys/stat.h>
     58 #include <fcntl.h>
     59 #endif
     60 #include <dbapi.h>
     61 #include <string.h>
     62 #include <stdio.h>
     63 
     64 #include "OMX_VPP.h"
     65 #include "OMX_VPP_Utils.h"
     66 #include <OMX_Component.h>
     67 
     68 typedef enum {
     69   ENoFilter,EScanAlgo
     70 }eFilterAlgoOption;
     71 
     72 const OMX_S32 KDeepFiltering        = 3 ;   /* Number of chrominance artefact redution algorithm scans */
     73 const OMX_U8  KColorKeyTolerence    = 50 ;  /* Tolerence on Color key detection                        */
     74 const OMX_S32 KColorKeyChannelPred  = 150 ; /* Color channel predominance detection                    */
     75 const OMX_S32 KColorKeyChannelMin   = 75 ;  /* Color channel predominance detection                    */
     76 const OMX_S32 KAlgoLumaTolerence    = 600 ; /* Tolerence on luminance to detect pixel near color key   */
     77 const OMX_S32 KAlgoChromaTolerance  = 50 ;  /* Tolerence on chrominance to detect pixel near color key */
     78 const OMX_S32 KqCifWidth            = 176 ;
     79 const OMX_S32 KqCifHeight           = 144 ;
     80 const OMX_S32 KCifWidth             = 352 ;
     81 const OMX_S32 KCifHeight            = 288 ;
     82 const OMX_S32 KInterlacedTiFormat   = 1 ;
     83 const OMX_S32 iFilteringAlgoEnable  = EScanAlgo;
     84 
     85 
     86 
     87 static void ConvertChromReduction(VPP_COMPONENT_PRIVATE *pComponentPrivate);
     88 static void ConvertFormatFromPlanar(OMX_U8 *apInBufferYUV420W, OMX_U8 *apTIinternalFormat);
     89 static void ConvertNoChromReduction(VPP_COMPONENT_PRIVATE *pComponentPrivate);
     90 
     91 
     92 
     93 OMX_ERRORTYPE ComputeTiOverlayImgFormat (VPP_COMPONENT_PRIVATE *pComponentPrivate,OMX_U8* aPictureArray, OMX_U8* aOutImagePtr, OMX_U8* aTransparencyKey )
     94 {
     95 
     96     OMX_ERRORTYPE eError = OMX_ErrorUndefined;
     97     OMX_U32 iHeight;
     98     OMX_U32 iWidth;
     99 
    100     /*If pointer was allocated in a previous call, free it to avoid memory leaks*/
    101     if(pComponentPrivate->overlay){
    102         if(pComponentPrivate->overlay->iOvlyConvBufPtr){
    103             OMX_FREE(pComponentPrivate->overlay->iOvlyConvBufPtr);
    104             pComponentPrivate->overlay->iOvlyConvBufPtr = NULL;
    105     }
    106     OMX_FREE(pComponentPrivate->overlay);
    107     pComponentPrivate->overlay=NULL;
    108     }
    109 
    110     OMX_MALLOC(pComponentPrivate->overlay, sizeof(VPP_OVERLAY));
    111     pComponentPrivate->overlay->iRBuff = NULL ;
    112     pComponentPrivate->overlay->iGBuff =  NULL;
    113     pComponentPrivate->overlay->iBBuff =  NULL;
    114     pComponentPrivate->overlay->iOvlyConvBufPtr =  NULL;
    115     pComponentPrivate->overlay->iRKey = 0 ;
    116     pComponentPrivate->overlay->iGKey = 0;
    117     pComponentPrivate->overlay->iBKey = 0 ;
    118     pComponentPrivate->overlay->iAlign =1 ;
    119 
    120     iHeight = pComponentPrivate->sCompPorts[1].pPortDef.format.video.nFrameHeight;
    121     iWidth  = pComponentPrivate->sCompPorts[1].pPortDef.format.video.nFrameWidth;
    122 
    123     VPP_DPRINT("CMMFVideoImageConv::Picture Size w = %d x  h= %d", iWidth, iHeight);
    124 
    125     OMX_MALLOC(pComponentPrivate->overlay->iOvlyConvBufPtr, ((2*iWidth*iHeight)+ (2*(iWidth+2)*(iHeight+3*KDeepFiltering))));
    126 
    127     /* if odd buffer, must align it adding a copy column on left from the last image column */
    128     if((iHeight & 1) !=0)
    129         pComponentPrivate->overlay->iAlign++;
    130 
    131     /* Only RGB 24 bits and BGR 24 bits formats are supported */
    132     if(pComponentPrivate->sCompPorts[1].pPortDef.format.video.eColorFormat==OMX_COLOR_Format24bitRGB888)
    133     {
    134         pComponentPrivate->overlay->iRBuff = (OMX_U8*)(aPictureArray)+((iHeight-1)*iWidth*3)+0;
    135         pComponentPrivate->overlay->iGBuff = (OMX_U8*)(aPictureArray)+((iHeight-1)*iWidth*3)+1;
    136         pComponentPrivate->overlay->iBBuff = (OMX_U8*)(aPictureArray)+((iHeight-1)*iWidth*3)+2;
    137     }
    138     else
    139     {
    140         eError = OMX_ErrorBadParameter;
    141         goto EXIT;
    142     }
    143 
    144     pComponentPrivate->overlay->iRKey = *aTransparencyKey++;
    145     pComponentPrivate->overlay->iGKey = *aTransparencyKey++;
    146     pComponentPrivate->overlay->iBKey = *aTransparencyKey++;
    147 
    148     if(iFilteringAlgoEnable == EScanAlgo)
    149         ConvertChromReduction(pComponentPrivate);
    150     else
    151         ConvertNoChromReduction(pComponentPrivate);
    152 
    153     if (KInterlacedTiFormat)
    154         ConvertFormatFromPlanar((pComponentPrivate->overlay->iOvlyConvBufPtr+(2*(iWidth+pComponentPrivate->overlay->iAlign)*(iHeight+3*KDeepFiltering))),
    155                                 aOutImagePtr);
    156     eError = OMX_ErrorNone;
    157 EXIT:
    158     if(eError != OMX_ErrorNone){
    159         if(pComponentPrivate->overlay){
    160             OMX_FREE(pComponentPrivate->overlay->iOvlyConvBufPtr);
    161         }
    162         OMX_FREE(pComponentPrivate->overlay);
    163     }
    164     return eError;
    165 }
    166 
    167 static OMX_U32 iWidth ;
    168 static OMX_U32 iHeight ;
    169 static OMX_U8  iRKey ;
    170 static OMX_U8  iGKey;
    171 static OMX_U8  iBKey;
    172 static OMX_U8  iAlign;
    173 
    174 /* PRE PROSESSING OVERLAYING ALGORITHM WITH CHROMINANCE ARTEFACT REDUCTION ALGORITH
    175 One 444 frame buffer allocation for chrominance
    176 Adding 3 line to use the same buffer for each filtering pass avoid the need
    177  to allocate a second frame buffer in 444 YUV space */
    178 static void ConvertChromReduction(VPP_COMPONENT_PRIVATE *pComponentPrivate)
    179 {
    180 
    181   OMX_U8 *y, *u, *v, *w;                  /* Pointers on Y U V buffers and Weight buffer */
    182   OMX_U8 *uu, *vv;                        /* U and V buffer in 444 space */
    183   OMX_U8 *puu,*pvv,*pyy;                  /* pointers on U,V, and Y on 444 YUV buffers */
    184   OMX_U8 *uuOut,*vvOut;                   /* U and V buffer in 444 space shifted on 3 lines */
    185   OMX_U8 *puOut,*pvOut;                   /* Pointers on U,V, and Y on 444 YUV buffers shifted on 3 lines */
    186   OMX_U8 *pv1, *pv2,*pu1, *pu2;           /* Pointers to 444 U and V buffers for to convert in 420 */
    187   OMX_U8 yKey,uKey,vKey;                  /* Color Key in YUV color space */
    188   OMX_U8 nKeyMax1,nKeyMax2,nKeyMax3;      /* Color Key range used in RVB to detect Color Key an in YUV to detect Near Color Key */
    189   OMX_U8 nKeyMin1,nKeyMin2,nKeyMin3;
    190   OMX_U8 nIncAlign;                       /* The buffer need to have a additional line on left if the width is even */
    191   OMX_U8 nKeyErrorSize = KColorKeyTolerence; /* Color Key error acceptable in percent */
    192   OMX_U32 wCpt,hCpt;
    193   OMX_S32 i;
    194   iHeight = pComponentPrivate->sCompPorts[1].pPortDef.format.video.nFrameHeight;
    195   iWidth  = pComponentPrivate->sCompPorts[1].pPortDef.format.video.nFrameWidth;
    196   iAlign  = pComponentPrivate->overlay->iAlign;
    197   iRKey   = pComponentPrivate->overlay->iRKey;
    198   iGKey   = pComponentPrivate->overlay->iGKey;
    199   iBKey   = pComponentPrivate->overlay->iBKey;
    200 
    201 
    202     y = pComponentPrivate->overlay->iOvlyConvBufPtr + 2*(iWidth+iAlign)*(iHeight+3*KDeepFiltering);
    203 
    204     /* Cb buffer in 444         */
    205     uuOut = pComponentPrivate->overlay->iOvlyConvBufPtr;
    206 
    207     /* Cr buffer int 444    */
    208     vvOut = (pComponentPrivate->overlay->iOvlyConvBufPtr+(iWidth+iAlign)*(iHeight+3*KDeepFiltering));
    209 
    210     /* Initalized pointer on line 4 of frame buffer       */
    211     uu = uuOut+3*KDeepFiltering*(iWidth+iAlign);
    212 
    213     /* for the first image scan the buffer begin a line 4 */
    214     vv = vvOut+3*KDeepFiltering*(iWidth+iAlign);
    215 
    216     puu = uu;
    217     pvv = vv;
    218 
    219 
    220     /* Dimension reduction for U and V components */
    221     u = (y+iWidth*iHeight);   /* Initialise pointer on YUV420 output buffers */
    222     v = (u+(iWidth*iHeight)/4);
    223     w = (v+(iWidth*iHeight)/4);
    224 
    225     /* Compute color key acceptable range depending on nKeyErrorSize */
    226     if(iRKey>KColorKeyChannelPred)
    227     {
    228         nKeyMax1 = ((iRKey+nKeyErrorSize)<255)?(iRKey+nKeyErrorSize*2):255;
    229         nKeyMin1 = ((nKeyErrorSize)<iRKey)?(iRKey-nKeyErrorSize*2):0;
    230     }
    231     else
    232     {
    233         nKeyMax1 = ((iRKey+nKeyErrorSize/2)<255)?(iRKey+nKeyErrorSize/2):255;
    234         nKeyMin1 = ((nKeyErrorSize/2)<iRKey)?(iRKey-nKeyErrorSize/2):0;
    235     }
    236 
    237     if(iGKey>KColorKeyChannelPred)
    238     {
    239         nKeyMax2 = ((iGKey+nKeyErrorSize)<255)?(iGKey+nKeyErrorSize*2):255;
    240         nKeyMin2 = ((nKeyErrorSize)<iGKey)?(iGKey-nKeyErrorSize*2):0;
    241     }
    242     else
    243     {
    244         nKeyMax2 = ((iGKey+nKeyErrorSize/2)<255)?(iGKey+nKeyErrorSize/2):255;
    245         nKeyMin2 = ((nKeyErrorSize/2)<iGKey)?(iGKey-nKeyErrorSize/2):0;
    246     }
    247 
    248 
    249     if(iBKey>KColorKeyChannelPred)
    250     {
    251         nKeyMax3 = ((iBKey+nKeyErrorSize)<255)?(iBKey+nKeyErrorSize*2):255;
    252         nKeyMin3 = ((nKeyErrorSize)<iBKey)?(iBKey-nKeyErrorSize*2):0;
    253     }
    254     else
    255     {
    256         nKeyMax3 = ((iBKey+nKeyErrorSize/2)<255)?(iBKey+nKeyErrorSize/2):255;
    257         nKeyMin3 = ((nKeyErrorSize/2)<iBKey)?(iBKey-nKeyErrorSize/2):0;
    258     }
    259 
    260     /* FIRST IMAGE SCAN ALGORITHM TO COMPUTR 444 UYV buffer from RGB buffer converting the color key */
    261     /* compute 444 YUV buffers from RGB input buffer converting RGB color key to an Y color key set at value 0 and and UV color key set at value (0,0) */
    262     for(hCpt=0;hCpt<iHeight;hCpt++)
    263     {
    264         nIncAlign =0; /* alignement incremental set */
    265         for (wCpt=0;wCpt<(iWidth+iAlign);wCpt++)
    266         {
    267 
    268             if( (*pComponentPrivate->overlay->iRBuff<=nKeyMax1 &&
    269                  *pComponentPrivate->overlay->iRBuff>=nKeyMin1) &&
    270                 (*pComponentPrivate->overlay->iGBuff<=nKeyMax2 &&
    271                  *pComponentPrivate->overlay->iGBuff>=nKeyMin2) &&
    272                 (*pComponentPrivate->overlay->iBBuff<=nKeyMax3 &&
    273                  *pComponentPrivate->overlay->iBBuff>=nKeyMin3) )
    274             {
    275                 *y   = 0;                                   /* set pixel at Y Color Key  */
    276                 *puu = 0;                                   /* set pixel at UV Color Key */
    277                 *pvv = 0;
    278             }
    279             else
    280             {
    281                 *y=(OMX_U8)((77*(OMX_S32)(*pComponentPrivate->overlay->iRBuff) +
    282                              150*(OMX_S32)(*pComponentPrivate->overlay->iGBuff) +
    283                              29*(OMX_S32)(*pComponentPrivate->overlay->iBBuff))>>8);
    284                 *puu=(OMX_U8)(((160*((OMX_S32)(*pComponentPrivate->overlay->iRBuff) - (OMX_S32)(*y)))>>8) + 128);
    285                 *pvv=(OMX_U8)(((126*((OMX_S32)(*pComponentPrivate->overlay->iBBuff) - (OMX_S32)(*y)))>>8) + 128);
    286 
    287                 if(*y == 0)
    288                     (*y)++;                                 /* avoid zero almost blackbecause is used by the Y color key   */
    289                 if(*puu == 0 && *pvv == 0)                  /* avoid zero almost black because is used by the UV color key */
    290                     (*puu)++;
    291             }
    292             puu++;
    293             pvv++;
    294 
    295             if(wCpt>iWidth)
    296                 nIncAlign=0;
    297 
    298             y        += nIncAlign;
    299             pComponentPrivate->overlay->iRBuff   += 3*nIncAlign;
    300             pComponentPrivate->overlay->iGBuff   += 3*nIncAlign;
    301             pComponentPrivate->overlay->iBBuff   += 3*nIncAlign;
    302             nIncAlign = 1;
    303         }
    304         pComponentPrivate->overlay->iRBuff -= 3*iWidth*2;
    305         pComponentPrivate->overlay->iGBuff -= 3*iWidth*2;
    306         pComponentPrivate->overlay->iBBuff -= 3*iWidth*2;
    307 
    308     }
    309 
    310     /* SECOND IMAGE SCAN ALGORITHM TO REMOVE COLOR KEY RESIDUALS ARTEFACTS */
    311     yKey     = (OMX_U8)((77*(OMX_S32)(iRKey) + 150*(OMX_S32)(iGKey) + 29*(OMX_S32)(iBKey))>>8); /* convert RGB color key in YUV space */
    312     uKey     = (OMX_U8)(((160*((OMX_S32)(iRKey) - (OMX_S32)(nKeyMin1)))>>8) + 128);
    313     vKey     = (OMX_U8)(((126*((OMX_S32)(iBKey) - (OMX_S32)(nKeyMin1)))>>8) + 128);
    314 
    315     nKeyMax1 = (OMX_U8)(((yKey+KAlgoLumaTolerence)<255)?(yKey+KAlgoLumaTolerence):255);
    316     /*nKeyMin1 = ((KAlgoLumaTolerence)<yKey)?(yKey-KAlgoLumaTolerence):0;*/
    317     nKeyMin1 = (OMX_U8)(yKey-KAlgoLumaTolerence);
    318 
    319     if(uKey>KColorKeyChannelPred && vKey>KColorKeyChannelPred)
    320     {
    321         nKeyMax2 = (OMX_U8)(((uKey+KAlgoChromaTolerance)<255)?(uKey+KAlgoChromaTolerance):255);
    322         nKeyMax3 = (OMX_U8)(((vKey+KAlgoChromaTolerance)<255)?(vKey+KAlgoChromaTolerance):255);
    323 
    324         nKeyMin2 = (OMX_U8)(((KAlgoChromaTolerance)<uKey)?(uKey-KAlgoChromaTolerance):0);
    325         nKeyMin3 = (OMX_U8)(((KAlgoChromaTolerance)<vKey)?(vKey-KAlgoChromaTolerance):0);
    326     }
    327     else if(uKey>KColorKeyChannelPred && vKey<KColorKeyChannelMin)
    328     {
    329         nKeyMax2 = (OMX_U8)(((uKey+KAlgoChromaTolerance/2)<255)?(uKey+KAlgoChromaTolerance/2):255);
    330         nKeyMin2 = (OMX_U8)(((KAlgoChromaTolerance/2)<uKey)?(uKey-KAlgoChromaTolerance/2):0);
    331         nKeyMax3 = 255;
    332         nKeyMin3 = 0;
    333     }
    334     else if(vKey>KColorKeyChannelPred && uKey<KColorKeyChannelMin)
    335     {
    336         nKeyMax3 = (OMX_U8)(((uKey+KAlgoChromaTolerance/2)<255)?(uKey+KAlgoChromaTolerance/2):255);
    337         nKeyMin3 = (OMX_U8)(((KAlgoChromaTolerance/2)<uKey)?(uKey-KAlgoChromaTolerance/2):0);
    338         nKeyMax2 = 255;
    339         nKeyMin2 = 0;
    340     }
    341     else
    342     {
    343         nKeyMax2 = (OMX_U8)(((uKey+KAlgoChromaTolerance/2)<255)?(uKey+KAlgoChromaTolerance/2):255);
    344         nKeyMax3 = (OMX_U8)(((vKey+KAlgoChromaTolerance/2)<255)?(vKey+KAlgoChromaTolerance/2):255);
    345 
    346         nKeyMin2 = (OMX_U8)(((KAlgoChromaTolerance/2)<uKey)?(uKey-KAlgoChromaTolerance/2):0);
    347         nKeyMin3 = (OMX_U8)(((KAlgoChromaTolerance/2)<vKey)?(vKey-KAlgoChromaTolerance/2):0);
    348     }
    349 
    350     for( i =KDeepFiltering;i>0;i--)
    351     {                                                       /* and on the next image scan the buffer start at line */
    352         uu    = uuOut+3*i*(iWidth+iAlign);
    353         vv    = vvOut+3*i*(iWidth+iAlign);
    354         puu   = uu;
    355         pvv   = vv;
    356         pyy   = (pComponentPrivate->overlay->iOvlyConvBufPtr + 2*(iWidth+iAlign)*(iHeight+3*KDeepFiltering)) + 1 + iWidth;
    357         puOut = uuOut+3*(i-1)*(iWidth+iAlign);
    358         pvOut = vvOut+3*(i-1)*(iWidth+iAlign);
    359 
    360         memcpy(puOut,puu,iWidth+iAlign);        /* recopy the first line which is not scanned during algorithm */
    361         memcpy(pvOut,pvv,iWidth+iAlign);
    362 
    363         puOut += iWidth+iAlign;             /* initalize pointers on second line */
    364         pvOut += iWidth+iAlign;
    365         puu   += iWidth+iAlign;              /* initalize pointers on second line */
    366         pvv   += iWidth+iAlign;
    367 
    368 
    369         for(hCpt=1;hCpt<(iHeight-1);hCpt++)
    370         {
    371             *puOut++ = *puu++;
    372             *pvOut++ = *pvv++;
    373             *puOut++ = *puu++;
    374             *pvOut++ = *pvv++;
    375 
    376             for (wCpt=1;wCpt<(iWidth-1);wCpt++)
    377             {
    378 
    379                 *puOut = *puu;
    380                 *pvOut = *pvv;
    381                 /* check if the pixel is near the color key */
    382                 if(((*pyy)<=nKeyMax1 && (*pyy)>=nKeyMin1) &&
    383                    ((*puu)<=nKeyMax2 && (*puu)>=nKeyMin2) &&
    384                    ((*pvv)<=nKeyMax3 && (*pvv)>=nKeyMin3))
    385                 {
    386                     /* check if a color key is avialable around the pixel */
    387                     if(((*(puu-1)== 0 && *(pvv-1)== 0) || (*(puu+1)== 0 && *(pvv+1)== 0)) ||
    388 
    389                        ((*(puu-(iWidth+iAlign))   == 0 && *(pvv-(iWidth+iAlign))   == 0) ||
    390                         (*(puu-(iWidth+iAlign)-1) == 0 && *(pvv-(iWidth+iAlign)-1) == 0) ||
    391                         (*(puu-(iWidth+iAlign)+1) == 0 && *(pvv-(iWidth+iAlign)+1) == 0))||
    392 
    393                        ((*(puu+(iWidth+iAlign))   == 0 && *(pvv+(iWidth+iAlign))   == 0) ||
    394                         (*(puu+(iWidth+iAlign)-1) == 0 && *(pvv+(iWidth+iAlign)-1) == 0) ||
    395                         (*(puu+(iWidth+iAlign)+1) == 0 && *(pvv+(iWidth+iAlign)+1) == 0)))
    396                     {
    397                         *puOut = 0;                           /* set the U and V pixel to UV color Key */
    398                         *pvOut = 0;
    399                     }
    400                 }
    401                 puOut++;
    402                 pvOut++;
    403                 pyy++;
    404                 puu++;
    405                 pvv++;
    406             }
    407             *puOut++ = *puu++;
    408             *pvOut++ = *pvv++;
    409 
    410             if(iAlign>1)
    411             {
    412                 *puOut++ = *puu++;
    413                 *pvOut++ = *pvv++;
    414             }
    415             pyy += 2;
    416         }
    417         memcpy(puOut,puu,iWidth+iAlign);
    418         memcpy(pvOut,pvv,iWidth+iAlign);
    419     }
    420     uu = uuOut;
    421     vv = vvOut;
    422 
    423     pu1 = uu;
    424     pu2 = uu+iWidth+iAlign;
    425     pv1 = vv;
    426     pv2 = vv+iWidth+iAlign;
    427 
    428     for(hCpt=0;hCpt<iHeight;hCpt+=2)
    429     {
    430         for(wCpt=0;wCpt<iWidth;wCpt+=2)
    431         {
    432             *u++ = (OMX_U8)(((OMX_U32)(*pu1+2*(*(pu1+1))+*(pu1+2)+*pu2+2*(*(pu2+1))+*(pu2+2)))>>3);
    433             *v++ = (OMX_U8)(((OMX_U32)(*pv1+2*(*(pv1+1))+*(pv1+2)+*pv2+2*(*(pv2+1))+*(pv2+2)))>>3);
    434 
    435             *w    = 0;
    436             (*w) += (*(pu1  )!=0  || *(pv1  )!=0)?0:1;
    437             (*w) += (*(pu1+1)!=0  || *(pv1+1)!=0)?0:2;
    438             (*w) += (*(pu1+2)!=0  || *(pv1+2)!=0)?0:1;
    439             (*w) += (*(pu2  )!=0  || *(pv2  )!=0)?0:1;
    440             (*w) += (*(pu2+1)!=0  || *(pv2+1)!=0)?0:2;
    441             (*w) += (*(pu2+2)!=0  || *(pv2+2)!=0)?0:1;
    442 
    443             w++;
    444             pu1 += 2;
    445             pv1 += 2;
    446             pu2 += 2;
    447             pv2 += 2;
    448         }
    449 
    450         pu1 += iWidth+2*iAlign; pu2+=iWidth+2*iAlign;
    451         pv1 += iWidth+2*iAlign; pv2+=iWidth+2*iAlign;
    452 
    453     }
    454 }
    455 
    456 /* PRE PROSESSING OVERLAYING ALGORITHM WITHOUT CHROMINANCE ARTEFACT REDUCTION ALGORITH
    457 // The algorithm is the same one which it used above but we did't need to allocate a full frame buffer in 444
    458 // Only 2 UV 444 lines are mandatoried */
    459 static void ConvertNoChromReduction(VPP_COMPONENT_PRIVATE *pComponentPrivate)
    460 {
    461     OMX_U8 *y, *u, *v, *w;
    462     OMX_U8 *uu, *vv;
    463     OMX_U8 *puu,*pvv;
    464     OMX_U8 *pv1, *pv2,*pu1, *pu2;
    465     OMX_U8 nKeyMax1,nKeyMax2,nKeyMax3;
    466     OMX_U8 nKeyMin1,nKeyMin2,nKeyMin3;
    467     OMX_U8 nIncAlign;
    468     OMX_U8 nKeyErrorSize = KColorKeyTolerence;
    469     OMX_U32 lCpt, hCpt, wCpt;
    470 
    471     y  = pComponentPrivate->overlay->iOvlyConvBufPtr + (4*(iWidth+iAlign));
    472     uu = pComponentPrivate->overlay->iOvlyConvBufPtr;
    473     vv = pComponentPrivate->overlay->iOvlyConvBufPtr + (iWidth+iAlign)*2;
    474 
    475     u = (y+iWidth*iHeight);
    476     v = (u+(iWidth*iHeight)/4);
    477     w = (v+(iWidth*iHeight)/4);
    478 
    479     /* Compute color key acceptable range depending on nKeyErrorSize. */
    480     nKeyMax1 = ((iRKey+nKeyErrorSize/2)<255)?(iRKey+nKeyErrorSize/2):255;
    481     nKeyMax2 = ((iGKey+nKeyErrorSize/2)<255)?(iGKey+nKeyErrorSize/2):255;
    482     nKeyMax3 = ((iBKey+nKeyErrorSize/2)<255)?(iBKey+nKeyErrorSize/2):255;
    483 
    484     nKeyMin1 = ((nKeyErrorSize/2)<iRKey)?(iRKey-nKeyErrorSize/2):0;
    485     nKeyMin2 = ((nKeyErrorSize/2)<iGKey)?(iGKey-nKeyErrorSize/2):0;
    486     nKeyMin3 = ((nKeyErrorSize/2)<iBKey)?(iBKey-nKeyErrorSize/2):0;
    487 
    488     for(hCpt=0;hCpt<iHeight;hCpt+=2)
    489     {
    490         /* 2 lines calculation */
    491         puu = uu;
    492         pvv = vv;
    493         for (lCpt=0;lCpt<2;lCpt++)
    494         {
    495             nIncAlign = 0;
    496             for (wCpt=0; wCpt<(iWidth+iAlign); wCpt++)
    497             {
    498                 if( (*pComponentPrivate->overlay->iRBuff<=nKeyMax1 &&
    499                      *pComponentPrivate->overlay->iRBuff>=nKeyMin1) &&
    500                     (*pComponentPrivate->overlay->iGBuff<=nKeyMax2 &&
    501                      *pComponentPrivate->overlay->iGBuff>=nKeyMin2) &&
    502                     (*pComponentPrivate->overlay->iBBuff<=nKeyMax3 &&
    503                      *pComponentPrivate->overlay->iBBuff>=nKeyMin3) )
    504                 {
    505                     *y     = 0;
    506                     *puu++ = 0;
    507                     *pvv++ = 0;
    508                 }
    509                 else
    510                 {
    511                     *y   = (OMX_U8)((77*(OMX_S32)(*pComponentPrivate->overlay->iRBuff) +
    512                                      150*(OMX_S32)(*pComponentPrivate->overlay->iGBuff) +
    513                                      29*(OMX_S32)(*pComponentPrivate->overlay->iBBuff))>>8);
    514                     *puu = (OMX_U8)(((160*((OMX_S32)(*pComponentPrivate->overlay->iRBuff) - (OMX_S32)(*y)))>>8) + 128);
    515                     *pvv = (OMX_U8)(((126*((OMX_S32)(*pComponentPrivate->overlay->iBBuff) - (OMX_S32)(*y)))>>8) + 128);
    516 
    517                     if(*y == 0)
    518                         (*y)++;
    519 
    520                     if(*puu == 0 && *pvv == 0)
    521                         (*puu)++;
    522 
    523                     puu++;
    524                     pvv++;
    525                 }
    526 
    527                 if(wCpt>iWidth)
    528                     nIncAlign=0;
    529 
    530                 y        += nIncAlign;
    531                 pComponentPrivate->overlay->iRBuff   += 3*nIncAlign;
    532                 pComponentPrivate->overlay->iGBuff   += 3*nIncAlign;
    533                 pComponentPrivate->overlay->iBBuff   += 3*nIncAlign;
    534                 nIncAlign = 1;
    535             }
    536         }
    537 
    538         pu1 = uu;
    539         pu2 = uu+iWidth+iAlign;
    540         pv1 = vv;
    541         pv2 = vv+iWidth+iAlign;
    542 
    543         for (wCpt=0; wCpt < iWidth; wCpt += 2)
    544         {
    545             *u++ = (OMX_U8)(((OMX_S32)(*pu1+2*(*(pu1+1))+*(pu1+2)+*pu2+2*(*(pu2+1))+*(pu2+2)))>>3);
    546             *v++ = (OMX_U8)(((OMX_S32)(*pv1+2*(*(pv1+1))+*(pv1+2)+*pv2+2*(*(pv2+1))+*(pv2+2)))>>3);
    547 
    548             *w = 0;
    549             (*w) += (*(pu1  )!=0 || *(pv1 )!=0) ?0:1;
    550             (*w) += (*(pu1+1)!=0 || *(pv1+1)!=0)?0:2;
    551             (*w) += (*(pu1+2)!=0 || *(pv1+2)!=0)?0:1;
    552             (*w) += (*(pu2  )!=0 || *(pv2  )!=0)?0:1;
    553             (*w) += (*(pu2+1)!=0 || *(pv2+1)!=0)?0:2;
    554             (*w) += (*(pu2+2)!=0 || *(pv2+2)!=0)?0:1;
    555 
    556             w++;
    557             pu1 += 2;
    558             pv1 += 2;
    559             pu2 += 2;
    560             pv2 += 2;
    561         }
    562     }
    563 }
    564 
    565 /*  Convert  buffer YUV420W planar to TI propietary file for overlaying post-processing
    566 //  The format is two lines of luminance followed with one line of interlaced Cb anc Cr value and followed by one Weight line in 16 dword size
    567 //  Y(k)   Y1     Y2     Y3     Y4     first Y line of image)
    568 //  Y(k+1) Y1     Y2     Y3     Y4     Y5(seconde Y line of image)
    569 //  C(k)   Cb1Cr1 Cb2Cr2 Cb3Cr3 Cb4Cr4 (one interlace line of Cb and Cr)
    570 //  W(k)   [0]W1  [0]W2  [0]W3  [0]W4  (One weight line in dword size) */
    571 static void ConvertFormatFromPlanar(OMX_U8 *apInBufferYUV420W, OMX_U8 *apTIinternalFormat)
    572 {
    573     OMX_S32    wCpt;
    574     OMX_S32    hCpt;
    575     OMX_S32    yCpt     = iHeight-1;
    576     OMX_U8  nUvalue  = 0;
    577     OMX_U8  nVvalue  = 0;
    578     OMX_U8  nWeight  = 0;
    579     OMX_U8* pYbuffer = apInBufferYUV420W;
    580     OMX_U8* pUbuffer = (pYbuffer+((OMX_S32)(iWidth)*iHeight));
    581     OMX_U8* pVbuffer = (pUbuffer+((OMX_S32)(iWidth)*iHeight/4));
    582     OMX_U8* pWbuffer = (pVbuffer+((OMX_S32)(iWidth)*iHeight/4));
    583 
    584     /* Perform copy of Y data with byte swapp for DSP DMA */
    585     for (hCpt=((iHeight)/2-1); hCpt>=0; hCpt--)
    586     {
    587         for(wCpt = 0; (OMX_U32)wCpt < iWidth; wCpt += 4)
    588         {
    589             *apTIinternalFormat++ = *(pYbuffer+1+(wCpt)+yCpt*iWidth);
    590             *apTIinternalFormat++ = *(pYbuffer+0+(wCpt)+yCpt*iWidth);
    591             *apTIinternalFormat++ = *(pYbuffer+3+(wCpt)+yCpt*iWidth);
    592             *apTIinternalFormat++ = *(pYbuffer+2+(wCpt)+yCpt*iWidth);
    593         }
    594         yCpt -= 1;
    595         for (wCpt = 0; (OMX_U32)wCpt < iWidth; wCpt += 4)
    596         {
    597             *apTIinternalFormat++ = *(pYbuffer+0+(wCpt)+yCpt*iWidth);
    598             *apTIinternalFormat++ = *(pYbuffer+1+(wCpt)+yCpt*iWidth);
    599             *apTIinternalFormat++ = *(pYbuffer+2+(wCpt)+yCpt*iWidth);
    600             *apTIinternalFormat++ = *(pYbuffer+3+(wCpt)+yCpt*iWidth);
    601         }
    602         yCpt -= 1;
    603 
    604         for (wCpt = 0; (OMX_U32)wCpt < iWidth/2; wCpt++)
    605         {
    606             nUvalue = *(pUbuffer+wCpt+hCpt*(iWidth/2));
    607             nVvalue = *(pVbuffer+wCpt+hCpt*(iWidth/2));
    608             if(nUvalue !=0 || nVvalue !=0)
    609             {
    610                 nWeight  = *(pWbuffer+wCpt+hCpt*(iWidth/2));
    611                 nUvalue -= (8-nWeight)<<4;
    612                 nVvalue -= (8-nWeight)<<4;
    613             }
    614             *apTIinternalFormat++ = nVvalue;
    615             *apTIinternalFormat++ = nUvalue;
    616         }
    617 
    618         for (wCpt = 0; (OMX_U32)wCpt < iWidth/2; wCpt++)
    619         {
    620             *apTIinternalFormat++ = (OMX_U8)0;
    621             *apTIinternalFormat++ = *(pWbuffer+wCpt+hCpt*(iWidth/2));
    622         }
    623     }
    624 }
    625 
    626 
    627 
    628 
    629