1 /* 2 * 3 * Copyright 2010 Samsung Electronics S.LSI Co. LTD 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /* 19 * @file SEC_OSAL_Buffer.c 20 * @brief 21 * @author SeungBeom Kim (sbcrux.kim (at) samsung.com) 22 * Jinsung Yang (jsgood.yang (at) samsung.com) 23 * @version 1.0.2 24 * @history 25 * 2011.5.15 : Create 26 */ 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include "SEC_OMX_Def.h" 37 #include "SEC_OMX_Macros.h" 38 #include "SEC_OSAL_Memory.h" 39 #include "SEC_OSAL_Semaphore.h" 40 #include "SEC_OSAL_Buffer.h" 41 #include "SEC_OMX_Basecomponent.h" 42 43 #define SEC_LOG_OFF 44 #include "SEC_OSAL_Log.h" 45 46 #ifdef __cplusplus 47 } 48 #endif 49 50 #include <ui/GraphicBuffer.h> 51 #include <ui/GraphicBufferMapper.h> 52 #include <ui/Rect.h> 53 #include <HardwareAPI.h> 54 #include <hardware/hardware.h> 55 #include <MetadataBufferType.h> 56 #include "hal_public.h" 57 58 #define HAL_PIXEL_FORMAT_C110_NV12 0x100 59 60 using namespace android; 61 62 63 struct AndroidNativeBuffersParams { 64 OMX_U32 nSize; 65 OMX_VERSIONTYPE nVersion; 66 OMX_U32 nPortIndex; 67 }; 68 69 #ifdef USE_ANDROID_EXTENSION 70 OMX_ERRORTYPE checkVersionANB(OMX_PTR ComponentParameterStructure) 71 { 72 OMX_ERRORTYPE ret = OMX_ErrorNone; 73 OMX_VERSIONTYPE* version = NULL; 74 75 76 AndroidNativeBuffersParams *pANBP; 77 pANBP = (AndroidNativeBuffersParams *)ComponentParameterStructure; 78 79 version = (OMX_VERSIONTYPE*)((char*)pANBP + sizeof(OMX_U32)); 80 if (*((OMX_U32*)pANBP) <= sizeof(AndroidNativeBuffersParams)) { 81 ret = OMX_ErrorBadParameter; 82 goto EXIT; 83 } 84 if (version->s.nVersionMajor != VERSIONMAJOR_NUMBER || 85 version->s.nVersionMinor != VERSIONMINOR_NUMBER) { 86 ret = OMX_ErrorVersionMismatch; 87 goto EXIT; 88 } 89 90 ret = OMX_ErrorNone; 91 92 EXIT: 93 return ret; 94 } 95 96 OMX_U32 checkPortIndexANB(OMX_PTR ComponentParameterStructure) 97 { 98 AndroidNativeBuffersParams *pANBP; 99 pANBP = (AndroidNativeBuffersParams *)ComponentParameterStructure; 100 101 return pANBP->nPortIndex; 102 } 103 104 OMX_U32 getMetadataBufferType(const uint8_t *ptr) 105 { 106 OMX_U32 type = *(OMX_U32 *) ptr; 107 SEC_OSAL_Log(SEC_LOG_TRACE, "getMetadataBufferType: %ld", type); 108 return type; 109 } 110 111 OMX_U32 getVADDRfromANB(OMX_PTR pUnreadableBuffer, OMX_U32 Width, OMX_U32 Height, void *pVirAddrs[]) 112 { 113 OMX_U32 ret = 0; 114 android_native_buffer_t *buf; 115 void *readableBuffer; 116 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 117 Rect bounds(Width, Height); 118 119 FunctionIn(); 120 121 buf = (android_native_buffer_t *)pUnreadableBuffer; 122 SEC_OSAL_Log(SEC_LOG_TRACE, "pUnreadableBuffer:0x%x, buf:0x%x, buf->handle:0x%x", 123 pUnreadableBuffer, buf, buf->handle); 124 125 ret = mapper.lock(buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, pVirAddrs); 126 if (ret != 0) { 127 SEC_OSAL_Log(SEC_LOG_ERROR, "mapper.lock Error, Error code:%d", ret); 128 } 129 FunctionOut(); 130 131 return ret; 132 } 133 134 OMX_U32 putVADDRtoANB(OMX_PTR pUnreadableBuffer) 135 { 136 android_native_buffer_t *buf; 137 void *readableBuffer; 138 int ret = 0; 139 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 140 141 FunctionIn(); 142 143 buf = (android_native_buffer_t *)pUnreadableBuffer; 144 145 FunctionOut(); 146 147 return mapper.unlock(buf->handle); 148 } 149 150 OMX_ERRORTYPE enableAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure) 151 { 152 OMX_ERRORTYPE ret = OMX_ErrorNone; 153 OMX_COMPONENTTYPE *pOMXComponent = NULL; 154 SEC_OMX_BASECOMPONENT *pSECComponent = NULL; 155 SEC_OMX_BASEPORT *pSECPort = NULL; 156 157 EnableAndroidNativeBuffersParams *peanbp; 158 159 FunctionIn(); 160 161 if (hComponent == NULL) { 162 ret = OMX_ErrorBadParameter; 163 goto EXIT; 164 } 165 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 166 if (pOMXComponent->pComponentPrivate == NULL) { 167 ret = OMX_ErrorBadParameter; 168 goto EXIT; 169 } 170 pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 171 peanbp = (EnableAndroidNativeBuffersParams *)ComponentParameterStructure; 172 pSECPort = &pSECComponent->pSECPort[peanbp->nPortIndex]; 173 174 if (peanbp->enable == OMX_FALSE) { 175 SEC_OSAL_Log(SEC_LOG_TRACE, "disable AndroidNativeBuffer"); 176 pSECPort->bUseAndroidNativeBuffer = OMX_FALSE; 177 } else { 178 SEC_OSAL_Log(SEC_LOG_TRACE, "enable AndroidNativeBuffer"); 179 pSECPort->bUseAndroidNativeBuffer = OMX_TRUE; 180 pSECPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatANBYUV420SemiPlanar; 181 } 182 183 ret = OMX_ErrorNone; 184 185 EXIT: 186 FunctionOut(); 187 188 return ret; 189 } 190 191 OMX_ERRORTYPE getAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure) 192 { 193 OMX_ERRORTYPE ret = OMX_ErrorNone; 194 OMX_COMPONENTTYPE *pOMXComponent = NULL; 195 SEC_OMX_BASECOMPONENT *pSECComponent = NULL; 196 SEC_OMX_BASEPORT *pSECPort = NULL; 197 198 GetAndroidNativeBufferUsageParams *pganbp; 199 200 FunctionIn(); 201 202 pganbp = (GetAndroidNativeBufferUsageParams *)ComponentParameterStructure; 203 204 pganbp->nUsage = GRALLOC_USAGE_SW_WRITE_OFTEN; 205 206 ret = OMX_ErrorNone; 207 208 EXIT: 209 FunctionOut(); 210 211 return ret; 212 } 213 214 OMX_ERRORTYPE UseBufferANB( 215 OMX_IN OMX_HANDLETYPE hComponent, 216 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 217 OMX_IN OMX_U32 nPortIndex, 218 OMX_IN OMX_PTR pAppPrivate, 219 OMX_IN OMX_U32 nSizeBytes, 220 OMX_IN OMX_U8 *pBuffer) 221 { 222 OMX_ERRORTYPE ret = OMX_ErrorNone; 223 OMX_COMPONENTTYPE *pOMXComponent = NULL; 224 SEC_OMX_BASECOMPONENT *pSECComponent = NULL; 225 SEC_OMX_BASEPORT *pSECPort = NULL; 226 OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; 227 int i = 0; 228 229 FunctionIn(); 230 231 if (hComponent == NULL) { 232 ret = OMX_ErrorBadParameter; 233 goto EXIT; 234 } 235 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 236 if (pOMXComponent->pComponentPrivate == NULL) { 237 ret = OMX_ErrorBadParameter; 238 goto EXIT; 239 } 240 pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 241 242 pSECPort = &pSECComponent->pSECPort[nPortIndex]; 243 if (nPortIndex >= pSECComponent->portParam.nPorts) { 244 ret = OMX_ErrorBadPortIndex; 245 goto EXIT; 246 } 247 if (pSECPort->portState != OMX_StateIdle) { 248 ret = OMX_ErrorIncorrectStateOperation; 249 goto EXIT; 250 } 251 252 if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { 253 ret = OMX_ErrorBadPortIndex; 254 goto EXIT; 255 } 256 257 temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); 258 if (temp_bufferHeader == NULL) { 259 ret = OMX_ErrorInsufficientResources; 260 goto EXIT; 261 } 262 SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); 263 264 for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { 265 if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { 266 pSECPort->bufferHeader[i] = temp_bufferHeader; 267 pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); 268 INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); 269 temp_bufferHeader->pBuffer = pBuffer; 270 temp_bufferHeader->nAllocLen = nSizeBytes; 271 temp_bufferHeader->pAppPrivate = pAppPrivate; 272 if (nPortIndex == INPUT_PORT_INDEX) 273 temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; 274 else 275 temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; 276 277 pSECPort->assignedBufferNum++; 278 if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { 279 pSECPort->portDefinition.bPopulated = OMX_TRUE; 280 /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ 281 SEC_OSAL_SemaphorePost(pSECPort->loadedResource); 282 /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ 283 } 284 *ppBufferHdr = temp_bufferHeader; 285 ret = OMX_ErrorNone; 286 goto EXIT; 287 } 288 } 289 290 SEC_OSAL_Free(temp_bufferHeader); 291 ret = OMX_ErrorInsufficientResources; 292 293 EXIT: 294 FunctionOut(); 295 296 return ret; 297 } 298 299 OMX_ERRORTYPE useAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure) 300 { 301 OMX_ERRORTYPE ret = OMX_ErrorNone; 302 OMX_COMPONENTTYPE *pOMXComponent = NULL; 303 SEC_OMX_BASECOMPONENT *pSECComponent = NULL; 304 SEC_OMX_BASEPORT *pSECPort = NULL; 305 OMX_U32 frameSize = 0; 306 OMX_U32 bufWidth, bufHeight; 307 UseAndroidNativeBufferParams *puanbp; 308 309 FunctionIn(); 310 311 puanbp = (UseAndroidNativeBufferParams *)ComponentParameterStructure; 312 313 OMX_PTR buffer = (void *)puanbp->nativeBuffer.get(); 314 android_native_buffer_t *buf = (android_native_buffer_t *)buffer; 315 bufWidth = ((buf->width + 15) / 16) * 16; 316 bufHeight = ((buf->height + 15) / 16) * 16; 317 frameSize = (bufWidth * bufHeight * 3) / 2; 318 SEC_OSAL_Log(SEC_LOG_TRACE, "buffer:0x%x, buf:0x%x, buf->handle:0x%x", buffer, buf, buf->handle); 319 320 ret = UseBufferANB(hComponent, puanbp->bufferHeader, puanbp->nPortIndex, 321 puanbp->pAppPrivate, frameSize, (OMX_U8 *)buffer); 322 323 EXIT: 324 FunctionOut(); 325 326 return ret; 327 } 328 329 OMX_ERRORTYPE enableStoreMetaDataInBuffers(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure) 330 { 331 OMX_ERRORTYPE ret = OMX_ErrorNone; 332 OMX_COMPONENTTYPE *pOMXComponent = NULL; 333 SEC_OMX_BASECOMPONENT *pSECComponent = NULL; 334 SEC_OMX_BASEPORT *pSECPort = NULL; 335 336 StoreMetaDataInBuffersParams *pStoreMetaData; 337 338 FunctionIn(); 339 340 if (hComponent == NULL) { 341 ret = OMX_ErrorBadParameter; 342 goto EXIT; 343 } 344 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 345 if (pOMXComponent->pComponentPrivate == NULL) { 346 ret = OMX_ErrorBadParameter; 347 goto EXIT; 348 } 349 pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 350 pStoreMetaData = (StoreMetaDataInBuffersParams*)ComponentParameterStructure; 351 pSECPort = &pSECComponent->pSECPort[pStoreMetaData->nPortIndex]; 352 353 if (pStoreMetaData->bStoreMetaData == OMX_FALSE) { 354 SEC_OSAL_Log(SEC_LOG_TRACE, "disable StoreMetaDataInBuffers"); 355 pSECPort->bStoreMetaDataInBuffer = OMX_FALSE; 356 } else { 357 SEC_OSAL_Log(SEC_LOG_TRACE, "enable StoreMetaDataInBuffers"); 358 pSECPort->bStoreMetaDataInBuffer = OMX_TRUE; 359 } 360 361 EXIT: 362 FunctionOut(); 363 364 return ret; 365 } 366 367 OMX_BOOL isMetadataBufferTypeGrallocSource(OMX_BYTE pInputDataBuffer) 368 { 369 OMX_U32 type = getMetadataBufferType(pInputDataBuffer); 370 371 if (type == kMetadataBufferTypeGrallocSource) 372 return OMX_TRUE; 373 else 374 return OMX_FALSE; 375 } 376 377 OMX_ERRORTYPE preprocessMetaDataInBuffers(OMX_HANDLETYPE hComponent, OMX_BYTE pInputDataBuffer, BUFFER_ADDRESS_INFO *pInputInfo) 378 { 379 OMX_ERRORTYPE ret = OMX_ErrorNone; 380 OMX_COMPONENTTYPE *pOMXComponent = NULL; 381 SEC_OMX_BASECOMPONENT *pSECComponent = NULL; 382 SEC_OMX_BASEPORT *pSECPort = NULL; 383 OMX_U32 type = 0; 384 385 FunctionIn(); 386 387 if (hComponent == NULL) { 388 ret = OMX_ErrorBadParameter; 389 goto EXIT; 390 } 391 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 392 if (pOMXComponent->pComponentPrivate == NULL) { 393 ret = OMX_ErrorBadParameter; 394 goto EXIT; 395 } 396 pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 397 pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; 398 399 type = getMetadataBufferType(pInputDataBuffer); 400 if (type == kMetadataBufferTypeCameraSource) { 401 SEC_OSAL_Memcpy(&pInputInfo->YPhyAddr, pInputDataBuffer + 4, sizeof(void *)); 402 SEC_OSAL_Memcpy(&pInputInfo->CPhyAddr, pInputDataBuffer + 4 + sizeof(void *), sizeof(void *)); 403 } else if (type == kMetadataBufferTypeGrallocSource){ 404 IMG_gralloc_module_public_t *module = (IMG_gralloc_module_public_t *)pSECPort->pIMGGrallocModule; 405 OMX_PTR pUnreadableBuffer = NULL; 406 OMX_PTR pReadableBuffer = NULL; 407 OMX_PTR pVirAddrs[3]; 408 int err = 0; 409 410 pVirAddrs[0] = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr; 411 pVirAddrs[1] = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr; 412 pVirAddrs[2] = NULL; 413 414 if (module == NULL) { 415 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module); 416 if(err) { 417 SEC_OSAL_Log(SEC_LOG_ERROR, "hw_get_module failed (err=%d)\n", err); 418 ret = OMX_ErrorUndefined; 419 goto EXIT; 420 } 421 pSECPort->pIMGGrallocModule = (OMX_PTR)module; 422 } 423 424 /**************************************/ 425 /* IMG CSC RGB to NV12 */ 426 /**************************************/ 427 buffer_handle_t buf = *((buffer_handle_t *) (pInputDataBuffer + 4)); 428 SEC_OSAL_Log(SEC_LOG_TRACE, "buffer handle %p)\n", buf); 429 err = module->Blit(module, buf, pVirAddrs, HAL_PIXEL_FORMAT_C110_NV12); 430 if(err) { 431 SEC_OSAL_Log(SEC_LOG_ERROR, "module->Blit() failed (err=%d)\n", err); 432 ret = OMX_ErrorUndefined; 433 goto EXIT; 434 } 435 436 pInputInfo->YPhyAddr = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr; 437 pInputInfo->CPhyAddr = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr; 438 } else { 439 ret = OMX_ErrorNotImplemented; 440 goto EXIT; 441 } 442 443 EXIT: 444 FunctionOut(); 445 446 return ret; 447 } 448 449 #endif 450