blob: 997b92601fa3662c11734d097d96b3bb9cd3e6a2 [file] [log] [blame]
/*
* Copyright 2012 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 Exynos_OSAL_Android.cpp
* @brief
* @author Seungbeom Kim (sbcrux.kim@samsung.com)
* @author Hyeyeon Chung (hyeon.chung@samsung.com)
* @author Yunji Kim (yunji.kim@samsung.com)
* @author Jinsung Yang (jsgood.yang@samsung.com)
* @version 2.0.0
* @history
* 2012.02.20 : Create
*/
#include <stdio.h>
#include <stdlib.h>
#include <system/window.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferMapper.h>
#include <ui/Rect.h>
#include <media/hardware/HardwareAPI.h>
#include <hardware/hardware.h>
#include <media/hardware/OMXPluginBase.h>
#include <media/hardware/MetadataBufferType.h>
#include <gralloc_priv.h>
#include "Exynos_OSAL_Mutex.h"
#include "Exynos_OSAL_Semaphore.h"
#include "Exynos_OMX_Baseport.h"
#include "Exynos_OMX_Basecomponent.h"
#include "Exynos_OMX_Macros.h"
#include "Exynos_OMX_Vdec.h"
#include "Exynos_OMX_Venc.h"
#include "Exynos_OSAL_Android.h"
#include "exynos_format.h"
#include "ion.h"
#undef EXYNOS_LOG_TAG
#define EXYNOS_LOG_TAG "Exynos_OSAL_Android"
#define EXYNOS_LOG_OFF
#include "Exynos_OSAL_Log.h"
using namespace android;
#ifdef __cplusplus
extern "C" {
#endif
int getIonFd(gralloc_module_t const *module)
{
private_module_t* m = const_cast<private_module_t*>(reinterpret_cast<const private_module_t*>(module));
return m->ionfd;
}
OMX_ERRORTYPE Exynos_OSAL_LockANBHandle(
OMX_IN OMX_U32 handle,
OMX_IN OMX_U32 width,
OMX_IN OMX_U32 height,
OMX_IN OMX_COLOR_FORMATTYPE format,
OMX_OUT OMX_U32 *pStride,
OMX_OUT OMX_PTR planes)
{
FunctionIn();
OMX_ERRORTYPE ret = OMX_ErrorNone;
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
buffer_handle_t bufferHandle = (buffer_handle_t) handle;
private_handle_t *priv_hnd = (private_handle_t *) bufferHandle;
Rect bounds(width, height);
ExynosVideoPlane *vplanes = (ExynosVideoPlane *) planes;
void *vaddr[MAX_BUFFER_PLANE];
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x", __func__, handle);
int usage = 0;
switch (format) {
case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420SemiPlanar:
case OMX_SEC_COLOR_FormatNV12Tiled:
usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
break;
default:
usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
break;
}
if (mapper.lock(bufferHandle, usage, bounds, vaddr) != 0) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.lock() fail", __func__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
vplanes[0].fd = priv_hnd->fd;
vplanes[0].offset = 0;
vplanes[0].addr = vaddr[0];
vplanes[1].fd = priv_hnd->fd1;
vplanes[1].offset = 0;
vplanes[1].addr = vaddr[1];
vplanes[2].fd = priv_hnd->fd2;
vplanes[2].offset = 0;
vplanes[2].addr = vaddr[2];
*pStride = priv_hnd->stride;
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer locked: 0x%x", __func__, *vaddr);
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_UnlockANBHandle(OMX_IN OMX_U32 handle)
{
FunctionIn();
OMX_ERRORTYPE ret = OMX_ErrorNone;
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
buffer_handle_t bufferHandle = (buffer_handle_t) handle;
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x", __func__, handle);
if (mapper.unlock(bufferHandle) != 0) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.unlock() fail", __func__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer unlocked: 0x%x", __func__, handle);
EXIT:
FunctionOut();
return ret;
}
OMX_COLOR_FORMATTYPE Exynos_OSAL_GetANBColorFormat(OMX_IN OMX_U32 handle)
{
FunctionIn();
OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused;
private_handle_t *priv_hnd = (private_handle_t *) handle;
ret = Exynos_OSAL_Hal2OMXPixelFormat(priv_hnd->format);
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ColorFormat: 0x%x", ret);
EXIT:
FunctionOut();
return ret;
}
OMX_U32 Exynos_OSAL_GetANBStride(OMX_IN OMX_U32 handle)
{
FunctionIn();
OMX_U32 nStride = 0;
private_handle_t *priv_hnd = (private_handle_t *) handle;
nStride = priv_hnd->stride;
EXIT:
FunctionOut();
return nStride;
}
OMX_ERRORTYPE Exynos_OSAL_LockMetaData(
OMX_IN OMX_PTR pBuffer,
OMX_IN OMX_U32 width,
OMX_IN OMX_U32 height,
OMX_IN OMX_COLOR_FORMATTYPE format,
OMX_OUT OMX_U32 *pStride,
OMX_OUT OMX_PTR planes)
{
FunctionIn();
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_PTR pBuf;
ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf);
if (ret == OMX_ErrorNone) {
ret = Exynos_OSAL_LockANBHandle((OMX_U32)pBuf, width, height, format, pStride, planes);
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(OMX_IN OMX_PTR pBuffer)
{
FunctionIn();
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_PTR pBuf;
ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf);
if (ret == OMX_ErrorNone)
ret = Exynos_OSAL_UnlockANBHandle((OMX_U32)pBuf);
EXIT:
FunctionOut();
return ret;
}
OMX_HANDLETYPE Exynos_OSAL_RefANB_Create()
{
int i = 0;
EXYNOS_OMX_REF_HANDLE *phREF = NULL;
gralloc_module_t *module = NULL;
OMX_ERRORTYPE err = OMX_ErrorNone;
FunctionIn();
phREF = (EXYNOS_OMX_REF_HANDLE *) Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_REF_HANDLE));
if (phREF == NULL)
goto EXIT;
Exynos_OSAL_Memset(phREF, 0, sizeof(EXYNOS_OMX_REF_HANDLE));
for (i = 0; i < MAX_BUFFER_REF; i++) {
phREF->SharedBuffer[i].BufferFd = -1;
phREF->SharedBuffer[i].BufferFd1 = -1;
phREF->SharedBuffer[i].BufferFd2 = -1;
}
hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module);
phREF->pGrallocModule = (OMX_PTR)module;
err = Exynos_OSAL_MutexCreate(&phREF->hMutex);
if (err != OMX_ErrorNone) {
Exynos_OSAL_Free(phREF);
phREF = NULL;
}
EXIT:
FunctionOut();
return ((OMX_HANDLETYPE)phREF);
}
OMX_ERRORTYPE Exynos_OSAL_RefANB_Reset(OMX_HANDLETYPE hREF)
{
int i = 0;
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
gralloc_module_t* module = NULL;
FunctionIn();
if (phREF == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
module = (gralloc_module_t *)phREF->pGrallocModule;
Exynos_OSAL_MutexLock(phREF->hMutex);
for (i = 0; i < MAX_BUFFER_REF; i++) {
if (phREF->SharedBuffer[i].BufferFd > -1) {
while(phREF->SharedBuffer[i].cnt > 0) {
if (phREF->SharedBuffer[i].BufferFd > -1)
ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle);
if (phREF->SharedBuffer[i].BufferFd1 > -1)
ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle1);
if (phREF->SharedBuffer[i].BufferFd2 > -1)
ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle2);
phREF->SharedBuffer[i].cnt--;
}
phREF->SharedBuffer[i].BufferFd = -1;
phREF->SharedBuffer[i].BufferFd1 = -1;
phREF->SharedBuffer[i].BufferFd2 = -1;
phREF->SharedBuffer[i].pIonHandle = NULL;
phREF->SharedBuffer[i].pIonHandle1 = NULL;
phREF->SharedBuffer[i].pIonHandle2 = NULL;
}
}
Exynos_OSAL_MutexUnlock(phREF->hMutex);
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_RefANB_Terminate(OMX_HANDLETYPE hREF)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
FunctionIn();
if (phREF == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
Exynos_OSAL_RefANB_Reset(phREF);
phREF->pGrallocModule = NULL;
ret = Exynos_OSAL_MutexTerminate(phREF->hMutex);
if (ret != OMX_ErrorNone)
goto EXIT;
Exynos_OSAL_Free(phREF);
phREF = NULL;
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_RefANB_Increase(OMX_HANDLETYPE hREF, OMX_PTR pBuffer)
{
int i;
OMX_ERRORTYPE ret = OMX_ErrorNone;
buffer_handle_t bufferHandle = (buffer_handle_t) pBuffer; //pANB->handle
private_handle_t *priv_hnd = (private_handle_t *) bufferHandle;
EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
gralloc_module_t* module = NULL;
unsigned long *pIonHandle;
unsigned long *pIonHandle1;
unsigned long *pIonHandle2;
FunctionIn();
if (phREF == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
module = (gralloc_module_t *)phREF->pGrallocModule;
Exynos_OSAL_MutexLock(phREF->hMutex);
if (priv_hnd->fd >= 0) {
ion_incRef(getIonFd(module), priv_hnd->fd, &pIonHandle);
}
if (priv_hnd->fd1 >= 0) {
ion_incRef(getIonFd(module), priv_hnd->fd1, &pIonHandle1);
}
if (priv_hnd->fd2 >= 0) {
ion_incRef(getIonFd(module), priv_hnd->fd2, &pIonHandle2);
}
for (i = 0; i < MAX_BUFFER_REF; i++) {
if (phREF->SharedBuffer[i].BufferFd == priv_hnd->fd) {
phREF->SharedBuffer[i].cnt++;
break;
}
}
if (i >= MAX_BUFFER_REF) {
for (i = 0; i < MAX_BUFFER_REF; i++) {
if (phREF->SharedBuffer[i].BufferFd == -1) {
phREF->SharedBuffer[i].BufferFd = priv_hnd->fd;
phREF->SharedBuffer[i].BufferFd1 = priv_hnd->fd1;
phREF->SharedBuffer[i].BufferFd2 = priv_hnd->fd2;
phREF->SharedBuffer[i].pIonHandle = pIonHandle;
phREF->SharedBuffer[i].pIonHandle1 = pIonHandle1;
phREF->SharedBuffer[i].pIonHandle2 = pIonHandle2;
phREF->SharedBuffer[i].cnt++;
break;
}
}
}
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "inc fd:%d cnt:%d", phREF->SharedBuffer[i].BufferFd, phREF->SharedBuffer[i].cnt);
Exynos_OSAL_MutexUnlock(phREF->hMutex);
if (i >= MAX_BUFFER_REF) {
ret = OMX_ErrorUndefined;
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_RefANB_Decrease(OMX_HANDLETYPE hREF, OMX_U32 BufferFd)
{
int i;
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
gralloc_module_t* module = NULL;
FunctionIn();
if ((phREF == NULL) || (BufferFd < 0)) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
module = (gralloc_module_t *)phREF->pGrallocModule;
Exynos_OSAL_MutexLock(phREF->hMutex);
for (i = 0; i < MAX_BUFFER_REF; i++) {
if (phREF->SharedBuffer[i].BufferFd == BufferFd) {
if (phREF->SharedBuffer[i].BufferFd > -1)
ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle);
if (phREF->SharedBuffer[i].BufferFd1 > -1)
ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle1);
if (phREF->SharedBuffer[i].BufferFd2 > -1)
ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle2);
phREF->SharedBuffer[i].cnt--;
if (phREF->SharedBuffer[i].cnt == 0) {
phREF->SharedBuffer[i].BufferFd = -1;
phREF->SharedBuffer[i].BufferFd1 = -1;
phREF->SharedBuffer[i].BufferFd2 = -1;
phREF->SharedBuffer[i].pIonHandle = NULL;
phREF->SharedBuffer[i].pIonHandle1 = NULL;
phREF->SharedBuffer[i].pIonHandle2 = NULL;
}
break;
}
}
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dec fd:%d cnt:%d", phREF->SharedBuffer[i].BufferFd, phREF->SharedBuffer[i].cnt);
Exynos_OSAL_MutexUnlock(phREF->hMutex);
if (i >= MAX_BUFFER_REF) {
ret = OMX_ErrorUndefined;
goto EXIT;
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE useAndroidNativeBuffer(
EXYNOS_OMX_BASEPORT *pExynosPort,
OMX_BUFFERHEADERTYPE **ppBufferHdr,
OMX_U32 nPortIndex,
OMX_PTR pAppPrivate,
OMX_U32 nSizeBytes,
OMX_U8 *pBuffer)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL;
unsigned int i = 0;
OMX_U32 width, height;
OMX_U32 stride;
ExynosVideoPlane planes[MAX_BUFFER_PLANE];
FunctionIn();
if (pExynosPort == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
if (pExynosPort->portState != OMX_StateIdle) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
if (temp_bufferHeader == NULL) {
ret = OMX_ErrorInsufficientResources;
goto EXIT;
}
Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader;
pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED);
INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer;
temp_bufferHeader->pBuffer = (OMX_U8 *)pANB->handle;
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;
width = pExynosPort->portDefinition.format.video.nFrameWidth;
height = pExynosPort->portDefinition.format.video.nFrameHeight;
Exynos_OSAL_LockANBHandle((OMX_U32)temp_bufferHeader->pBuffer, width, height,
pExynosPort->portDefinition.format.video.eColorFormat,
&stride, planes);
pExynosPort->extendBufferHeader[i].buf_fd[0] = planes[0].fd;
pExynosPort->extendBufferHeader[i].pYUVBuf[0] = planes[0].addr;
pExynosPort->extendBufferHeader[i].buf_fd[1] = planes[1].fd;
pExynosPort->extendBufferHeader[i].pYUVBuf[1] = planes[1].addr;
pExynosPort->extendBufferHeader[i].buf_fd[2] = planes[2].fd;
pExynosPort->extendBufferHeader[i].pYUVBuf[2] = planes[2].addr;
Exynos_OSAL_UnlockANBHandle((OMX_U32)temp_bufferHeader->pBuffer);
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "useAndroidNativeBuffer: buf %d pYUVBuf[0]:0x%x (fd:%d), pYUVBuf[1]:0x%x (fd:%d)",
i, pExynosPort->extendBufferHeader[i].pYUVBuf[0], planes[0].fd,
pExynosPort->extendBufferHeader[i].pYUVBuf[1], planes[1].fd);
pExynosPort->assignedBufferNum++;
if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) {
pExynosPort->portDefinition.bPopulated = OMX_TRUE;
/* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
/* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
}
*ppBufferHdr = temp_bufferHeader;
ret = OMX_ErrorNone;
goto EXIT;
}
}
Exynos_OSAL_Free(temp_bufferHeader);
ret = OMX_ErrorInsufficientResources;
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_GetANBParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR ComponentParameterStructure)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if (hComponent == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pExynosComponent->currentState == OMX_StateInvalid ) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
if (ComponentParameterStructure == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
switch (nIndex) {
case OMX_IndexParamGetAndroidNativeBuffer:
{
GetAndroidNativeBufferUsageParams *pANBParams = (GetAndroidNativeBufferUsageParams *) ComponentParameterStructure;
OMX_U32 portIndex = pANBParams->nPortIndex;
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamGetAndroidNativeBuffer", __func__);
ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(GetAndroidNativeBufferUsageParams));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(GetAndroidNativeBufferUsageParams) is failed", __func__);
goto EXIT;
}
if (portIndex >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
/* NOTE: OMX_IndexParamGetAndroidNativeBuffer returns original 'nUsage' without any
* modifications since currently not defined what the 'nUsage' is for.
*/
pANBParams->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
}
break;
default:
{
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex);
ret = OMX_ErrorUnsupportedIndex;
goto EXIT;
}
break;
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_SetANBParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR ComponentParameterStructure)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if (hComponent == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pExynosComponent->currentState == OMX_StateInvalid ) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
if (ComponentParameterStructure == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
switch (nIndex) {
case OMX_IndexParamEnableAndroidBuffers:
{
EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
EnableAndroidNativeBuffersParams *pANBParams = (EnableAndroidNativeBuffersParams *) ComponentParameterStructure;
OMX_U32 portIndex = pANBParams->nPortIndex;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamEnableAndroidNativeBuffers", __func__);
ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(EnableAndroidNativeBuffersParams));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(EnableAndroidNativeBuffersParams) is failed", __func__);
goto EXIT;
}
if (portIndex >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
pExynosPort = &pExynosComponent->pExynosPort[portIndex];
if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
/* ANB and DPB Buffer Sharing */
if (pExynosPort->bStoreMetaData != OMX_TRUE)
pExynosPort->bIsANBEnabled = pANBParams->enable;
if ((portIndex == OUTPUT_PORT_INDEX) &&
(pExynosPort->bIsANBEnabled == OMX_TRUE) &&
((pExynosPort->bufferProcessType & BUFFER_ANBSHARE) == BUFFER_ANBSHARE)) {
pExynosPort->bufferProcessType = BUFFER_SHARE;
pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexParamEnableAndroidBuffers & bufferProcessType change to BUFFER_SHARE");
}
}
break;
case OMX_IndexParamUseAndroidNativeBuffer:
{
EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
UseAndroidNativeBufferParams *pANBParams = (UseAndroidNativeBufferParams *) ComponentParameterStructure;
OMX_U32 portIndex = pANBParams->nPortIndex;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
android_native_buffer_t *pANB;
OMX_U32 nSizeBytes;
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamUseAndroidNativeBuffer, portIndex: %d", __func__, portIndex);
ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(UseAndroidNativeBufferParams));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(UseAndroidNativeBufferParams) is failed", __func__);
goto EXIT;
}
if (portIndex >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
pExynosPort = &pExynosComponent->pExynosPort[portIndex];
if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if (pExynosPort->portState != OMX_StateIdle) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Port state should be IDLE", __func__);
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
pANB = pANBParams->nativeBuffer.get();
/* MALI alignment restriction */
nSizeBytes = ALIGN(pANB->width, 16) * ALIGN(pANB->height, 16);
nSizeBytes += ALIGN(pANB->width / 2, 16) * ALIGN(pANB->height / 2, 16) * 2;
ret = useAndroidNativeBuffer(pExynosPort,
pANBParams->bufferHeader,
pANBParams->nPortIndex,
pANBParams->pAppPrivate,
nSizeBytes,
(OMX_U8 *) pANB);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: useAndroidNativeBuffer is failed: err=0x%x", __func__,ret);
goto EXIT;
}
}
break;
case OMX_IndexParamStoreMetaDataBuffer:
{
StoreMetaDataInBuffersParams *pANBParams = (StoreMetaDataInBuffersParams *) ComponentParameterStructure;
OMX_U32 portIndex = pANBParams->nPortIndex;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamStoreMetaDataBuffer", __func__);
ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(StoreMetaDataInBuffersParams));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(StoreMetaDataInBuffersParams) is failed", __func__);
goto EXIT;
}
if (portIndex >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
pExynosPort = &pExynosComponent->pExynosPort[portIndex];
if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
pExynosPort->bStoreMetaData = pANBParams->bStoreMetaData;
if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) {
EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;;
} else if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) {
EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;;
if ((portIndex == OUTPUT_PORT_INDEX) &&
(pExynosPort->bStoreMetaData == OMX_TRUE) &&
((pExynosPort->bufferProcessType & BUFFER_ANBSHARE) == BUFFER_ANBSHARE)) {
pExynosPort->bufferProcessType = BUFFER_SHARE;
pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexParamStoreMetaDataBuffer & bufferProcessType change to BUFFER_SHARE");
}
}
}
break;
default:
{
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex);
ret = OMX_ErrorUnsupportedIndex;
goto EXIT;
}
break;
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer,
OMX_OUT OMX_PTR *ppBuf)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
MetadataBufferType type;
FunctionIn();
/*
* meta data contains the following data format.
* payload depends on the MetadataBufferType
* --------------------------------------------------------------
* | MetadataBufferType | payload |
* --------------------------------------------------------------
*
* If MetadataBufferType is kMetadataBufferTypeCameraSource, then
* --------------------------------------------------------------
* | kMetadataBufferTypeCameraSource | physical addr. of Y |physical addr. of CbCr |
* --------------------------------------------------------------
*
* If MetadataBufferType is kMetadataBufferTypeGrallocSource, then
* --------------------------------------------------------------
* | kMetadataBufferTypeGrallocSource | buffer_handle_t |
* --------------------------------------------------------------
*/
/* MetadataBufferType */
Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType));
if (type == kMetadataBufferTypeCameraSource) {
void *pAddress = NULL;
/* Address. of Y */
Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType), sizeof(void *));
ppBuf[0] = (void *)pAddress;
/* Address. of CbCr */
Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType) + sizeof(void *), sizeof(void *));
ppBuf[1] = (void *)pAddress;
} else if (type == kMetadataBufferTypeGrallocSource) {
buffer_handle_t pBufHandle;
/* buffer_handle_t */
Exynos_OSAL_Memcpy(&pBufHandle, pBuffer + sizeof(MetadataBufferType), sizeof(buffer_handle_t));
ppBuf[0] = (OMX_PTR)pBufHandle;
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OSAL_SetPrependSPSPPSToIDR(
OMX_PTR pComponentParameterStructure,
OMX_PTR pbPrependSpsPpsToIdr)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
PrependSPSPPSToIDRFramesParams *pANBParams = (PrependSPSPPSToIDRFramesParams *)pComponentParameterStructure;
ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(PrependSPSPPSToIDRFramesParams));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(PrependSPSPPSToIDRFrames) is failed", __func__);
goto EXIT;
}
(*((OMX_BOOL *)pbPrependSpsPpsToIdr)) = pANBParams->bEnable;
EXIT:
return ret;
}
OMX_COLOR_FORMATTYPE Exynos_OSAL_Hal2OMXPixelFormat(
unsigned int hal_format)
{
OMX_COLOR_FORMATTYPE omx_format;
switch (hal_format) {
case HAL_PIXEL_FORMAT_YCbCr_422_I:
omx_format = OMX_COLOR_FormatYCbYCr;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P:
omx_format = OMX_COLOR_FormatYUV420Planar;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
omx_format = OMX_COLOR_FormatYUV420SemiPlanar;
break;
case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED:
omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12TPhysicalAddress;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
break;
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
omx_format = OMX_COLOR_Format32bitARGB8888;
break;
default:
omx_format = OMX_COLOR_FormatYUV420Planar;
break;
}
return omx_format;
}
unsigned int Exynos_OSAL_OMX2HalPixelFormat(
OMX_COLOR_FORMATTYPE omx_format)
{
unsigned int hal_format;
switch (omx_format) {
case OMX_COLOR_FormatYCbYCr:
hal_format = HAL_PIXEL_FORMAT_YCbCr_422_I;
break;
case OMX_COLOR_FormatYUV420Planar:
hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P;
break;
case OMX_COLOR_FormatYUV420SemiPlanar:
hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP;
break;
case OMX_SEC_COLOR_FormatNV12TPhysicalAddress:
hal_format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED;
break;
case OMX_SEC_COLOR_FormatNV12Tiled:
hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
break;
case OMX_COLOR_Format32bitARGB8888:
hal_format = HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888;
break;
default:
hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P;
break;
}
return hal_format;
}
#ifdef __cplusplus
}
#endif