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
68typedef enum {
69  ENoFilter,EScanAlgo
70}eFilterAlgoOption;
71
72const OMX_S32 KDeepFiltering        = 3 ;   /* Number of chrominance artefact redution algorithm scans */
73const OMX_U8  KColorKeyTolerence    = 50 ;  /* Tolerence on Color key detection                        */
74const OMX_S32 KColorKeyChannelPred  = 150 ; /* Color channel predominance detection                    */
75const OMX_S32 KColorKeyChannelMin   = 75 ;  /* Color channel predominance detection                    */
76const OMX_S32 KAlgoLumaTolerence    = 600 ; /* Tolerence on luminance to detect pixel near color key   */
77const OMX_S32 KAlgoChromaTolerance  = 50 ;  /* Tolerence on chrominance to detect pixel near color key */
78const OMX_S32 KqCifWidth            = 176 ;
79const OMX_S32 KqCifHeight           = 144 ;
80const OMX_S32 KCifWidth             = 352 ;
81const OMX_S32 KCifHeight            = 288 ;
82const OMX_S32 KInterlacedTiFormat   = 1 ;
83const OMX_S32 iFilteringAlgoEnable  = EScanAlgo;
84
85
86
87static void ConvertChromReduction(VPP_COMPONENT_PRIVATE *pComponentPrivate);
88static void ConvertFormatFromPlanar(OMX_U8 *apInBufferYUV420W, OMX_U8 *apTIinternalFormat);
89static void ConvertNoChromReduction(VPP_COMPONENT_PRIVATE *pComponentPrivate);
90
91
92
93OMX_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;
157EXIT:
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
167static OMX_U32 iWidth ;
168static OMX_U32 iHeight ;
169static OMX_U8  iRKey ;
170static OMX_U8  iGKey;
171static OMX_U8  iBKey;
172static OMX_U8  iAlign;
173
174/* PRE PROSESSING OVERLAYING ALGORITHM WITH CHROMINANCE ARTEFACT REDUCTION ALGORITH
175One 444 frame buffer allocation for chrominance
176Adding 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 */
178static 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 */
459static 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) */
571static 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