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