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