1 /* 2 * Copyright 2012 Samsung Electronics S.LSI Co. LTD 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * @file Exynos_OSAL_Android.cpp 19 * @brief 20 * @author Seungbeom Kim (sbcrux.kim (at) samsung.com) 21 * @author Hyeyeon Chung (hyeon.chung (at) samsung.com) 22 * @author Yunji Kim (yunji.kim (at) samsung.com) 23 * @author Jinsung Yang (jsgood.yang (at) samsung.com) 24 * @version 2.0.0 25 * @history 26 * 2012.02.20 : Create 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 32 #include <system/window.h> 33 #include <ui/GraphicBuffer.h> 34 #include <ui/GraphicBufferMapper.h> 35 #include <ui/Rect.h> 36 #include <media/hardware/HardwareAPI.h> 37 #include <hardware/hardware.h> 38 #include <media/hardware/OMXPluginBase.h> 39 #include <media/hardware/MetadataBufferType.h> 40 #include <gralloc_priv.h> 41 42 #include "Exynos_OSAL_Mutex.h" 43 #include "Exynos_OSAL_Semaphore.h" 44 #include "Exynos_OMX_Baseport.h" 45 #include "Exynos_OMX_Basecomponent.h" 46 #include "Exynos_OMX_Macros.h" 47 #include "Exynos_OMX_Vdec.h" 48 #include "Exynos_OMX_Venc.h" 49 #include "Exynos_OSAL_Android.h" 50 #include "exynos_format.h" 51 #include "ion.h" 52 53 #undef EXYNOS_LOG_TAG 54 #define EXYNOS_LOG_TAG "Exynos_OSAL_Android" 55 #define EXYNOS_LOG_OFF 56 #include "Exynos_OSAL_Log.h" 57 58 using namespace android; 59 60 #ifdef __cplusplus 61 extern "C" { 62 #endif 63 64 int getIonFd(gralloc_module_t const *module) 65 { 66 private_module_t* m = const_cast<private_module_t*>(reinterpret_cast<const private_module_t*>(module)); 67 return m->ionfd; 68 } 69 70 OMX_ERRORTYPE Exynos_OSAL_LockANBHandle( 71 OMX_IN OMX_U32 handle, 72 OMX_IN OMX_U32 width, 73 OMX_IN OMX_U32 height, 74 OMX_IN OMX_COLOR_FORMATTYPE format, 75 OMX_OUT OMX_U32 *pStride, 76 OMX_OUT OMX_PTR planes) 77 { 78 FunctionIn(); 79 80 OMX_ERRORTYPE ret = OMX_ErrorNone; 81 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 82 buffer_handle_t bufferHandle = (buffer_handle_t) handle; 83 private_handle_t *priv_hnd = (private_handle_t *) bufferHandle; 84 Rect bounds(width, height); 85 ExynosVideoPlane *vplanes = (ExynosVideoPlane *) planes; 86 void *vaddr[MAX_BUFFER_PLANE]; 87 88 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); 89 90 int usage = 0; 91 92 switch (format) { 93 case OMX_COLOR_FormatYUV420Planar: 94 case OMX_COLOR_FormatYUV420SemiPlanar: 95 case OMX_SEC_COLOR_FormatNV12Tiled: 96 usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; 97 break; 98 default: 99 usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; 100 break; 101 } 102 103 if (mapper.lock(bufferHandle, usage, bounds, vaddr) != 0) { 104 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.lock() fail", __func__); 105 ret = OMX_ErrorUndefined; 106 goto EXIT; 107 } 108 109 vplanes[0].fd = priv_hnd->fd; 110 vplanes[0].offset = 0; 111 vplanes[0].addr = vaddr[0]; 112 vplanes[1].fd = priv_hnd->fd1; 113 vplanes[1].offset = 0; 114 vplanes[1].addr = vaddr[1]; 115 vplanes[2].fd = priv_hnd->fd2; 116 vplanes[2].offset = 0; 117 vplanes[2].addr = vaddr[2]; 118 119 *pStride = priv_hnd->stride; 120 121 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer locked: 0x%x", __func__, *vaddr); 122 123 EXIT: 124 FunctionOut(); 125 126 return ret; 127 } 128 129 OMX_ERRORTYPE Exynos_OSAL_UnlockANBHandle(OMX_IN OMX_U32 handle) 130 { 131 FunctionIn(); 132 133 OMX_ERRORTYPE ret = OMX_ErrorNone; 134 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 135 buffer_handle_t bufferHandle = (buffer_handle_t) handle; 136 137 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); 138 139 if (mapper.unlock(bufferHandle) != 0) { 140 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.unlock() fail", __func__); 141 ret = OMX_ErrorUndefined; 142 goto EXIT; 143 } 144 145 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer unlocked: 0x%x", __func__, handle); 146 147 EXIT: 148 FunctionOut(); 149 150 return ret; 151 } 152 153 OMX_COLOR_FORMATTYPE Exynos_OSAL_GetANBColorFormat(OMX_IN OMX_U32 handle) 154 { 155 FunctionIn(); 156 157 OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused; 158 private_handle_t *priv_hnd = (private_handle_t *) handle; 159 160 ret = Exynos_OSAL_Hal2OMXPixelFormat(priv_hnd->format); 161 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ColorFormat: 0x%x", ret); 162 163 EXIT: 164 FunctionOut(); 165 166 return ret; 167 } 168 169 OMX_U32 Exynos_OSAL_GetANBStride(OMX_IN OMX_U32 handle) 170 { 171 FunctionIn(); 172 173 OMX_U32 nStride = 0; 174 private_handle_t *priv_hnd = (private_handle_t *) handle; 175 176 nStride = priv_hnd->stride; 177 178 EXIT: 179 FunctionOut(); 180 181 return nStride; 182 } 183 184 OMX_ERRORTYPE Exynos_OSAL_LockMetaData( 185 OMX_IN OMX_PTR pBuffer, 186 OMX_IN OMX_U32 width, 187 OMX_IN OMX_U32 height, 188 OMX_IN OMX_COLOR_FORMATTYPE format, 189 OMX_OUT OMX_U32 *pStride, 190 OMX_OUT OMX_PTR planes) 191 { 192 FunctionIn(); 193 194 OMX_ERRORTYPE ret = OMX_ErrorNone; 195 OMX_PTR pBuf; 196 197 ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf); 198 if (ret == OMX_ErrorNone) { 199 ret = Exynos_OSAL_LockANBHandle((OMX_U32)pBuf, width, height, format, pStride, planes); 200 } 201 202 EXIT: 203 FunctionOut(); 204 205 return ret; 206 } 207 208 OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(OMX_IN OMX_PTR pBuffer) 209 { 210 FunctionIn(); 211 212 OMX_ERRORTYPE ret = OMX_ErrorNone; 213 OMX_PTR pBuf; 214 215 ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf); 216 if (ret == OMX_ErrorNone) 217 ret = Exynos_OSAL_UnlockANBHandle((OMX_U32)pBuf); 218 219 EXIT: 220 FunctionOut(); 221 222 return ret; 223 } 224 225 OMX_HANDLETYPE Exynos_OSAL_RefANB_Create() 226 { 227 int i = 0; 228 EXYNOS_OMX_REF_HANDLE *phREF = NULL; 229 gralloc_module_t *module = NULL; 230 231 OMX_ERRORTYPE err = OMX_ErrorNone; 232 233 FunctionIn(); 234 235 phREF = (EXYNOS_OMX_REF_HANDLE *) Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_REF_HANDLE)); 236 if (phREF == NULL) 237 goto EXIT; 238 239 Exynos_OSAL_Memset(phREF, 0, sizeof(EXYNOS_OMX_REF_HANDLE)); 240 for (i = 0; i < MAX_BUFFER_REF; i++) { 241 phREF->SharedBuffer[i].BufferFd = -1; 242 phREF->SharedBuffer[i].BufferFd1 = -1; 243 phREF->SharedBuffer[i].BufferFd2 = -1; 244 } 245 246 hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module); 247 phREF->pGrallocModule = (OMX_PTR)module; 248 249 err = Exynos_OSAL_MutexCreate(&phREF->hMutex); 250 if (err != OMX_ErrorNone) { 251 Exynos_OSAL_Free(phREF); 252 phREF = NULL; 253 } 254 255 EXIT: 256 FunctionOut(); 257 258 return ((OMX_HANDLETYPE)phREF); 259 } 260 261 OMX_ERRORTYPE Exynos_OSAL_RefANB_Reset(OMX_HANDLETYPE hREF) 262 { 263 int i = 0; 264 OMX_ERRORTYPE ret = OMX_ErrorNone; 265 EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF; 266 gralloc_module_t* module = NULL; 267 268 FunctionIn(); 269 270 if (phREF == NULL) { 271 ret = OMX_ErrorBadParameter; 272 goto EXIT; 273 } 274 275 module = (gralloc_module_t *)phREF->pGrallocModule; 276 277 Exynos_OSAL_MutexLock(phREF->hMutex); 278 for (i = 0; i < MAX_BUFFER_REF; i++) { 279 if (phREF->SharedBuffer[i].BufferFd > -1) { 280 while(phREF->SharedBuffer[i].cnt > 0) { 281 if (phREF->SharedBuffer[i].BufferFd > -1) 282 ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle); 283 if (phREF->SharedBuffer[i].BufferFd1 > -1) 284 ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle1); 285 if (phREF->SharedBuffer[i].BufferFd2 > -1) 286 ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle2); 287 phREF->SharedBuffer[i].cnt--; 288 } 289 phREF->SharedBuffer[i].BufferFd = -1; 290 phREF->SharedBuffer[i].BufferFd1 = -1; 291 phREF->SharedBuffer[i].BufferFd2 = -1; 292 phREF->SharedBuffer[i].pIonHandle = NULL; 293 phREF->SharedBuffer[i].pIonHandle1 = NULL; 294 phREF->SharedBuffer[i].pIonHandle2 = NULL; 295 } 296 } 297 Exynos_OSAL_MutexUnlock(phREF->hMutex); 298 299 EXIT: 300 FunctionOut(); 301 302 return ret; 303 } 304 305 OMX_ERRORTYPE Exynos_OSAL_RefANB_Terminate(OMX_HANDLETYPE hREF) 306 { 307 OMX_ERRORTYPE ret = OMX_ErrorNone; 308 EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF; 309 FunctionIn(); 310 311 if (phREF == NULL) { 312 ret = OMX_ErrorBadParameter; 313 goto EXIT; 314 } 315 316 Exynos_OSAL_RefANB_Reset(phREF); 317 318 phREF->pGrallocModule = NULL; 319 320 ret = Exynos_OSAL_MutexTerminate(phREF->hMutex); 321 if (ret != OMX_ErrorNone) 322 goto EXIT; 323 324 Exynos_OSAL_Free(phREF); 325 phREF = NULL; 326 327 EXIT: 328 FunctionOut(); 329 330 return ret; 331 } 332 333 OMX_ERRORTYPE Exynos_OSAL_RefANB_Increase(OMX_HANDLETYPE hREF, OMX_PTR pBuffer) 334 { 335 int i; 336 OMX_ERRORTYPE ret = OMX_ErrorNone; 337 buffer_handle_t bufferHandle = (buffer_handle_t) pBuffer; //pANB->handle 338 private_handle_t *priv_hnd = (private_handle_t *) bufferHandle; 339 EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF; 340 gralloc_module_t* module = NULL; 341 342 unsigned long *pIonHandle; 343 unsigned long *pIonHandle1; 344 unsigned long *pIonHandle2; 345 346 FunctionIn(); 347 348 if (phREF == NULL) { 349 ret = OMX_ErrorBadParameter; 350 goto EXIT; 351 } 352 353 module = (gralloc_module_t *)phREF->pGrallocModule; 354 355 Exynos_OSAL_MutexLock(phREF->hMutex); 356 357 if (priv_hnd->fd >= 0) { 358 ion_incRef(getIonFd(module), priv_hnd->fd, &pIonHandle); 359 } 360 if (priv_hnd->fd1 >= 0) { 361 ion_incRef(getIonFd(module), priv_hnd->fd1, &pIonHandle1); 362 } 363 if (priv_hnd->fd2 >= 0) { 364 ion_incRef(getIonFd(module), priv_hnd->fd2, &pIonHandle2); 365 } 366 367 for (i = 0; i < MAX_BUFFER_REF; i++) { 368 if (phREF->SharedBuffer[i].BufferFd == priv_hnd->fd) { 369 phREF->SharedBuffer[i].cnt++; 370 break; 371 } 372 } 373 374 if (i >= MAX_BUFFER_REF) { 375 for (i = 0; i < MAX_BUFFER_REF; i++) { 376 if (phREF->SharedBuffer[i].BufferFd == -1) { 377 phREF->SharedBuffer[i].BufferFd = priv_hnd->fd; 378 phREF->SharedBuffer[i].BufferFd1 = priv_hnd->fd1; 379 phREF->SharedBuffer[i].BufferFd2 = priv_hnd->fd2; 380 phREF->SharedBuffer[i].pIonHandle = pIonHandle; 381 phREF->SharedBuffer[i].pIonHandle1 = pIonHandle1; 382 phREF->SharedBuffer[i].pIonHandle2 = pIonHandle2; 383 phREF->SharedBuffer[i].cnt++; 384 break; 385 } 386 } 387 } 388 389 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "inc fd:%d cnt:%d", phREF->SharedBuffer[i].BufferFd, phREF->SharedBuffer[i].cnt); 390 391 Exynos_OSAL_MutexUnlock(phREF->hMutex); 392 393 if (i >= MAX_BUFFER_REF) { 394 ret = OMX_ErrorUndefined; 395 } 396 397 EXIT: 398 FunctionOut(); 399 400 return ret; 401 } 402 403 OMX_ERRORTYPE Exynos_OSAL_RefANB_Decrease(OMX_HANDLETYPE hREF, OMX_U32 BufferFd) 404 { 405 int i; 406 OMX_ERRORTYPE ret = OMX_ErrorNone; 407 EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF; 408 gralloc_module_t* module = NULL; 409 410 FunctionIn(); 411 412 if ((phREF == NULL) || (BufferFd < 0)) { 413 ret = OMX_ErrorBadParameter; 414 goto EXIT; 415 } 416 417 module = (gralloc_module_t *)phREF->pGrallocModule; 418 419 Exynos_OSAL_MutexLock(phREF->hMutex); 420 421 for (i = 0; i < MAX_BUFFER_REF; i++) { 422 if (phREF->SharedBuffer[i].BufferFd == BufferFd) { 423 if (phREF->SharedBuffer[i].BufferFd > -1) 424 ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle); 425 if (phREF->SharedBuffer[i].BufferFd1 > -1) 426 ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle1); 427 if (phREF->SharedBuffer[i].BufferFd2 > -1) 428 ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle2); 429 phREF->SharedBuffer[i].cnt--; 430 if (phREF->SharedBuffer[i].cnt == 0) { 431 phREF->SharedBuffer[i].BufferFd = -1; 432 phREF->SharedBuffer[i].BufferFd1 = -1; 433 phREF->SharedBuffer[i].BufferFd2 = -1; 434 phREF->SharedBuffer[i].pIonHandle = NULL; 435 phREF->SharedBuffer[i].pIonHandle1 = NULL; 436 phREF->SharedBuffer[i].pIonHandle2 = NULL; 437 } 438 break; 439 } 440 } 441 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dec fd:%d cnt:%d", phREF->SharedBuffer[i].BufferFd, phREF->SharedBuffer[i].cnt); 442 443 Exynos_OSAL_MutexUnlock(phREF->hMutex); 444 445 if (i >= MAX_BUFFER_REF) { 446 ret = OMX_ErrorUndefined; 447 goto EXIT; 448 } 449 450 EXIT: 451 FunctionOut(); 452 453 return ret; 454 } 455 456 OMX_ERRORTYPE useAndroidNativeBuffer( 457 EXYNOS_OMX_BASEPORT *pExynosPort, 458 OMX_BUFFERHEADERTYPE **ppBufferHdr, 459 OMX_U32 nPortIndex, 460 OMX_PTR pAppPrivate, 461 OMX_U32 nSizeBytes, 462 OMX_U8 *pBuffer) 463 { 464 OMX_ERRORTYPE ret = OMX_ErrorNone; 465 OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; 466 unsigned int i = 0; 467 OMX_U32 width, height; 468 OMX_U32 stride; 469 ExynosVideoPlane planes[MAX_BUFFER_PLANE]; 470 471 FunctionIn(); 472 473 if (pExynosPort == NULL) { 474 ret = OMX_ErrorBadParameter; 475 goto EXIT; 476 } 477 if (pExynosPort->portState != OMX_StateIdle) { 478 ret = OMX_ErrorIncorrectStateOperation; 479 goto EXIT; 480 } 481 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 482 ret = OMX_ErrorBadPortIndex; 483 goto EXIT; 484 } 485 486 temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); 487 if (temp_bufferHeader == NULL) { 488 ret = OMX_ErrorInsufficientResources; 489 goto EXIT; 490 } 491 Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); 492 493 for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { 494 if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { 495 pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader; 496 pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); 497 INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); 498 android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; 499 temp_bufferHeader->pBuffer = (OMX_U8 *)pANB->handle; 500 temp_bufferHeader->nAllocLen = nSizeBytes; 501 temp_bufferHeader->pAppPrivate = pAppPrivate; 502 if (nPortIndex == INPUT_PORT_INDEX) 503 temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; 504 else 505 temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; 506 507 width = pExynosPort->portDefinition.format.video.nFrameWidth; 508 height = pExynosPort->portDefinition.format.video.nFrameHeight; 509 Exynos_OSAL_LockANBHandle((OMX_U32)temp_bufferHeader->pBuffer, width, height, 510 pExynosPort->portDefinition.format.video.eColorFormat, 511 &stride, planes); 512 pExynosPort->extendBufferHeader[i].buf_fd[0] = planes[0].fd; 513 pExynosPort->extendBufferHeader[i].pYUVBuf[0] = planes[0].addr; 514 pExynosPort->extendBufferHeader[i].buf_fd[1] = planes[1].fd; 515 pExynosPort->extendBufferHeader[i].pYUVBuf[1] = planes[1].addr; 516 pExynosPort->extendBufferHeader[i].buf_fd[2] = planes[2].fd; 517 pExynosPort->extendBufferHeader[i].pYUVBuf[2] = planes[2].addr; 518 Exynos_OSAL_UnlockANBHandle((OMX_U32)temp_bufferHeader->pBuffer); 519 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "useAndroidNativeBuffer: buf %d pYUVBuf[0]:0x%x (fd:%d), pYUVBuf[1]:0x%x (fd:%d)", 520 i, pExynosPort->extendBufferHeader[i].pYUVBuf[0], planes[0].fd, 521 pExynosPort->extendBufferHeader[i].pYUVBuf[1], planes[1].fd); 522 523 pExynosPort->assignedBufferNum++; 524 if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { 525 pExynosPort->portDefinition.bPopulated = OMX_TRUE; 526 /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ 527 Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); 528 /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ 529 } 530 *ppBufferHdr = temp_bufferHeader; 531 ret = OMX_ErrorNone; 532 533 goto EXIT; 534 } 535 } 536 537 Exynos_OSAL_Free(temp_bufferHeader); 538 ret = OMX_ErrorInsufficientResources; 539 540 EXIT: 541 FunctionOut(); 542 543 return ret; 544 } 545 546 OMX_ERRORTYPE Exynos_OSAL_GetANBParameter( 547 OMX_IN OMX_HANDLETYPE hComponent, 548 OMX_IN OMX_INDEXTYPE nIndex, 549 OMX_INOUT OMX_PTR ComponentParameterStructure) 550 { 551 OMX_ERRORTYPE ret = OMX_ErrorNone; 552 OMX_COMPONENTTYPE *pOMXComponent = NULL; 553 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 554 555 FunctionIn(); 556 557 if (hComponent == NULL) { 558 ret = OMX_ErrorBadParameter; 559 goto EXIT; 560 } 561 562 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 563 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 564 if (ret != OMX_ErrorNone) { 565 goto EXIT; 566 } 567 568 if (pOMXComponent->pComponentPrivate == NULL) { 569 ret = OMX_ErrorBadParameter; 570 goto EXIT; 571 } 572 573 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 574 if (pExynosComponent->currentState == OMX_StateInvalid ) { 575 ret = OMX_ErrorInvalidState; 576 goto EXIT; 577 } 578 579 if (ComponentParameterStructure == NULL) { 580 ret = OMX_ErrorBadParameter; 581 goto EXIT; 582 } 583 584 switch (nIndex) { 585 case OMX_IndexParamGetAndroidNativeBuffer: 586 { 587 GetAndroidNativeBufferUsageParams *pANBParams = (GetAndroidNativeBufferUsageParams *) ComponentParameterStructure; 588 OMX_U32 portIndex = pANBParams->nPortIndex; 589 590 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamGetAndroidNativeBuffer", __func__); 591 592 ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(GetAndroidNativeBufferUsageParams)); 593 if (ret != OMX_ErrorNone) { 594 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(GetAndroidNativeBufferUsageParams) is failed", __func__); 595 goto EXIT; 596 } 597 598 if (portIndex >= pExynosComponent->portParam.nPorts) { 599 ret = OMX_ErrorBadPortIndex; 600 goto EXIT; 601 } 602 603 /* NOTE: OMX_IndexParamGetAndroidNativeBuffer returns original 'nUsage' without any 604 * modifications since currently not defined what the 'nUsage' is for. 605 */ 606 pANBParams->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 607 } 608 break; 609 610 default: 611 { 612 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex); 613 ret = OMX_ErrorUnsupportedIndex; 614 goto EXIT; 615 } 616 break; 617 } 618 619 EXIT: 620 FunctionOut(); 621 622 return ret; 623 } 624 625 OMX_ERRORTYPE Exynos_OSAL_SetANBParameter( 626 OMX_IN OMX_HANDLETYPE hComponent, 627 OMX_IN OMX_INDEXTYPE nIndex, 628 OMX_IN OMX_PTR ComponentParameterStructure) 629 { 630 OMX_ERRORTYPE ret = OMX_ErrorNone; 631 OMX_COMPONENTTYPE *pOMXComponent = NULL; 632 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 633 634 FunctionIn(); 635 636 if (hComponent == NULL) { 637 ret = OMX_ErrorBadParameter; 638 goto EXIT; 639 } 640 641 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 642 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 643 if (ret != OMX_ErrorNone) { 644 goto EXIT; 645 } 646 647 if (pOMXComponent->pComponentPrivate == NULL) { 648 ret = OMX_ErrorBadParameter; 649 goto EXIT; 650 } 651 652 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 653 if (pExynosComponent->currentState == OMX_StateInvalid ) { 654 ret = OMX_ErrorInvalidState; 655 goto EXIT; 656 } 657 658 if (ComponentParameterStructure == NULL) { 659 ret = OMX_ErrorBadParameter; 660 goto EXIT; 661 } 662 663 switch (nIndex) { 664 case OMX_IndexParamEnableAndroidBuffers: 665 { 666 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 667 EnableAndroidNativeBuffersParams *pANBParams = (EnableAndroidNativeBuffersParams *) ComponentParameterStructure; 668 OMX_U32 portIndex = pANBParams->nPortIndex; 669 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 670 671 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamEnableAndroidNativeBuffers", __func__); 672 673 ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(EnableAndroidNativeBuffersParams)); 674 if (ret != OMX_ErrorNone) { 675 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(EnableAndroidNativeBuffersParams) is failed", __func__); 676 goto EXIT; 677 } 678 679 if (portIndex >= pExynosComponent->portParam.nPorts) { 680 ret = OMX_ErrorBadPortIndex; 681 goto EXIT; 682 } 683 684 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 685 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 686 ret = OMX_ErrorBadPortIndex; 687 goto EXIT; 688 } 689 690 /* ANB and DPB Buffer Sharing */ 691 if (pExynosPort->bStoreMetaData != OMX_TRUE) 692 pExynosPort->bIsANBEnabled = pANBParams->enable; 693 if ((portIndex == OUTPUT_PORT_INDEX) && 694 (pExynosPort->bIsANBEnabled == OMX_TRUE) && 695 ((pExynosPort->bufferProcessType & BUFFER_ANBSHARE) == BUFFER_ANBSHARE)) { 696 pExynosPort->bufferProcessType = BUFFER_SHARE; 697 pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; 698 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexParamEnableAndroidBuffers & bufferProcessType change to BUFFER_SHARE"); 699 } 700 } 701 break; 702 703 case OMX_IndexParamUseAndroidNativeBuffer: 704 { 705 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 706 UseAndroidNativeBufferParams *pANBParams = (UseAndroidNativeBufferParams *) ComponentParameterStructure; 707 OMX_U32 portIndex = pANBParams->nPortIndex; 708 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 709 android_native_buffer_t *pANB; 710 OMX_U32 nSizeBytes; 711 712 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamUseAndroidNativeBuffer, portIndex: %d", __func__, portIndex); 713 714 ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(UseAndroidNativeBufferParams)); 715 if (ret != OMX_ErrorNone) { 716 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(UseAndroidNativeBufferParams) is failed", __func__); 717 goto EXIT; 718 } 719 720 if (portIndex >= pExynosComponent->portParam.nPorts) { 721 ret = OMX_ErrorBadPortIndex; 722 goto EXIT; 723 } 724 725 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 726 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 727 ret = OMX_ErrorBadPortIndex; 728 goto EXIT; 729 } 730 731 if (pExynosPort->portState != OMX_StateIdle) { 732 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Port state should be IDLE", __func__); 733 ret = OMX_ErrorIncorrectStateOperation; 734 goto EXIT; 735 } 736 737 pANB = pANBParams->nativeBuffer.get(); 738 739 /* MALI alignment restriction */ 740 nSizeBytes = ALIGN(pANB->width, 16) * ALIGN(pANB->height, 16); 741 nSizeBytes += ALIGN(pANB->width / 2, 16) * ALIGN(pANB->height / 2, 16) * 2; 742 743 ret = useAndroidNativeBuffer(pExynosPort, 744 pANBParams->bufferHeader, 745 pANBParams->nPortIndex, 746 pANBParams->pAppPrivate, 747 nSizeBytes, 748 (OMX_U8 *) pANB); 749 if (ret != OMX_ErrorNone) { 750 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: useAndroidNativeBuffer is failed: err=0x%x", __func__,ret); 751 goto EXIT; 752 } 753 } 754 break; 755 756 case OMX_IndexParamStoreMetaDataBuffer: 757 { 758 StoreMetaDataInBuffersParams *pANBParams = (StoreMetaDataInBuffersParams *) ComponentParameterStructure; 759 OMX_U32 portIndex = pANBParams->nPortIndex; 760 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 761 762 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamStoreMetaDataBuffer", __func__); 763 764 ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(StoreMetaDataInBuffersParams)); 765 if (ret != OMX_ErrorNone) { 766 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(StoreMetaDataInBuffersParams) is failed", __func__); 767 goto EXIT; 768 } 769 770 if (portIndex >= pExynosComponent->portParam.nPorts) { 771 ret = OMX_ErrorBadPortIndex; 772 goto EXIT; 773 } 774 775 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 776 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 777 ret = OMX_ErrorBadPortIndex; 778 goto EXIT; 779 } 780 781 pExynosPort->bStoreMetaData = pANBParams->bStoreMetaData; 782 if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) { 783 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;; 784 } else if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) { 785 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;; 786 if ((portIndex == OUTPUT_PORT_INDEX) && 787 (pExynosPort->bStoreMetaData == OMX_TRUE) && 788 ((pExynosPort->bufferProcessType & BUFFER_ANBSHARE) == BUFFER_ANBSHARE)) { 789 pExynosPort->bufferProcessType = BUFFER_SHARE; 790 pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; 791 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexParamStoreMetaDataBuffer & bufferProcessType change to BUFFER_SHARE"); 792 } 793 794 } 795 } 796 break; 797 798 default: 799 { 800 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex); 801 ret = OMX_ErrorUnsupportedIndex; 802 goto EXIT; 803 } 804 break; 805 } 806 807 EXIT: 808 FunctionOut(); 809 810 return ret; 811 } 812 813 OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer, 814 OMX_OUT OMX_PTR *ppBuf) 815 { 816 OMX_ERRORTYPE ret = OMX_ErrorNone; 817 MetadataBufferType type; 818 819 FunctionIn(); 820 821 /* 822 * meta data contains the following data format. 823 * payload depends on the MetadataBufferType 824 * -------------------------------------------------------------- 825 * | MetadataBufferType | payload | 826 * -------------------------------------------------------------- 827 * 828 * If MetadataBufferType is kMetadataBufferTypeCameraSource, then 829 * -------------------------------------------------------------- 830 * | kMetadataBufferTypeCameraSource | physical addr. of Y |physical addr. of CbCr | 831 * -------------------------------------------------------------- 832 * 833 * If MetadataBufferType is kMetadataBufferTypeGrallocSource, then 834 * -------------------------------------------------------------- 835 * | kMetadataBufferTypeGrallocSource | buffer_handle_t | 836 * -------------------------------------------------------------- 837 */ 838 839 /* MetadataBufferType */ 840 Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType)); 841 842 if (type == kMetadataBufferTypeCameraSource) { 843 void *pAddress = NULL; 844 845 /* Address. of Y */ 846 Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType), sizeof(void *)); 847 ppBuf[0] = (void *)pAddress; 848 849 /* Address. of CbCr */ 850 Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType) + sizeof(void *), sizeof(void *)); 851 ppBuf[1] = (void *)pAddress; 852 853 } else if (type == kMetadataBufferTypeGrallocSource) { 854 buffer_handle_t pBufHandle; 855 856 /* buffer_handle_t */ 857 Exynos_OSAL_Memcpy(&pBufHandle, pBuffer + sizeof(MetadataBufferType), sizeof(buffer_handle_t)); 858 ppBuf[0] = (OMX_PTR)pBufHandle; 859 } 860 861 EXIT: 862 FunctionOut(); 863 864 return ret; 865 } 866 867 OMX_ERRORTYPE Exynos_OSAL_SetPrependSPSPPSToIDR( 868 OMX_PTR pComponentParameterStructure, 869 OMX_PTR pbPrependSpsPpsToIdr) 870 { 871 OMX_ERRORTYPE ret = OMX_ErrorNone; 872 PrependSPSPPSToIDRFramesParams *pANBParams = (PrependSPSPPSToIDRFramesParams *)pComponentParameterStructure; 873 874 ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(PrependSPSPPSToIDRFramesParams)); 875 if (ret != OMX_ErrorNone) { 876 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(PrependSPSPPSToIDRFrames) is failed", __func__); 877 goto EXIT; 878 } 879 880 (*((OMX_BOOL *)pbPrependSpsPpsToIdr)) = pANBParams->bEnable; 881 882 EXIT: 883 return ret; 884 } 885 886 OMX_COLOR_FORMATTYPE Exynos_OSAL_Hal2OMXPixelFormat( 887 unsigned int hal_format) 888 { 889 OMX_COLOR_FORMATTYPE omx_format; 890 switch (hal_format) { 891 case HAL_PIXEL_FORMAT_YCbCr_422_I: 892 omx_format = OMX_COLOR_FormatYCbYCr; 893 break; 894 case HAL_PIXEL_FORMAT_YCbCr_420_P: 895 omx_format = OMX_COLOR_FormatYUV420Planar; 896 break; 897 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 898 omx_format = OMX_COLOR_FormatYUV420SemiPlanar; 899 break; 900 case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: 901 omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12TPhysicalAddress; 902 break; 903 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 904 omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; 905 break; 906 case HAL_PIXEL_FORMAT_BGRA_8888: 907 case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: 908 omx_format = OMX_COLOR_Format32bitARGB8888; 909 break; 910 default: 911 omx_format = OMX_COLOR_FormatYUV420Planar; 912 break; 913 } 914 return omx_format; 915 } 916 917 unsigned int Exynos_OSAL_OMX2HalPixelFormat( 918 OMX_COLOR_FORMATTYPE omx_format) 919 { 920 unsigned int hal_format; 921 switch (omx_format) { 922 case OMX_COLOR_FormatYCbYCr: 923 hal_format = HAL_PIXEL_FORMAT_YCbCr_422_I; 924 break; 925 case OMX_COLOR_FormatYUV420Planar: 926 hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; 927 break; 928 case OMX_COLOR_FormatYUV420SemiPlanar: 929 hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP; 930 break; 931 case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: 932 hal_format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; 933 break; 934 case OMX_SEC_COLOR_FormatNV12Tiled: 935 hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; 936 break; 937 case OMX_COLOR_Format32bitARGB8888: 938 hal_format = HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888; 939 break; 940 default: 941 hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; 942 break; 943 } 944 return hal_format; 945 } 946 947 948 #ifdef __cplusplus 949 } 950 #endif 951