diff options
Diffstat (limited to 'exynos3/s5pc110/sec_mm/sec_omx/sec_osal/SEC_OSAL_Buffer.cpp')
-rw-r--r-- | exynos3/s5pc110/sec_mm/sec_omx/sec_osal/SEC_OSAL_Buffer.cpp | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/exynos3/s5pc110/sec_mm/sec_omx/sec_osal/SEC_OSAL_Buffer.cpp b/exynos3/s5pc110/sec_mm/sec_omx/sec_osal/SEC_OSAL_Buffer.cpp new file mode 100644 index 0000000..b28f702 --- /dev/null +++ b/exynos3/s5pc110/sec_mm/sec_omx/sec_osal/SEC_OSAL_Buffer.cpp @@ -0,0 +1,456 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Buffer.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Jinsung Yang (jsgood.yang@samsung.com) + * @version 1.0.2 + * @history + * 2011.5.15 : Create + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "SEC_OMX_Def.h" +#include "SEC_OMX_Macros.h" +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Buffer.h" +#include "SEC_OMX_Basecomponent.h" + +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +#ifdef __cplusplus +} +#endif + +#include <cutils/properties.h> +#include <ui/GraphicBuffer.h> +#include <ui/GraphicBufferMapper.h> +#include <ui/Rect.h> +#include <HardwareAPI.h> +#include <hardware/hardware.h> +#include <MetadataBufferType.h> +#include "hal_public.h" + +#define HAL_PIXEL_FORMAT_C110_NV12 0x100 + +using namespace android; + + +struct AndroidNativeBuffersParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; +}; + +#ifdef USE_ANDROID_EXTENSION +OMX_ERRORTYPE checkVersionANB(OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_VERSIONTYPE* version = NULL; + + + AndroidNativeBuffersParams *pANBP; + pANBP = (AndroidNativeBuffersParams *)ComponentParameterStructure; + + version = (OMX_VERSIONTYPE*)((char*)pANBP + sizeof(OMX_U32)); + if (*((OMX_U32*)pANBP) <= sizeof(AndroidNativeBuffersParams)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (version->s.nVersionMajor != VERSIONMAJOR_NUMBER || + version->s.nVersionMinor != VERSIONMINOR_NUMBER) { + ret = OMX_ErrorVersionMismatch; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +OMX_U32 checkPortIndexANB(OMX_PTR ComponentParameterStructure) +{ + AndroidNativeBuffersParams *pANBP; + pANBP = (AndroidNativeBuffersParams *)ComponentParameterStructure; + + return pANBP->nPortIndex; +} + +OMX_U32 getMetadataBufferType(const uint8_t *ptr) +{ + OMX_U32 type = *(OMX_U32 *) ptr; + SEC_OSAL_Log(SEC_LOG_TRACE, "getMetadataBufferType: %ld", type); + return type; +} + +OMX_U32 getVADDRfromANB(OMX_PTR pUnreadableBuffer, OMX_U32 Width, OMX_U32 Height, void *pVirAddrs[]) +{ + OMX_U32 ret = 0; + android_native_buffer_t *buf; + void *readableBuffer; + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + Rect bounds(Width, Height); + + FunctionIn(); + + buf = (android_native_buffer_t *)pUnreadableBuffer; + SEC_OSAL_Log(SEC_LOG_TRACE, "pUnreadableBuffer:0x%x, buf:0x%x, buf->handle:0x%x", + pUnreadableBuffer, buf, buf->handle); + + ret = mapper.lock(buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, pVirAddrs); + if (ret != 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "mapper.lock Error, Error code:%d", ret); + } + FunctionOut(); + + return ret; +} + +OMX_U32 putVADDRtoANB(OMX_PTR pUnreadableBuffer) +{ + android_native_buffer_t *buf; + void *readableBuffer; + int ret = 0; + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + + FunctionIn(); + + buf = (android_native_buffer_t *)pUnreadableBuffer; + + FunctionOut(); + + return mapper.unlock(buf->handle); +} + +OMX_ERRORTYPE enableAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + EnableAndroidNativeBuffersParams *peanbp; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + peanbp = (EnableAndroidNativeBuffersParams *)ComponentParameterStructure; + pSECPort = &pSECComponent->pSECPort[peanbp->nPortIndex]; + + if (peanbp->enable == OMX_FALSE) { + SEC_OSAL_Log(SEC_LOG_TRACE, "disable AndroidNativeBuffer"); + pSECPort->bUseAndroidNativeBuffer = OMX_FALSE; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "enable AndroidNativeBuffer"); + pSECPort->bUseAndroidNativeBuffer = OMX_TRUE; + pSECPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatANBYUV420SemiPlanar; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE getAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + GetAndroidNativeBufferUsageParams *pganbp; + + FunctionIn(); + + pganbp = (GetAndroidNativeBufferUsageParams *)ComponentParameterStructure; + + pganbp->nUsage = GRALLOC_USAGE_SW_WRITE_OFTEN; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE UseBufferANB( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + if (pSECPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = pBuffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + SEC_OSAL_Free(temp_bufferHeader); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE useAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 frameSize = 0; + OMX_U32 bufWidth, bufHeight; + UseAndroidNativeBufferParams *puanbp; + + FunctionIn(); + + puanbp = (UseAndroidNativeBufferParams *)ComponentParameterStructure; + + OMX_PTR buffer = (void *)puanbp->nativeBuffer.get(); + android_native_buffer_t *buf = (android_native_buffer_t *)buffer; + bufWidth = ((buf->width + 15) / 16) * 16; + bufHeight = ((buf->height + 15) / 16) * 16; + frameSize = (bufWidth * bufHeight * 3) / 2; + SEC_OSAL_Log(SEC_LOG_TRACE, "buffer:0x%x, buf:0x%x, buf->handle:0x%x", buffer, buf, buf->handle); + + ret = UseBufferANB(hComponent, puanbp->bufferHeader, puanbp->nPortIndex, + puanbp->pAppPrivate, frameSize, (OMX_U8 *)buffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE enableStoreMetaDataInBuffers(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + StoreMetaDataInBuffersParams *pStoreMetaData; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pStoreMetaData = (StoreMetaDataInBuffersParams*)ComponentParameterStructure; + pSECPort = &pSECComponent->pSECPort[pStoreMetaData->nPortIndex]; + + if (pStoreMetaData->bStoreMetaData == OMX_FALSE) { + SEC_OSAL_Log(SEC_LOG_TRACE, "disable StoreMetaDataInBuffers"); + pSECPort->bStoreMetaDataInBuffer = OMX_FALSE; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "enable StoreMetaDataInBuffers"); + pSECPort->bStoreMetaDataInBuffer = OMX_TRUE; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_BOOL isMetadataBufferTypeGrallocSource(OMX_BYTE pInputDataBuffer) +{ + OMX_U32 type = getMetadataBufferType(pInputDataBuffer); + + if (type == kMetadataBufferTypeGrallocSource) + return OMX_TRUE; + else + return OMX_FALSE; +} + +OMX_ERRORTYPE preprocessMetaDataInBuffers(OMX_HANDLETYPE hComponent, OMX_BYTE pInputDataBuffer, BUFFER_ADDRESS_INFO *pInputInfo) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 type = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + + type = getMetadataBufferType(pInputDataBuffer); + if (type == kMetadataBufferTypeCameraSource) { + SEC_OSAL_Memcpy(&pInputInfo->YPhyAddr, pInputDataBuffer + 4, sizeof(void *)); + SEC_OSAL_Memcpy(&pInputInfo->CPhyAddr, pInputDataBuffer + 4 + sizeof(void *), sizeof(void *)); + } else if (type == kMetadataBufferTypeGrallocSource){ + IMG_gralloc_module_public_t *module = (IMG_gralloc_module_public_t *)pSECPort->pIMGGrallocModule; + OMX_PTR pUnreadableBuffer = NULL; + OMX_PTR pReadableBuffer = NULL; + OMX_PTR pVirAddrs[3]; + int err = 0; + + pVirAddrs[0] = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr; + pVirAddrs[1] = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr; + pVirAddrs[2] = NULL; + + if (module == NULL) { + err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module); + if(err) { + SEC_OSAL_Log(SEC_LOG_ERROR, "hw_get_module failed (err=%d)\n", err); + ret = OMX_ErrorUndefined; + goto EXIT; + } + pSECPort->pIMGGrallocModule = (OMX_PTR)module; + } + + /**************************************/ + /* IMG CSC RGB to NV12 */ + /**************************************/ + buffer_handle_t buf = *((buffer_handle_t *) (pInputDataBuffer + 4)); + SEC_OSAL_Log(SEC_LOG_TRACE, "buffer handle %p)\n", buf); + err = module->Blit(module, buf, pVirAddrs, HAL_PIXEL_FORMAT_C110_NV12); + if(err) { + SEC_OSAL_Log(SEC_LOG_ERROR, "module->Blit() failed (err=%d)\n", err); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pInputInfo->YPhyAddr = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr; + pInputInfo->CPhyAddr = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr; + } else { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +int isTvOutEnabled() { + char value[PROPERTY_VALUE_MAX]; + property_get("init.svc.tvouthack", value, ""); + return (strcmp(value, "running") == 0); +} + +#endif |