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