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 
ComputeTiOverlayImgFormat(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_U8 * aPictureArray,OMX_U8 * aOutImagePtr,OMX_U8 * aTransparencyKey)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 */
ConvertChromReduction(VPP_COMPONENT_PRIVATE * pComponentPrivate)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 */
ConvertNoChromReduction(VPP_COMPONENT_PRIVATE * pComponentPrivate)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) */
ConvertFormatFromPlanar(OMX_U8 * apInBufferYUV420W,OMX_U8 * apTIinternalFormat)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