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