diff options
Diffstat (limited to 'domx/omx_proxy_component')
-rw-r--r-- | domx/omx_proxy_component/Android.mk | 202 | ||||
-rwxr-xr-x | domx/omx_proxy_component/Makefile | 89 | ||||
-rwxr-xr-x | domx/omx_proxy_component/omx_camera/src/omx_proxy_camera.c | 905 | ||||
-rwxr-xr-x | domx/omx_proxy_component/omx_h264_enc/Makefile | 103 | ||||
-rw-r--r-- | domx/omx_proxy_component/omx_h264_enc/src/omx_proxy_h264enc.c | 1097 | ||||
-rw-r--r-- | domx/omx_proxy_component/omx_mpeg4_enc/Makefile | 103 | ||||
-rw-r--r-- | domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c | 1050 | ||||
-rwxr-xr-x | domx/omx_proxy_component/omx_sample/Makefile | 103 | ||||
-rwxr-xr-x | domx/omx_proxy_component/omx_sample/src/omx_proxy_sample.c | 109 | ||||
-rwxr-xr-x | domx/omx_proxy_component/omx_video_dec/Makefile | 103 | ||||
-rwxr-xr-x | domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec.c | 797 | ||||
-rw-r--r-- | domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec_secure.c | 157 | ||||
-rwxr-xr-x | domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec_utils.c | 318 |
13 files changed, 5136 insertions, 0 deletions
diff --git a/domx/omx_proxy_component/Android.mk b/domx/omx_proxy_component/Android.mk new file mode 100644 index 0000000..722ccd0 --- /dev/null +++ b/domx/omx_proxy_component/Android.mk @@ -0,0 +1,202 @@ +LOCAL_PATH := $(call my-dir) + +# +# libOMX.TI.DUCATI1.VIDEO.DECODER +# + +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../omx_core/inc \ + $(LOCAL_PATH)/../mm_osal/inc \ + $(LOCAL_PATH)/../domx \ + $(LOCAL_PATH)/../domx/omx_rpc/inc \ + hardware/libhardware/include \ + $(DEVICE_FOLDER)/hwc/ + +LOCAL_SHARED_LIBRARIES := \ + libmm_osal \ + libc \ + libOMX_Core \ + liblog \ + libdomx \ + libhardware + +LOCAL_CFLAGS += -DLINUX -DTMS32060 -D_DB_TIOMAP -DSYSLINK_USE_SYSMGR -DSYSLINK_USE_LOADER +LOCAL_CFLAGS += -D_Android -DSET_STRIDE_PADDING_FROM_PROXY -DANDROID_QUIRK_CHANGE_PORT_VALUES -DUSE_ENHANCED_PORTRECONFIG +LOCAL_CFLAGS += -DANDROID_QUIRK_LOCK_BUFFER -DUSE_ION -DENABLE_GRALLOC_BUFFERS + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := omx_video_dec/src/omx_proxy_videodec.c omx_video_dec/src/omx_proxy_videodec_utils.c +LOCAL_MODULE := libOMX.TI.DUCATI1.VIDEO.DECODER +include $(BUILD_SHARED_LIBRARY) + +# +# libOMX.TI.DUCATI1.MISC.SAMPLE +# + +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../omx_core/inc \ + $(LOCAL_PATH)/../mm_osal/inc \ + $(LOCAL_PATH)/../domx \ + $(LOCAL_PATH)/../domx/omx_rpc/inc + +LOCAL_SHARED_LIBRARIES := \ + libmm_osal \ + libc \ + libOMX_Core \ + liblog \ + libdomx + +LOCAL_CFLAGS += -DTMS32060 -D_DB_TIOMAP -DSYSLINK_USE_SYSMGR -DSYSLINK_USE_LOADER +LOCAL_CFLAGS += -D_Android -DSET_STRIDE_PADDING_FROM_PROXY -DANDROID_QUIRK_CHANGE_PORT_VALUES -DUSE_ENHANCED_PORTRECONFIG +LOCAL_CFLAGS += -DANDROID_QUIRK_LOCK_BUFFER -DUSE_ION + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := omx_sample/src/omx_proxy_sample.c +LOCAL_MODULE := libOMX.TI.DUCATI1.MISC.SAMPLE +include $(BUILD_SHARED_LIBRARY) + + +# +# libOMX.TI.DUCATI1.VIDEO.CAMERA +# + +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../omx_core/inc \ + $(LOCAL_PATH)/../mm_osal/inc \ + $(LOCAL_PATH)/../domx \ + $(DEVICE_FOLDER)/libion_ti/ \ + $(LOCAL_PATH)/../domx/omx_rpc/inc + +LOCAL_SHARED_LIBRARIES := \ + libmm_osal \ + libc \ + libOMX_Core \ + liblog \ + libion_ti \ + libdomx + +LOCAL_CFLAGS += -DTMS32060 -D_DB_TIOMAP -DSYSLINK_USE_SYSMGR -DSYSLINK_USE_LOADER +LOCAL_CFLAGS += -D_Android -DSET_STRIDE_PADDING_FROM_PROXY -DANDROID_QUIRK_CHANGE_PORT_VALUES -DUSE_ENHANCED_PORTRECONFIG +LOCAL_CFLAGS += -DANDROID_QUIRK_LOCK_BUFFER -DUSE_ION + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := omx_camera/src/omx_proxy_camera.c +LOCAL_MODULE := libOMX.TI.DUCATI1.VIDEO.CAMERA +include $(BUILD_SHARED_LIBRARY) + +# +# libOMX.TI.DUCATI1.VIDEO.H264E +# + +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../omx_core/inc \ + $(LOCAL_PATH)/../mm_osal/inc \ + $(LOCAL_PATH)/../domx \ + $(LOCAL_PATH)/../domx/omx_rpc/inc \ + system/core/include/cutils \ + $(DEVICE_FOLDER)/hwc \ + $(DEVICE_FOLDER)/camera/inc \ + frameworks/base/include/media/stagefright \ + frameworks/native/include/media/hardware + +LOCAL_SHARED_LIBRARIES := \ + libmm_osal \ + libc \ + libOMX_Core \ + liblog \ + libdomx \ + libhardware \ + libcutils + + +LOCAL_CFLAGS += -DLINUX -DTMS32060 -D_DB_TIOMAP -DSYSLINK_USE_SYSMGR -DSYSLINK_USE_LOADER +LOCAL_CFLAGS += -D_Android -DSET_STRIDE_PADDING_FROM_PROXY -DANDROID_QUIRK_CHANGE_PORT_VALUES -DUSE_ENHANCED_PORTRECONFIG +LOCAL_CFLAGS += -DENABLE_GRALLOC_BUFFER -DANDROID_QUIRK_LOCK_BUFFER -DUSE_ION +LOCAL_CFLAGS += -DANDROID_CUSTOM_OPAQUECOLORFORMAT + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := omx_h264_enc/src/omx_proxy_h264enc.c +LOCAL_MODULE := libOMX.TI.DUCATI1.VIDEO.H264E +include $(BUILD_SHARED_LIBRARY) + +# +# libOMX.TI.DUCATI1.VIDEO.MPEG4E +# + +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../omx_core/inc \ + $(LOCAL_PATH)/../mm_osal/inc \ + $(LOCAL_PATH)/../domx \ + $(LOCAL_PATH)/../domx/omx_rpc/inc \ + system/core/include/cutils \ + $(DEVICE_FOLDER)/hwc \ + $(DEVICE_FOLDER)/camera/inc \ + frameworks/base/include/media/stagefright \ + frameworks/native/include/media/hardware + +LOCAL_SHARED_LIBRARIES := \ + libmm_osal \ + libc \ + libOMX_Core \ + liblog \ + libdomx \ + libhardware \ + libcutils + +LOCAL_CFLAGS += -DLINUX -DTMS32060 -D_DB_TIOMAP -DSYSLINK_USE_SYSMGR -DSYSLINK_USE_LOADER +LOCAL_CFLAGS += -D_Android -DSET_STRIDE_PADDING_FROM_PROXY -DANDROID_QUIRK_CHANGE_PORT_VALUES -DUSE_ENHANCED_PORTRECONFIG +LOCAL_CFLAGS += -DENABLE_GRALLOC_BUFFER -DANDROID_QUIRK_LOCK_BUFFER -DUSE_ION +LOCAL_CFLAGS += -DANDROID_CUSTOM_OPAQUECOLORFORMAT + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c +LOCAL_MODULE := libOMX.TI.DUCATI1.VIDEO.MPEG4E +include $(BUILD_SHARED_LIBRARY) + +# +# libOMX.TI.DUCATI1.VIDEO.DECODER.secure +# + +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../omx_core/inc \ + $(LOCAL_PATH)/../mm_osal/inc \ + $(LOCAL_PATH)/../domx \ + $(LOCAL_PATH)/../domx/omx_rpc/inc \ + hardware/libhardware/include \ + $(DEVICE_FOLDER)/hwc/ + +LOCAL_SHARED_LIBRARIES := \ + libmm_osal \ + libc \ + libOMX_Core \ + liblog \ + libdomx \ + libhardware \ + libOMX.TI.DUCATI1.VIDEO.DECODER + +LOCAL_CFLAGS += -DLINUX -DTMS32060 -D_DB_TIOMAP -DSYSLINK_USE_SYSMGR -DSYSLINK_USE_LOADER +LOCAL_CFLAGS += -D_Android -DSET_STRIDE_PADDING_FROM_PROXY -DANDROID_QUIRK_CHANGE_PORT_VALUES -DUSE_ENHANCED_PORTRECONFIG +LOCAL_CFLAGS += -DANDROID_QUIRK_LOCK_BUFFER -DUSE_ION -DENABLE_GRALLOC_BUFFERS + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := omx_video_dec/src/omx_proxy_videodec_secure.c +LOCAL_MODULE := libOMX.TI.DUCATI1.VIDEO.DECODER.secure +include $(BUILD_SHARED_LIBRARY) diff --git a/domx/omx_proxy_component/Makefile b/domx/omx_proxy_component/Makefile new file mode 100755 index 0000000..1ddc22b --- /dev/null +++ b/domx/omx_proxy_component/Makefile @@ -0,0 +1,89 @@ +# +# Copyright 2001-2008 Texas Instruments - http://www.ti.com/ +# +# 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. +# +# ---------------------------------------------------------------------------- +# Revision History +# +# +# SEP xx,2002 REF=ORG Swamy MC +# Original version. +# ---------------------------------------------------------------------------- + +#PROJROOT = $(ROOTDIR)/src + +include $(PROJROOT)/make/start.mk + +# Do not change above "include" line(s) + +# Arguments to tools, will move to make system once finalized. + +CFLAGS = +CDEFS = DEBUG + +EXEC_ARGS = +ST_LIB_ARGS = +SH_LIB_ARGS = + +# Define this macro if target runs in kernel mode +#__KERNEL__ = 1 + +# Target name and extension +# static library (ST_LIB): filename.a +# shared library soname (SH_LIB): filename.so.maj_ver.min_ver +# executable (EXEC) : filename.out + +TARGETNAME = + + +# TARGETTYPE must be EXEC, ST_LIB or SH_LIB in upper case. +#TARGETTYPE = ST_LIB +TARGETTYPE = + +# For shared object library, soname is filename.so.maj_ver +SH_SONAME = + +# Folders in which gmake will run before building current target + +SUBMODULES = \ +omx_sample \ +omx_video_dec \ +omx_h264_enc \ +omx_mpeg4_enc \ + +#video/omx_proxy_component/test + +# Filename must not begin with '.', '/' or '\' + +SOURCES = + +# Search path for include files + +INCLUDES = + +# Libraries needed for linking. + +ST_LIBS = +SH_LIBS = + +# Search path for library (and linker command) files. +# Current folder and target folder are included by default. + +LIBINCLUDES = + + +# Do not change below "include" line(s) + +include $(PROJROOT)/make/build.mk + diff --git a/domx/omx_proxy_component/omx_camera/src/omx_proxy_camera.c b/domx/omx_proxy_component/omx_camera/src/omx_proxy_camera.c new file mode 100755 index 0000000..ce0af09 --- /dev/null +++ b/domx/omx_proxy_component/omx_camera/src/omx_proxy_camera.c @@ -0,0 +1,905 @@ +/* + * Copyright (c) 2010, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file omx_proxy_camera.c + * This file contains methods that provides the functionality for + * the OpenMAX1.1 DOMX Framework Tunnel Proxy component. + ****************************************************************************** + This is the proxy specific wrapper that passes the component name to the + generic proxy init() The proxy wrapper also does some runtime/static time + config on per proxy basis This is a thin wrapper that is called when + componentiit() of the proxy is called static OMX_ERRORTYPE PROXY_Wrapper_init + (OMX_HANDLETYPE hComponent, OMX_PTR pAppData); + this layer gets called first whenever a proxy s get handle is called + ****************************************************************************** + * @path WTSD_DucatiMMSW\omx\omx_il_1_x\omx_proxy_component\src + * + * @rev 1.0 + */ + +/*============================================================== + *! Revision History + *! ============================ + *! 19-August-2009 B Ravi Kiran ravi.kiran@ti.com: Initial Version + *================================================================*/ + +/****************************************************************** + * INCLUDE FILES + ******************************************************************/ +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <dirent.h> +#include <stdio.h> +#include <string.h> +#include <pthread.h> +#include <sys/time.h> +#include <stdlib.h> +#include <errno.h> + +#include <timm_osal_interfaces.h> +#include <OMX_TI_IVCommon.h> +#include <OMX_TI_Index.h> +#include "omx_proxy_common.h" +#include "timm_osal_mutex.h" + +#ifdef USE_ION +#include <unistd.h> +#include <ion_ti/ion.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/eventfd.h> +#include <fcntl.h> +#include <errno.h> +#endif + +#define COMPONENT_NAME "OMX.TI.DUCATI1.VIDEO.CAMERA" +/*Needs to be specific for every configuration wrapper*/ + +#undef LOG_TAG +#define LOG_TAG "CameraHAL" + +#define DEFAULT_DCC 1 + +#define LINUX_PAGE_SIZE (4 * 1024) + +#define _PROXY_OMX_INIT_PARAM(param,type) do { \ + TIMM_OSAL_Memset((param), 0, sizeof (type)); \ + (param)->nSize = sizeof (type); \ + (param)->nVersion.s.nVersionMajor = 1; \ + (param)->nVersion.s.nVersionMinor = 1; \ + } while(0) + +/* VTC specific changes */ +#define MAX_NUM_INTERNAL_BUFFERS 4 +#define MAX_VTC_WIDTH 1920 +#define MAX_VTC_HEIGHT 1080 +#define BORDER_WIDTH 32 +#define BORDER_HEIGHT 32 +#define MAX_VTC_WIDTH_WITH_VNF (MAX_VTC_WIDTH + BORDER_WIDTH) +#define MAX_VTC_HEIGHT_WITH_VNF (MAX_VTC_HEIGHT + BORDER_HEIGHT) +#ifndef OMAP_TUNA +OMX_PTR gCamIonHdl[MAX_NUM_INTERNAL_BUFFERS][2]; +#endif + +/* Tiler heap resservation specific */ +#define OMAP_ION_HEAP_TILER_ALLOCATION_MASK (1<<4) +/* store handles for tracking and freeing */ +OMX_PTR gComponentBufferAllocation[PROXY_MAXNUMOFPORTS][MAX_NUM_INTERNAL_BUFFERS]; + +/* Incase of multiple instance, making sure DCC is initialized only for + first instance */ +static OMX_S16 numofInstance = 0; +int dcc_flag = 0; +TIMM_OSAL_PTR cam_mutex = NULL; + +/* To store DCC buffer size */ +OMX_S32 dccbuf_size = 0; + +/* Ducati Mapped Addr */ +OMX_PTR DCC_Buff = NULL; + +#ifdef USE_ION +OMX_PTR DCC_Buff_ptr = NULL; +int ion_fd; +int mmap_fd; +#endif + +OMX_S32 read_DCCdir(OMX_PTR, OMX_STRING *, OMX_U16); +OMX_ERRORTYPE DCC_Init(OMX_HANDLETYPE); +OMX_ERRORTYPE send_DCCBufPtr(OMX_HANDLETYPE hComponent); +void DCC_DeInit(); +OMX_ERRORTYPE PROXY_ComponentDeInit(OMX_HANDLETYPE); +OMX_ERRORTYPE __PROXY_SetConfig(OMX_HANDLETYPE, OMX_INDEXTYPE, + OMX_PTR, OMX_PTR); +OMX_ERRORTYPE __PROXY_GetConfig(OMX_HANDLETYPE, OMX_INDEXTYPE, + OMX_PTR, OMX_PTR); +OMX_ERRORTYPE __PROXY_SetParameter(OMX_IN OMX_HANDLETYPE, OMX_INDEXTYPE, + OMX_PTR, OMX_PTR, OMX_U32); +OMX_ERRORTYPE __PROXY_GetParameter(OMX_IN OMX_HANDLETYPE, OMX_INDEXTYPE, + OMX_PTR, OMX_PTR); +OMX_ERRORTYPE PROXY_SendCommand(OMX_HANDLETYPE, OMX_COMMANDTYPE, + OMX_U32,OMX_PTR); +OMX_ERRORTYPE CameraMaptoTilerDuc(OMX_TI_CONFIG_SHAREDBUFFER *, OMX_PTR *); +//COREID TARGET_CORE_ID = CORE_APPM3; + +static OMX_ERRORTYPE ComponentPrivateDeInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + TIMM_OSAL_ERRORTYPE eOsalError = TIMM_OSAL_ERR_NONE; + PROXY_COMPONENT_PRIVATE *pCompPrv; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_U32 i, j; + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + if (dcc_flag) + { + eOsalError = + TIMM_OSAL_MutexObtain(cam_mutex, TIMM_OSAL_SUSPEND); + if (eOsalError != TIMM_OSAL_ERR_NONE) + { + TIMM_OSAL_Error("Mutex Obtain failed"); + } + + numofInstance = numofInstance - 1; + + eOsalError = TIMM_OSAL_MutexRelease(cam_mutex); + PROXY_assert(eOsalError == TIMM_OSAL_ERR_NONE, + OMX_ErrorInsufficientResources, "Mutex release failed"); + } +#ifndef OMAP_TUNA + for(i=0; i < MAX_NUM_INTERNAL_BUFFERS; i++) { + if (gCamIonHdl[i][0] != NULL) { + ion_free(pCompPrv->ion_fd, gCamIonHdl[i][0]); + gCamIonHdl[i][0] = NULL; + } + if (gCamIonHdl[i][1] != NULL) { + ion_free(pCompPrv->ion_fd, gCamIonHdl[i][1]); + gCamIonHdl[i][1] = NULL; + } + } +#endif + + for (i = 0; i < PROXY_MAXNUMOFPORTS; i++) { + for (j = 0; j < MAX_NUM_INTERNAL_BUFFERS; j++) { + if (gComponentBufferAllocation[i][j]) { + ion_free(pCompPrv->ion_fd, gComponentBufferAllocation[i][j]); + } + gComponentBufferAllocation[i][j] = NULL; + } + } + + eError = PROXY_ComponentDeInit(hComponent); + + EXIT: + return eError; +} + +static OMX_ERRORTYPE Camera_SendCommand(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE eCmd, + OMX_IN OMX_U32 nParam, OMX_IN OMX_PTR pCmdData) + +{ + OMX_ERRORTYPE eError = OMX_ErrorNone, eCompReturn; + RPC_OMX_ERRORTYPE eRPCError = RPC_OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + static OMX_BOOL dcc_loaded = OMX_FALSE; + + OMX_ERRORTYPE dcc_eError = OMX_ErrorNone; + TIMM_OSAL_ERRORTYPE eOsalError = TIMM_OSAL_ERR_NONE; + OMX_U32 i; + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + if ((eCmd == OMX_CommandStateSet) && + (nParam == (OMX_STATETYPE) OMX_StateIdle)) + { + if (!dcc_loaded) + { + dcc_eError = DCC_Init(hComponent); + if (dcc_eError != OMX_ErrorNone) + { + DOMX_ERROR(" Error in DCC Init"); + } + /* Configure Ducati to use DCC buffer from A9 side + *ONLY* if DCC_Init is successful. */ + if (dcc_eError == OMX_ErrorNone) + { + dcc_eError = send_DCCBufPtr(hComponent); + if (dcc_eError != OMX_ErrorNone) + { + DOMX_ERROR(" Error in Sending DCC Buf ptr"); + } + DCC_DeInit(); + } + dcc_loaded = OMX_TRUE; + } + } else if (eCmd == OMX_CommandPortDisable) { + int i, j; + for (i = 0; i < MAX_NUM_INTERNAL_BUFFERS; i++) { + for (j = 0; j < PROXY_MAXNUMOFPORTS; j++) { + if (((j == nParam) || (nParam == OMX_ALL)) && + gComponentBufferAllocation[i][j]) + { + ion_free(pCompPrv->ion_fd, gComponentBufferAllocation[i][j]); + gComponentBufferAllocation[i][j] = NULL; + } + } + } + + } + + + eError = + PROXY_SendCommand(hComponent,eCmd,nParam,pCmdData); + + +EXIT: + + DOMX_EXIT("eError: %d", eError); + return eError; + +} + +/* ===========================================================================*/ +/** + * @name CameraGetConfig() + * @brief For some specific indices, buffer allocated on A9 side + * needs to be mapped and sent to Ducati. + * @param + * @return OMX_ErrorNone = Successful + */ +/* ===========================================================================*/ + +static OMX_ERRORTYPE CameraGetConfig(OMX_IN OMX_HANDLETYPE + hComponent, OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_TI_CONFIG_SHAREDBUFFER *pConfigSharedBuffer = NULL; + OMX_PTR pTempSharedBuff = NULL; + OMX_U32 status = 0; + + switch (nParamIndex) + { + case OMX_TI_IndexConfigAAAskipBuffer: + case OMX_TI_IndexConfigCamCapabilities: + case OMX_TI_IndexConfigExifTags: + case OMX_TI_IndexConfigAlgoAreas: + pConfigSharedBuffer = + (OMX_TI_CONFIG_SHAREDBUFFER *) pComponentParameterStructure; + + pTempSharedBuff = pConfigSharedBuffer->pSharedBuff; + + // TODO(XXX): Cache API is not yet available. Client needs to + // allocate tiler buffer directly and assign to pSharedBuff. + // Ptr allocated by MemMgr_Alloc in uncacheable so there + // would be no need to cache API + + eError = __PROXY_GetConfig(hComponent, + nParamIndex, + pConfigSharedBuffer, + &(pConfigSharedBuffer->pSharedBuff)); + + PROXY_assert((eError == OMX_ErrorNone), eError, + "Error in GetConfig"); + + pConfigSharedBuffer->pSharedBuff = pTempSharedBuff; + + goto EXIT; + break; + default: + break; + } + + return __PROXY_GetConfig(hComponent, + nParamIndex, + pComponentParameterStructure, + NULL); + + EXIT: + return eError; +} + +/* ===========================================================================*/ +/** + * @name CameraSetConfig() + * @brief For some specific indices, buffer allocated on A9 side needs to + * be mapped and sent to Ducati. + * @param + * @return OMX_ErrorNone = Successful + */ +/* ===========================================================================*/ + + +static OMX_ERRORTYPE CameraSetConfig(OMX_IN OMX_HANDLETYPE + hComponent, OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_TI_CONFIG_SHAREDBUFFER *pConfigSharedBuffer = NULL; + OMX_PTR pTempSharedBuff = NULL; + OMX_U32 status = 0; + + switch (nParamIndex) + { + case OMX_TI_IndexConfigAAAskipBuffer: + case OMX_TI_IndexConfigCamCapabilities: + case OMX_TI_IndexConfigExifTags: + case OMX_TI_IndexConfigAlgoAreas: + pConfigSharedBuffer = + (OMX_TI_CONFIG_SHAREDBUFFER *) + pComponentParameterStructure; + + pTempSharedBuff = pConfigSharedBuffer->pSharedBuff; + + // TODO(XXX): Cache API is not yet available. Client needs to + // allocate tiler buffer directly and assign to pSharedBuff. + // Ptr allocated by MemMgr_Alloc in uncacheable so there + // would be no need to cache API + + eError = __PROXY_SetConfig(hComponent, + nParamIndex, + pConfigSharedBuffer, + &(pConfigSharedBuffer->pSharedBuff)); + + PROXY_assert((eError == OMX_ErrorNone), eError, + "Error in GetConfig"); + + pConfigSharedBuffer->pSharedBuff = pTempSharedBuff; + + goto EXIT; + break; + default: + break; + } + + return __PROXY_SetConfig(hComponent, + nParamIndex, + pComponentParameterStructure, + NULL); + + EXIT: + return eError; +} + +static OMX_ERRORTYPE CameraSetParam(OMX_IN OMX_HANDLETYPE + hComponent, OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + struct ion_handle *handle; + OMX_U32 i =0; + OMX_S32 ret = 0; + PROXY_COMPONENT_PRIVATE *pCompPrv; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *)hComponent; + OMX_U32 stride_Y = 0, stride_UV = 0; +#ifndef OMAP_TUNA + OMX_TI_PARAM_VTCSLICE *pVtcConfig;// = (OMX_TI_PARAM_VTCSLICE *)pComponentParameterStructure; + OMX_TI_PARAM_COMPONENTBUFALLOCTYPE *bufferalloc = NULL; +#endif + int size = 0; + int fd1 = -1, fd2 = -1; + + pCompPrv = (PROXY_COMPONENT_PRIVATE *)hComp->pComponentPrivate; + //fprintf(stdout, "DOMX: CameraSetParam: called!!!\n"); + switch (nParamIndex) + { +#ifndef OMAP_TUNA + case OMX_TI_IndexParamVtcSlice: + pVtcConfig = (OMX_TI_PARAM_VTCSLICE *)pComponentParameterStructure; + fprintf(stdout, "DOMX: CameraSetParam: OMX_TI_IndexParamVtcSlice is called!!!\n"); + DOMX_ERROR("CameraSetParam Called for Vtc Slice index\n"); + + //fprintf(stdout, "CameraSetParam Called for Vtc Slice height = %d\n", ((OMX_TI_PARAM_VTCSLICE *)pComponentParameterStructure)->nSliceHeight); + // MAX_NUM_INTERNAL_BUFFERS; + + for(i=0; i < MAX_NUM_INTERNAL_BUFFERS; i++) { + pVtcConfig->nInternalBuffers = i; + ret = ion_alloc_tiler(pCompPrv->ion_fd, MAX_VTC_WIDTH_WITH_VNF, MAX_VTC_HEIGHT_WITH_VNF, TILER_PIXEL_FMT_8BIT, OMAP_ION_HEAP_TILER_MASK, &handle, (size_t *)&stride_Y); + if (ret < 0) { + DOMX_ERROR ("ION allocation failed - %s", strerror(errno)); + goto EXIT; + } + + ret = ion_share(pCompPrv->ion_fd, handle, &fd1); + if (ret < 0) { + DOMX_ERROR("ION share failed"); + ion_free(pCompPrv->ion_fd, handle); + goto EXIT; + } + + pVtcConfig->IonBufhdl[0] = (OMX_PTR)(fd1); + + //fprintf(stdout, "DOMX: ION Buffer#%d: Y: 0x%x\n", i, pVtcConfig->IonBufhdl[0]); + + ret = ion_alloc_tiler(pCompPrv->ion_fd, MAX_VTC_WIDTH_WITH_VNF/2, MAX_VTC_HEIGHT_WITH_VNF/2, TILER_PIXEL_FMT_16BIT, OMAP_ION_HEAP_TILER_MASK, &handle, (size_t *)&stride_UV); + if (ret < 0) { + DOMX_ERROR ("ION allocation failed - %s", strerror(errno)); + goto EXIT; + } + + ret = ion_share(pCompPrv->ion_fd, handle, &fd2); + if (ret < 0) { + DOMX_ERROR("ION share failed"); + ion_free(pCompPrv->ion_fd, handle); + goto EXIT; + } + + pVtcConfig->IonBufhdl[1] = (OMX_PTR)(fd2); + gCamIonHdl[i][0] = pVtcConfig->IonBufhdl[0]; + gCamIonHdl[i][1] = pVtcConfig->IonBufhdl[1]; + //fprintf(stdout, "DOMX: ION Buffer#%d: UV: 0x%x\n", i, pVtcConfig->IonBufhdl[1]); + eError = __PROXY_SetParameter(hComponent, + OMX_TI_IndexParamVtcSlice, + pVtcConfig, + pVtcConfig->IonBufhdl, 2); + close(fd1); + close(fd2); + } + goto EXIT; + case OMX_TI_IndexParamComponentBufferAllocation: { + OMX_U32 port = 0, index = 0; + int fd; + bufferalloc = (OMX_TI_PARAM_COMPONENTBUFALLOCTYPE *) + pComponentParameterStructure; + + port = bufferalloc->nPortIndex; + index = bufferalloc->nIndex; + + size = bufferalloc->nAllocWidth * bufferalloc->nAllocLines; + ret = ion_alloc_tiler (pCompPrv->ion_fd, size, 1, + TILER_PIXEL_FMT_PAGE, + OMAP_ION_HEAP_TILER_ALLOCATION_MASK, + &handle, &stride_Y); + if (ret < 0) { + DOMX_ERROR ("ION allocation failed - %s", strerror(errno)); + goto EXIT; + } + + ret = ion_share(pCompPrv->ion_fd, handle, &fd); + if (ret < 0) { + DOMX_ERROR("ION share failed"); + ion_free(pCompPrv->ion_fd, handle); + goto EXIT; + } + + bufferalloc->pBuf[0] = fd; + eError = __PROXY_SetParameter(hComponent, + OMX_TI_IndexParamComponentBufferAllocation, + bufferalloc, &bufferalloc->pBuf[0], 1); + if (eError != OMX_ErrorNone) { + ion_free(pCompPrv->ion_fd, handle); + } else { + if (gComponentBufferAllocation[port][index]) { + ion_free(pCompPrv->ion_fd, gComponentBufferAllocation[port][index]); + } + gComponentBufferAllocation[port][index] = handle; + } + close (fd); + } + goto EXIT; + break; +#endif + default: + break; + } + eError = __PROXY_SetParameter(hComponent, + nParamIndex, + pComponentParameterStructure, + NULL, 0); + + if (eError != OMX_ErrorNone) { + DOMX_ERROR(" CameraSetParam: Error in SetParam 0x%x", eError); + } +EXIT: + return eError; +} +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_ERRORTYPE dcc_eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *pHandle = NULL; + PROXY_COMPONENT_PRIVATE *pComponentPrivate; + OMX_U32 i = 0, j = 0; + pHandle = (OMX_COMPONENTTYPE *) hComponent; + TIMM_OSAL_ERRORTYPE eOsalError = TIMM_OSAL_ERR_NONE; + DOMX_ENTER("_____________________INSIDE CAMERA PROXY" + "WRAPPER__________________________\n"); + pHandle->pComponentPrivate = (PROXY_COMPONENT_PRIVATE *) + TIMM_OSAL_Malloc(sizeof(PROXY_COMPONENT_PRIVATE), + TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT); + + pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate; + if (pHandle->pComponentPrivate == NULL) + { + DOMX_ERROR(" ERROR IN ALLOCATING PROXY COMPONENT" + "PRIVATE STRUCTURE"); + eError = OMX_ErrorInsufficientResources; + goto EXIT; + } + TIMM_OSAL_Memset(pComponentPrivate, 0, + sizeof(PROXY_COMPONENT_PRIVATE)); + + pComponentPrivate->cCompName = + TIMM_OSAL_Malloc(MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8), + TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT); + /*Copying component Name - this will be picked up in the proxy common */ + assert(strlen(COMPONENT_NAME) + 1 < MAX_COMPONENT_NAME_LENGTH); + TIMM_OSAL_Memcpy(pComponentPrivate->cCompName, COMPONENT_NAME, + strlen(COMPONENT_NAME) + 1); + + /*Calling Proxy Common Init() */ + eError = OMX_ProxyCommonInit(hComponent); + if (eError != OMX_ErrorNone) + { + DOMX_ERROR("\Error in Initializing Proxy"); + TIMM_OSAL_Free(pComponentPrivate->cCompName); + TIMM_OSAL_Free(pComponentPrivate); + goto EXIT; + } +#ifndef OMAP_TUNA + for(i=0; i < MAX_NUM_INTERNAL_BUFFERS; i++) { + gCamIonHdl[i][0] = NULL; + gCamIonHdl[i][1] = NULL; + } +#endif + + for (i = 0; i < PROXY_MAXNUMOFPORTS; i++) { + for (j = 0; j < MAX_NUM_INTERNAL_BUFFERS; j++) { + gComponentBufferAllocation[i][j] = NULL; + } + } + + pHandle->ComponentDeInit = ComponentPrivateDeInit; + pHandle->GetConfig = CameraGetConfig; + pHandle->SetConfig = CameraSetConfig; + pHandle->SendCommand = Camera_SendCommand; + pHandle->SetParameter = CameraSetParam; + + EXIT: + return eError; +} + +/* ===========================================================================*/ +/** + * @name DCC_Init() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE DCC_Init(OMX_HANDLETYPE hComponent) +{ + OMX_TI_PARAM_DCCURIINFO param; + OMX_PTR ptempbuf; + OMX_U16 nIndex = 0; + OMX_ERRORTYPE eError = OMX_ErrorNone; +#ifdef USE_ION + int ret; + size_t stride; +#endif + + OMX_S32 status = 0; + OMX_STRING dcc_dir[200]; + OMX_U16 i; + _PROXY_OMX_INIT_PARAM(¶m, OMX_TI_PARAM_DCCURIINFO); + + DOMX_ENTER("ENTER"); + /* Read the the DCC URI info */ + for (nIndex = 0; eError != OMX_ErrorNoMore; nIndex++) + { + param.nIndex = nIndex; + eError = + OMX_GetParameter(hComponent, + OMX_TI_IndexParamDccUriInfo, ¶m); + + PROXY_assert((eError == OMX_ErrorNone) || + (eError == OMX_ErrorNoMore), eError, + "Error in GetParam for Dcc URI info"); + + if (eError == OMX_ErrorNone) + { + DOMX_DEBUG("DCC URI's %s ", param.sDCCURI); + dcc_dir[nIndex] = + TIMM_OSAL_Malloc(sizeof(OMX_U8) * + (strlen(DCC_PATH) + MAX_URI_LENGTH + 1), + TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT); + PROXY_assert(dcc_dir[nIndex] != NULL, + OMX_ErrorInsufficientResources, "Malloc failed"); + strcpy(dcc_dir[nIndex], DCC_PATH); + strncat(dcc_dir[nIndex], (OMX_STRING) param.sDCCURI, MAX_URI_LENGTH); + strcat(dcc_dir[nIndex], "/"); + } + } + + /* setting back errortype OMX_ErrorNone */ + if (eError == OMX_ErrorNoMore) + { + eError = OMX_ErrorNone; + } + + dccbuf_size = read_DCCdir(NULL, dcc_dir, nIndex); + + if(dccbuf_size <= 0) + { + DOMX_DEBUG("No DCC files found, switching back to default DCC"); + return OMX_ErrorInsufficientResources; + } + +#ifdef USE_ION + ion_fd = ion_open(); + if(ion_fd == 0) + { + DOMX_ERROR("ion_open failed!!!"); + return OMX_ErrorInsufficientResources; + } + dccbuf_size = (dccbuf_size + LINUX_PAGE_SIZE -1) & ~(LINUX_PAGE_SIZE - 1); + ret = ion_alloc(ion_fd, dccbuf_size, 0x1000, 1 << ION_HEAP_TYPE_CARVEOUT, + (struct ion_handle **)&DCC_Buff); + + if (ret || ((int)DCC_Buff == -ENOMEM)) { + ret = ion_alloc_tiler(ion_fd, dccbuf_size, 1, TILER_PIXEL_FMT_PAGE, + OMAP_ION_HEAP_TILER_MASK, &DCC_Buff, &stride); + } + + if (ret || ((int)DCC_Buff == -ENOMEM)) { + DOMX_ERROR("FAILED to allocate DCC buffer of size=%d. ret=0x%x", + dccbuf_size, ret); + return OMX_ErrorInsufficientResources; + } + + if (ion_map(ion_fd, DCC_Buff, dccbuf_size, PROT_READ | PROT_WRITE, MAP_SHARED, 0, + (unsigned char **)&DCC_Buff_ptr, &mmap_fd) < 0) + { + DOMX_ERROR("userspace mapping of ION buffers returned error"); + return OMX_ErrorInsufficientResources; + } + ptempbuf = DCC_Buff_ptr; +#endif + dccbuf_size = read_DCCdir(ptempbuf, dcc_dir, nIndex); + + PROXY_assert(dccbuf_size > 0, OMX_ErrorInsufficientResources, + "ERROR in copy DCC files into buffer"); + + EXIT: + for (i = 0; i < nIndex - 1; i++) + { + TIMM_OSAL_Free(dcc_dir[i]); + } + + return eError; + +} + +/* ===========================================================================*/ +/** + * @name send_DCCBufPtr() + * @brief : Sending the DCC uri buff addr to ducati + * @param void + * @return return = 0 is successful + * @sa TBD + * + */ +/* ===========================================================================*/ + +OMX_ERRORTYPE send_DCCBufPtr(OMX_HANDLETYPE hComponent) +{ + OMX_TI_CONFIG_SHAREDBUFFER uribufparam; + OMX_ERRORTYPE eError = OMX_ErrorNone; + + _PROXY_OMX_INIT_PARAM(&uribufparam, OMX_TI_CONFIG_SHAREDBUFFER); + uribufparam.nPortIndex = OMX_ALL; + + DOMX_ENTER("ENTER"); + + uribufparam.nSharedBuffSize = dccbuf_size; +#ifdef USE_ION + uribufparam.pSharedBuff = (OMX_PTR) mmap_fd; +#else + uribufparam.pSharedBuff = (OMX_PTR) DCC_Buff; +#endif + + DOMX_DEBUG("SYSLINK MAPPED ADDR: 0x%x sizeof buffer %d", + uribufparam.pSharedBuff, uribufparam.nSharedBuffSize); + + eError = __PROXY_SetParameter(hComponent, + OMX_TI_IndexParamDccUriBuffer, + &uribufparam, + &(uribufparam.pSharedBuff), 1); + + if (eError != OMX_ErrorNone) { + DOMX_ERROR(" Error in SetParam for DCC Uri Buffer 0x%x", eError); + } + + DOMX_EXIT("EXIT"); + return eError; +} + +/* ===========================================================================*/ +/** + * @name read_DCCdir() + * @brief : copies all the dcc profiles into the allocated 1D-Tiler buffer + * and returns the size of the buffer. + * @param void : OMX_PTR is null then returns the size of the DCC directory + * @return return = size of the DCC directory or error in case of any failures + * in file read or open + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_S32 read_DCCdir(OMX_PTR buffer, OMX_STRING * dir_path, OMX_U16 numofURI) +{ + FILE *pFile; + OMX_S32 lSize; + OMX_S32 dcc_buf_size = 0; + size_t result; + OMX_STRING filename; + char temp[200]; + OMX_STRING dotdot = ".."; + DIR *d; + struct dirent *dir; + OMX_U16 i = 0; + OMX_S32 ret = 0; + + DOMX_ENTER("ENTER"); + for (i = 0; i < numofURI - 1; i++) + { + d = opendir(dir_path[i]); + if (d) + { + /* read each filename */ + while ((dir = readdir(d)) != NULL) + { + filename = dir->d_name; + strcpy(temp, dir_path[i]); + strcat(temp, filename); + if ((*filename != *dotdot)) + { + DOMX_DEBUG + ("\n\t DCC Profiles copying into buffer => %s mpu_addr: %p", + temp, buffer); + pFile = fopen(temp, "rb"); + if (pFile == NULL) + { + DOMX_ERROR("File open error"); + ret = -1; + } else + { + fseek(pFile, 0, SEEK_END); + lSize = ftell(pFile); + rewind(pFile); + /* buffer is not NULL then copy all the DCC profiles into buffer + else return the size of the DCC directory */ + if (buffer) + { + // copy file into the buffer: + result = + fread(buffer, 1, + lSize, pFile); + if (result != (size_t) lSize) + { + DOMX_ERROR + ("fread: Reading error"); + ret = -1; + } + buffer = + buffer + lSize; + } + /* getting the size of the total dcc files available in FS */ + dcc_buf_size = + dcc_buf_size + lSize; + // terminate + fclose(pFile); + } + } + } + closedir(d); + } + } + if (ret == 0) + ret = dcc_buf_size; + + DOMX_EXIT("return %d", ret); + return ret; +} + +/* ===========================================================================*/ +/** + * @name DCC_Deinit() + * @brief + * @param void + * @return void + * @sa TBD + * + */ +/* ===========================================================================*/ +void DCC_DeInit() +{ + DOMX_ENTER("ENTER"); + + if (DCC_Buff) + { +#ifdef USE_ION + munmap(DCC_Buff_ptr, dccbuf_size); + close(mmap_fd); + ion_free(ion_fd, DCC_Buff); + ion_close(ion_fd); + DCC_Buff = NULL; +#endif + } + + DOMX_EXIT("EXIT"); +} + + + +/*===============================================================*/ +/** @fn Cam_Setup : This function is called when the the OMX Camera library is + * loaded. It creates a mutex, which is used during DCC_Init() + */ +/*===============================================================*/ +void __attribute__ ((constructor)) Cam_Setup(void) +{ + TIMM_OSAL_ERRORTYPE eError = TIMM_OSAL_ERR_NONE; + + eError = TIMM_OSAL_MutexCreate(&cam_mutex); + if (eError != TIMM_OSAL_ERR_NONE) + { + TIMM_OSAL_Error("Creation of default mutex failed"); + } +} + + +/*===============================================================*/ +/** @fn Cam_Destroy : This function is called when the the OMX Camera library is + * unloaded. It destroys the mutex which was created by + * Core_Setup(). + * + */ +/*===============================================================*/ +void __attribute__ ((destructor)) Cam_Destroy(void) +{ + TIMM_OSAL_ERRORTYPE eError = TIMM_OSAL_ERR_NONE; + + eError = TIMM_OSAL_MutexDelete(cam_mutex); + if (eError != TIMM_OSAL_ERR_NONE) + { + TIMM_OSAL_Error("Destruction of default mutex failed"); + } +} diff --git a/domx/omx_proxy_component/omx_h264_enc/Makefile b/domx/omx_proxy_component/omx_h264_enc/Makefile new file mode 100755 index 0000000..c528740 --- /dev/null +++ b/domx/omx_proxy_component/omx_h264_enc/Makefile @@ -0,0 +1,103 @@ +# +# Copyright (C) Texas Instruments - http://www.ti.com/ +# +# 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. +# +# ---------------------------------------------------------------------------- +# Revision History +# +# +# REF=ORG +# Original version. +# ---------------------------------------------------------------------------- + + + +include $(PROJROOT)/make/start.mk + +# Do not change above "include" line(s) + +# Arguments to tools, will move to make system once finalized. + +CFLAGS = +CDEFS = +ifeq ($(BUILD),udeb) +CDEFS += DEBUG +endif +CDEFS += + +EXEC_ARGS = +ST_LIB_ARGS = +SH_LIB_ARGS = + +# Define this macro if target runs in kernel mode +#__KERNEL__ = 1 + +# Target name and extension +# static library (ST_LIB): filename.a +# shared library soname (SH_LIB): filename.so.maj_ver.min_ver +# executable (EXEC) : filename.out + +TARGETNAME = libOMX.TI.DUCATI1.VIDEO.H264E.so + + +# TARGETTYPE must be EXEC, ST_LIB or SH_LIB in upper case. + +TARGETTYPE = SH_LIB + +# install directory relative to the HOSTTARGET directory +HOSTRELEASE = lib + +# install directory relative to the root filesystem +ROOTFSRELEASE = lib + +# Folders in which gmake will run before building current target + +SUBMODULES = \ + +# Filename must not begin with '.', '/' or '\' + +SOURCES = \ +src/omx_proxy_h264enc.c \ + + + +# Search path for include files + +INCLUDES = \ + $(PROJROOT)/omx_core/inc \ + $(PROJROOT)/mm_osal/inc \ + $(PROJROOT)/domx \ + $(PROJROOT)/domx/omx_rpc/inc \ + + +# Libraries needed for linking. + +ST_LIBS = +#mm_osal domx +SH_LIBS = domx omx_core mm_osal +#pthread rt utils procmgr ipc rcm notify +#SH_LIBS += sysmgr sysmemmgr + + +# Search path for library (and linker command) files. +# Current folder and target folder are included by default. + +LIBINCLUDES = $(PROJROOT)/mm_osal \ + $(PROJROOT)/domx \ + $(PROJROOT)/omx_core + + +# Do not change below "include" line(s) + +include $(PROJROOT)/make/build.mk diff --git a/domx/omx_proxy_component/omx_h264_enc/src/omx_proxy_h264enc.c b/domx/omx_proxy_component/omx_h264_enc/src/omx_proxy_h264enc.c new file mode 100644 index 0000000..7a20bcb --- /dev/null +++ b/domx/omx_proxy_component/omx_h264_enc/src/omx_proxy_h264enc.c @@ -0,0 +1,1097 @@ +/* + * Copyright (c) 2010, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file omx_proxy_h264enc.c + * This file contains methods that provides the functionality for + * the OpenMAX1.1 DOMX Framework Proxy component. + ********************************************************************************************* + This is the proxy specific wrapper that passes the component name to the generic proxy init() + The proxy wrapper also does some runtime/static time onfig on per proxy basis + This is a thin wrapper that is called when componentiit() of the proxy is called + static OMX_ERRORTYPE PROXY_Wrapper_init(OMX_HANDLETYPE hComponent, OMX_PTR pAppData); + this layer gets called first whenever a proxy's get handle is called + ************************************************************************************************ + * @path WTSD_DucatiMMSW\omx\omx_il_1_x\omx_proxy_component\src + * + * @rev 1.0 + */ + +/*============================================================== + *! Revision History + *! ============================ + * 26-August-2011 Abhishek Ranka : Support for color conv at encoder + * input port + * + *! 20-August-2010 Sarthak Aggarwal sarthak@ti.com: Initial Version + *================================================================*/ + +/****************************************************************** + * INCLUDE FILES + ******************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include "omx_proxy_common.h" +#include <timm_osal_interfaces.h> +#include "OMX_TI_IVCommon.h" +#include "OMX_TI_Video.h" +#include "OMX_TI_Index.h" + +#include <MetadataBufferType.h> +#ifdef ENABLE_GRALLOC_BUFFER +#include "native_handle.h" +#include <hal_public.h> +#include <VideoMetadata.h> +#endif + +#include <stdlib.h> +#include <cutils/properties.h> + +#define COMPONENT_NAME "OMX.TI.DUCATI1.VIDEO.H264E" +/* needs to be specific for every configuration wrapper */ + +#define OMX_H264E_INPUT_PORT 0 +#define LINUX_PAGE_SIZE 4096 + +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES + +OMX_ERRORTYPE LOCAL_PROXY_H264E_GetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct); + +OMX_ERRORTYPE LOCAL_PROXY_H264E_SetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct); + +#endif + + +#define OMX_INIT_STRUCT(_s_, _name_) \ + memset(&(_s_), 0x0, sizeof(_name_)); \ + (_s_).nSize = sizeof(_name_); \ + (_s_).nVersion.s.nVersionMajor = 0x1; \ + (_s_).nVersion.s.nVersionMinor = 0x1; \ + (_s_).nVersion.s.nRevision = 0x0; \ + (_s_).nVersion.s.nStep = 0x0 + + +/* Params needed for Dynamic Frame Rate Control*/ +#define FRAME_RATE_THRESHOLD 1 /* Change in Frame rate to configure the encoder */ +OMX_U32 nFrameRateThreshold = 0;/* Frame Rate threshold for every frame rate update */ +OMX_U32 nPortFrameRate = 0; /* Port FPS initially set to the Encoder */ +OMX_U32 nFrameCounter = 0; /* Number of input frames recieved since last framerate calculation */ +OMX_TICKS nVideoTime = 0; /* Video duration since last framerate calculation */ +OMX_TICKS nLastFrameRateUpdateTime = 0; /*Time stamp at last frame rate update */ +OMX_U16 nBFrames = 0; /* Number of B Frames in H264 Encoder */ + + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT +/* Opaque color format requires below quirks to be enabled + * ENABLE_GRALLOC_BUFFER + * ANDROID_QUIRCK_CHANGE_PORT_VALUES + */ +#define OMX_H264VE_NUM_INTERNAL_BUF (8) +#define HAL_PIXEL_FORMAT_TI_NV12 (0x100) + +#define COLORCONVERT_MAX_SUB_BUFFERS (3) + +#define COLORCONVERT_BUFTYPE_VIRTUAL (0x0) +#define COLORCONVERT_BUFTYPE_ION (0x1) +#define COLORCONVERT_BUFTYPE_GRALLOCOPAQUE (0x2) + +int COLORCONVERT_open(void **hCC, PROXY_COMPONENT_PRIVATE *pCompPrv); +int COLORCONVERT_PlatformOpaqueToNV12(void *hCC, void *pSrc[], + void *pDst[], int nWidth, + int nHeight, int nStride, + int nSrcBufType, int nDstBufType); +int COLORCONVERT_close(void *hCC,PROXY_COMPONENT_PRIVATE *pCompPrv); +static int COLORCONVERT_AllocateBuffer(OMX_HANDLETYPE hComponent, OMX_U32 nStride); +static OMX_ERRORTYPE LOCAL_PROXY_H264E_AllocateBuffer(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); + +static OMX_ERRORTYPE LOCAL_PROXY_H264E_FreeBuffer(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, OMX_IN OMX_BUFFERHEADERTYPE * pBufferHdr); + +static OMX_ERRORTYPE LOCAL_PROXY_H264E_ComponentDeInit(OMX_HANDLETYPE hComponent); + +typedef struct _OMX_PROXY_H264E_PRIVATE +{ + OMX_PTR hBufPipe; + OMX_BOOL bAndroidOpaqueFormat; + OMX_PTR hCC; + IMG_native_handle_t* gralloc_handle[OMX_H264VE_NUM_INTERNAL_BUF]; + OMX_S32 nCurBufIndex; + alloc_device_t* mAllocDev; +}OMX_PROXY_H264E_PRIVATE; + +RPC_OMX_ERRORTYPE RPC_RegisterBuffer(OMX_HANDLETYPE hRPCCtx, int fd, + OMX_PTR *handle1, OMX_PTR *handle2, + PROXY_BUFFER_TYPE proxyBufferType); +RPC_OMX_ERRORTYPE RPC_UnRegisterBuffer(OMX_HANDLETYPE hRPCCtx, OMX_PTR handle); +#endif + + +OMX_ERRORTYPE LOCAL_PROXY_H264E_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, OMX_OUT OMX_INDEXTYPE * pIndexType); + +OMX_ERRORTYPE LOCAL_PROXY_H264E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr); + +static OMX_ERRORTYPE OMX_ConfigureDynamicFrameRate( OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_U32 nTargetFrameRate = 0; /* Target Frame Rate to be provided to Encoder */ + OMX_U32 nCurrentFrameRate = 0; /* Current Frame Rate currently set in Encoder */ + OMX_CONFIG_FRAMERATETYPE tFrameRate; + OMX_COMPONENTTYPE *pHandle; + if (hComponent == NULL){ + DOMX_ERROR("Component is invalid/ not present "); + return OMX_ErrorBadParameter; + } + pHandle = (OMX_COMPONENTTYPE *) hComponent; + + /* Initialise the OMX structures */ + OMX_INIT_STRUCT(tFrameRate,OMX_CONFIG_FRAMERATETYPE); + + /* Intialise nLastFrameRateUpdateTime for the 1st frame */ + if((!nFrameCounter) && (!nLastFrameRateUpdateTime)){ + nLastFrameRateUpdateTime = pBufferHdr-> nTimeStamp; + } + + /* Increment the Frame Counter and Calculate Frame Rate*/ + nFrameCounter++; + nVideoTime = pBufferHdr->nTimeStamp - nLastFrameRateUpdateTime; + + if(nVideoTime < 0) { + return OMX_ErrorBadParameter; + } + + /*Get Port Frame Rate if not read yet*/ + if(!nFrameRateThreshold) { + tFrameRate.nPortIndex = OMX_H264E_INPUT_PORT; /* As per ducati support-set for input port */ + + /* Read Current FrameRate */ + eError = pHandle->GetConfig(hComponent,OMX_IndexConfigVideoFramerate,&tFrameRate); + if (eError != OMX_ErrorNone) + DOMX_ERROR ("pHandle->GetConfig OMX_IndexConfigVideoFramerate eError :0x%x \n",eError); + nFrameRateThreshold = tFrameRate.xEncodeFramerate >>16; + nPortFrameRate = nFrameRateThreshold; + DOMX_DEBUG(" Port Frame Rate is %d ", nPortFrameRate); + } + nCurrentFrameRate = nFrameRateThreshold; + + /* If Number of frames is less than the Threshold + * Frame Rate udpate is not necessary + */ + if(nFrameCounter < nFrameRateThreshold){ + DOMX_EXIT(" Threshold not reached, no update necessary"); + return OMX_ErrorNone; + } + + /*Calculate the new target Frame Rate*/ + if (nVideoTime != 0) + nTargetFrameRate = nFrameCounter * 1000000 / nVideoTime; + + /* For 1080p record, max FPS supported by Codec for profile 4.1 is 30. + * When Dynamic Frame Rate is enabled, there might be scenario when FPS + * calculated is more than 30. Hence adding the check so that Dynamic Frame + * Rate set is never greater than the port FPS initially set. + */ + if(nTargetFrameRate > nPortFrameRate){ + DOMX_DEBUG("Frame Rate Calculated is more than initial port set Frame Rate"); + nTargetFrameRate = nPortFrameRate; + } + + /* Difference in Frame Rate is more than Threshold - Only then update Frame Rate*/ + if((( (OMX_S32)nTargetFrameRate) -((OMX_S32) nCurrentFrameRate) >= FRAME_RATE_THRESHOLD) || + (((OMX_S32) nCurrentFrameRate) - ( (OMX_S32)nTargetFrameRate) >= FRAME_RATE_THRESHOLD)) { + + /* Now Send the new Frame Rate */ + tFrameRate.nPortIndex = OMX_H264E_INPUT_PORT; /* As per ducati support-set for input port */ + tFrameRate.xEncodeFramerate = (OMX_U32)(nTargetFrameRate * (1 << 16)); + eError = pHandle->SetConfig(hComponent,OMX_IndexConfigVideoFramerate,&tFrameRate); + if(eError != OMX_ErrorNone){ + DOMX_ERROR(" Error while configuring Dynamic Frame Rate,Error info = %d",eError); + return eError; + } else { + DOMX_DEBUG("Dynamic Frame Rate configuration successful \n"); + } + nFrameRateThreshold = nTargetFrameRate; /*Update the threshold */ + } + + /* reset all params */ + nFrameCounter = 0 ; + nVideoTime = 0; + nLastFrameRateUpdateTime = pBufferHdr->nTimeStamp; + return OMX_ErrorNone; +} + +static OMX_ERRORTYPE ComponentPrivateEmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + + eError = OMX_ConfigureDynamicFrameRate(hComponent, pBufferHdr); + if( eError != OMX_ErrorNone) + DOMX_ERROR(" Error while configuring FrameRate Dynamically.Error info = %d",eError); + + DOMX_DEBUG("Redirection from ComponentPricateEmptyThisBuffer to PROXY_EmptyThisBuffer"); + return LOCAL_PROXY_H264E_EmptyThisBuffer (hComponent,pBufferHdr); +} + +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *pHandle = NULL; + PROXY_COMPONENT_PRIVATE *pComponentPrivate = NULL; + pHandle = (OMX_COMPONENTTYPE *) hComponent; + OMX_TI_PARAM_ENHANCEDPORTRECONFIG tParamStruct; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; +#endif + char value[OMX_MAX_STRINGNAME_SIZE]; + OMX_U32 mEnableVFR = 1; /* Flag used to enable/disable VFR for Encoder */ + property_get("debug.vfr.enable", value, "1"); + mEnableVFR = atoi(value); + + DOMX_ENTER(""); + + DOMX_DEBUG("Component name provided is %s", COMPONENT_NAME); + + pHandle->pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) + TIMM_OSAL_Malloc(sizeof(PROXY_COMPONENT_PRIVATE), TIMM_OSAL_TRUE, + 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pHandle->pComponentPrivate != NULL, + OMX_ErrorInsufficientResources, + "ERROR IN ALLOCATING PROXY COMPONENT PRIVATE STRUCTURE"); + + pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate; + + TIMM_OSAL_Memset(pComponentPrivate, 0, + sizeof(PROXY_COMPONENT_PRIVATE)); + + pComponentPrivate->cCompName = + TIMM_OSAL_Malloc(MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8), + TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pComponentPrivate->cCompName != NULL, + OMX_ErrorInsufficientResources, + " Error in Allocating space for proxy component table"); + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pComponentPrivate->pCompProxyPrv = + (OMX_PROXY_H264E_PRIVATE *) + TIMM_OSAL_Malloc(sizeof(OMX_PROXY_H264E_PRIVATE), TIMM_OSAL_TRUE, + 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pComponentPrivate->pCompProxyPrv != NULL, + OMX_ErrorInsufficientResources, + " Could not allocate proxy component private"); + + TIMM_OSAL_Memset(pComponentPrivate->pCompProxyPrv, 0, + sizeof(OMX_PROXY_H264E_PRIVATE)); + + pProxy = (OMX_PROXY_H264E_PRIVATE *) pComponentPrivate->pCompProxyPrv; + + /* Create Pipe of for encoder input buffers */ + eOSALStatus = TIMM_OSAL_CreatePipe(&pProxy->hBufPipe, sizeof(OMX_U32), + OMX_H264VE_NUM_INTERNAL_BUF, 1); + PROXY_assert(eOSALStatus == TIMM_OSAL_ERR_NONE, + OMX_ErrorInsufficientResources, + "Pipe creation failed"); +#endif + + // Copying component Name - this will be picked up in the proxy common + PROXY_assert(strlen(COMPONENT_NAME) + 1 < MAX_COMPONENT_NAME_LENGTH, + OMX_ErrorInvalidComponentName, + "Length of component name is longer than the max allowed"); + TIMM_OSAL_Memcpy(pComponentPrivate->cCompName, COMPONENT_NAME, + strlen(COMPONENT_NAME) + 1); + + eError = OMX_ProxyCommonInit(hComponent); // Calling Proxy Common Init() +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES + pHandle->SetParameter = LOCAL_PROXY_H264E_SetParameter; + pHandle->GetParameter = LOCAL_PROXY_H264E_GetParameter; +#endif + pComponentPrivate->IsLoadedState = OMX_TRUE; + pHandle->EmptyThisBuffer = LOCAL_PROXY_H264E_EmptyThisBuffer; + pHandle->GetExtensionIndex = LOCAL_PROXY_H264E_GetExtensionIndex; + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pHandle->ComponentDeInit = LOCAL_PROXY_H264E_ComponentDeInit; + pHandle->FreeBuffer = LOCAL_PROXY_H264E_FreeBuffer; + pHandle->AllocateBuffer = LOCAL_PROXY_H264E_AllocateBuffer; +#endif + + if(mEnableVFR) + pHandle->EmptyThisBuffer = ComponentPrivateEmptyThisBuffer; + + EXIT: + if (eError != OMX_ErrorNone) + { + DOMX_DEBUG("Error in Initializing Proxy"); + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + if(pProxy->hBufPipe != NULL) + { + TIMM_OSAL_DeletePipe(pProxy->hBufPipe); + pProxy->hBufPipe = NULL; + } + + if(pComponentPrivate->pCompProxyPrv != NULL) + { + TIMM_OSAL_Free(pComponentPrivate->pCompProxyPrv); + pComponentPrivate->pCompProxyPrv = NULL; + pProxy = NULL; + } +#endif + if (pComponentPrivate->cCompName != NULL) + { + TIMM_OSAL_Free(pComponentPrivate->cCompName); + pComponentPrivate->cCompName = NULL; + } + if (pComponentPrivate != NULL) + { + TIMM_OSAL_Free(pComponentPrivate); + pComponentPrivate = NULL; + } + } + return eError; +} + +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES + +/* ===========================================================================*/ +/** + * @name PROXY_H264E_GetParameter() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE LOCAL_PROXY_H264E_GetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PARAM_PORTDEFINITIONTYPE* pPortDef = NULL; + OMX_VIDEO_PARAM_PORTFORMATTYPE* pPortParam = NULL; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; +#endif + + PROXY_require((pParamStruct != NULL), OMX_ErrorBadParameter, NULL); + PROXY_assert((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; +#endif + + DOMX_ENTER + ("hComponent = %p, pCompPrv = %p, nParamIndex = %d, pParamStruct = %p", + hComponent, pCompPrv, nParamIndex, pParamStruct); + + eError = PROXY_GetParameter(hComponent,nParamIndex, pParamStruct); + + if(nParamIndex == OMX_IndexParamPortDefinition) + { + pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct; + + if(pPortDef->format.video.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar) + { +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + if(pProxy->bAndroidOpaqueFormat == OMX_TRUE) + { + pPortDef->format.video.eColorFormat = OMX_COLOR_FormatAndroidOpaque; + } + else +#endif + { + pPortDef->format.video.eColorFormat = OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; + } + } + + if(pPortDef->nPortIndex == OMX_H264E_INPUT_PORT) + { + if(pCompPrv->proxyPortBuffers[OMX_H264E_INPUT_PORT].proxyBufferType == EncoderMetadataPointers) + { + pPortDef->nBufferSize = sizeof(video_metadata_t); + } + } + } + else if (nParamIndex == OMX_IndexParamVideoPortFormat) + { + pPortParam = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pParamStruct; + + if((eError == OMX_ErrorNone) && + (pPortParam->eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar)) + { + pPortParam->eColorFormat = OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; + } +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + else if ((eError == OMX_ErrorNoMore) && + (pPortParam->nIndex == 1)) + { + /* HACK:Remote OMX-H264E supports only 1 color format (index 0). The + * OMX_COLOR_FormatAndroidOpaque is supported only at the proxy. + * Call GetParameter() to fill in defaults for parameters and + * override color format and index for the additional + * OMX_COLOR_FormatAndroidOpaque support*/ + pPortParam->nIndex = 0; + eError = PROXY_GetParameter(hComponent, nParamIndex, pParamStruct); + pPortParam->nIndex = 1; + pPortParam->eColorFormat = OMX_COLOR_FormatAndroidOpaque; + eError = OMX_ErrorNone; + } +#endif + } +#ifndef OMAP_TUNA + else if (nParamIndex == OMX_TI_IndexComponentHandle) + { + OMX_TI_COMPONENT_HANDLE * pCompHandle = pParamStruct; + pCompHandle->pHandle = hComponent; + eError = OMX_ErrorNone; + } +#endif + PROXY_assert((eError == OMX_ErrorNone) || (eError == OMX_ErrorNoMore), + eError," Error in Proxy GetParameter"); + + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +/* ===========================================================================*/ +/** + * @name PROXY_H264E_SetParameter() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE LOCAL_PROXY_H264E_SetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_IN OMX_PTR pParamStruct) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PARAM_PORTDEFINITIONTYPE* pPortDef = NULL; + OMX_VIDEO_PARAM_PORTFORMATTYPE* pPortParams = NULL; + OMX_VIDEO_STOREMETADATAINBUFFERSPARAMS* pStoreMetaData = NULL; + OMX_TI_PARAM_BUFFERPREANNOUNCE tParamSetNPA; + OMX_PARAM_PORTDEFINITIONTYPE sPortDef; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; +#endif + + DOMX_ENTER + ("hComponent = %p, pCompPrv = %p, nParamIndex = %d, pParamStruct = %p", + hComponent, pCompPrv, nParamIndex, pParamStruct); + + PROXY_require((pParamStruct != NULL), OMX_ErrorBadParameter, NULL); + PROXY_require((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; +#endif + + if(nParamIndex == OMX_IndexParamPortDefinition) + { + pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct; + + if(pPortDef->format.video.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) + { + pPortDef->format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + else if(pPortDef->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) + { + if(COLORCONVERT_open(&pProxy->hCC,pCompPrv) != 0) + { + PROXY_assert(0, OMX_ErrorInsufficientResources, + "Failed to open Color converting service"); + } + pProxy->bAndroidOpaqueFormat = OMX_TRUE; + pPortDef->format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } +#endif + } + else if(nParamIndex == OMX_IndexParamVideoPortFormat) + { + pPortParams = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pParamStruct; + + if(pPortParams->eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) + { + pPortParams->eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + else if(pPortParams->eColorFormat == OMX_COLOR_FormatAndroidOpaque) + { + if(COLORCONVERT_open(&pProxy->hCC,pCompPrv) != 0) + { + PROXY_assert(0, OMX_ErrorInsufficientResources, + "Failed to open Color converting service"); + } + pProxy->bAndroidOpaqueFormat = OMX_TRUE; + pPortParams->eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } +#endif + } + else if(nParamIndex == (OMX_INDEXTYPE) OMX_TI_IndexEncoderStoreMetadatInBuffers) + { + pStoreMetaData = (OMX_VIDEO_STOREMETADATAINBUFFERSPARAMS *) pParamStruct; + + DOMX_DEBUG("Moving to Metadatamode"); + if (pStoreMetaData->nPortIndex == OMX_H264E_INPUT_PORT && pStoreMetaData->bStoreMetaData == OMX_TRUE) + { + tParamSetNPA.nSize = sizeof(OMX_TI_PARAM_BUFFERPREANNOUNCE); + tParamSetNPA.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + tParamSetNPA.nVersion.s.nVersionMinor = OMX_VER_MINOR; + tParamSetNPA.nVersion.s.nRevision = 0x0; + tParamSetNPA.nVersion.s.nStep = 0x0; + tParamSetNPA.nPortIndex = OMX_H264E_INPUT_PORT; + tParamSetNPA.bEnabled = OMX_FALSE; + //Call NPA on OMX encoder on ducati. + PROXY_SetParameter(hComponent,OMX_TI_IndexParamBufferPreAnnouncement, &tParamSetNPA); + pCompPrv->proxyPortBuffers[pStoreMetaData->nPortIndex].proxyBufferType = EncoderMetadataPointers; + DOMX_DEBUG("Moving to Metadatamode done"); + + /*Initializing Structure */ + sPortDef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + sPortDef.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + sPortDef.nVersion.s.nVersionMinor = OMX_VER_MINOR; + sPortDef.nVersion.s.nRevision = 0x0; + sPortDef.nVersion.s.nStep = 0x0; + sPortDef.nPortIndex = OMX_H264E_INPUT_PORT; + + eError = PROXY_GetParameter(hComponent,OMX_IndexParamPortDefinition, &sPortDef); + PROXY_assert(eError == OMX_ErrorNone, eError," Error in Proxy GetParameter for Port Def"); + + sPortDef.format.video.nStride = LINUX_PAGE_SIZE; + + eError = PROXY_SetParameter(hComponent,OMX_IndexParamPortDefinition, &sPortDef); + + PROXY_assert(eError == OMX_ErrorNone, eError," Error in Proxy SetParameter for Port Def"); + } + goto EXIT; + } + + eError = PROXY_SetParameter(hComponent, nParamIndex, pParamStruct); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy SetParameter"); + + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +#endif + + +/* ===========================================================================*/ +/** + * @name PROXY_GetExtensionIndex() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE LOCAL_PROXY_H264E_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, OMX_OUT OMX_INDEXTYPE * pIndexType) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = hComponent; + + PROXY_require((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + PROXY_require(cParameterName != NULL, OMX_ErrorBadParameter, NULL); + PROXY_require(pIndexType != NULL, OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + DOMX_ENTER("%s hComponent = %p, pCompPrv = %p, cParameterName = %s", + __FUNCTION__,hComponent, pCompPrv, cParameterName); + + // Check for NULL Parameters + PROXY_require((cParameterName != NULL && pIndexType != NULL), + OMX_ErrorBadParameter, NULL); + + // Ensure that String length is not greater than Max allowed length + PROXY_require(strlen(cParameterName) <= 127, OMX_ErrorBadParameter, NULL); + + if(strcmp(cParameterName, "OMX.google.android.index.storeMetaDataInBuffers") == 0) + { + // If Index type is 2D Buffer Allocated Dimension + *pIndexType = (OMX_INDEXTYPE) OMX_TI_IndexEncoderStoreMetadatInBuffers; + goto EXIT; + } + + eError = PROXY_GetExtensionIndex(hComponent, cParameterName, pIndexType); + + EXIT: + DOMX_EXIT("%s eError: %d",__FUNCTION__, eError); + return eError; +} + +/* ===========================================================================*/ +/** + * @name PROXY_H264E_EmptyThisBuffer() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE LOCAL_PROXY_H264E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PTR pBufferOrig = NULL; + OMX_U32 nStride = 0, nNumLines = 0; + OMX_PARAM_PORTDEFINITIONTYPE tParamStruct; + OMX_U32 nFilledLen, nAllocLen; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + OMX_U32 nBufIndex = 0, nSize=0, nRet=0; +#endif +#ifdef ENABLE_GRALLOC_BUFFER + OMX_PTR pAuxBuf0 = NULL, pAuxBuf1 = NULL; + RPC_OMX_ERRORTYPE eRPCError = RPC_OMX_ErrorNone; + OMX_ERRORTYPE eCompReturn = OMX_ErrorNone; + IMG_native_handle_t* pGrallocHandle=NULL; +#endif + + PROXY_require(pBufferHdr != NULL, OMX_ErrorBadParameter, NULL); + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + PROXY_CHK_VERSION(pBufferHdr, OMX_BUFFERHEADERTYPE); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; +#endif + + tParamStruct.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + tParamStruct.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + tParamStruct.nVersion.s.nVersionMinor = OMX_VER_MINOR; + tParamStruct.nVersion.s.nRevision = 0x0; + tParamStruct.nVersion.s.nStep = 0x0; + tParamStruct.nPortIndex = OMX_H264E_INPUT_PORT; + + eError = PROXY_GetParameter(hComponent, OMX_IndexParamPortDefinition, &tParamStruct); + PROXY_require(eError == OMX_ErrorNone, OMX_ErrorBadParameter, "Error is Get Parameter for port def"); + nFilledLen = pBufferHdr->nFilledLen; + nAllocLen = pBufferHdr->nAllocLen; + if(nFilledLen != 0) + { + pBufferHdr->nFilledLen = tParamStruct.nBufferSize; + } + pBufferHdr->nAllocLen = tParamStruct.nBufferSize; + + DOMX_DEBUG + ("%s hComponent=%p, pCompPrv=%p, nFilledLen=%d, nOffset=%d, nFlags=%08x", + __FUNCTION__,hComponent, pCompPrv, pBufferHdr->nFilledLen, + pBufferHdr->nOffset, pBufferHdr->nFlags); + + if( pCompPrv->proxyPortBuffers[OMX_H264E_INPUT_PORT].proxyBufferType == EncoderMetadataPointers ) + { + OMX_U32 *pTempBuffer; + OMX_U32 nMetadataBufferType; + DOMX_DEBUG("Passing meta data to encoder"); + + pBufferOrig = pBufferHdr->pBuffer; + + pTempBuffer = (OMX_U32 *) (pBufferHdr->pBuffer); + nMetadataBufferType = *pTempBuffer; + + if(nMetadataBufferType == kMetadataBufferTypeCameraSource) + { +#ifdef ENABLE_GRALLOC_BUFFER + video_metadata_t* pVideoMetadataBuffer; + DOMX_DEBUG("MetadataBufferType is kMetadataBufferTypeCameraSource"); + + pVideoMetadataBuffer = (video_metadata_t*) ((OMX_U32 *)(pBufferHdr->pBuffer)); + pGrallocHandle = (IMG_native_handle_t*) (pVideoMetadataBuffer->handle); + DOMX_DEBUG("Grallloc buffer recieved in metadata buffer 0x%x",pGrallocHandle ); + if( pGrallocHandle->iFormat != HAL_PIXEL_FORMAT_TI_NV12 && pProxy->gralloc_handle[0] == NULL ) { + DOMX_DEBUG("Allocating NV12 buffers internally within DOMX actual count: %d", pCompPrv->nAllocatedBuffers); + pProxy->nCurBufIndex = 0; + + while( (unsigned) pProxy->nCurBufIndex < pCompPrv->nAllocatedBuffers ) { + eError = COLORCONVERT_AllocateBuffer(hComponent, nStride); + PROXY_require(eError == OMX_ErrorNone, eError, "Error allocating buffers for color conversion"); + pProxy->nCurBufIndex++; + } + } + pBufferHdr->pBuffer = (OMX_U8 *)(pGrallocHandle->fd[0]); + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)-> + pAuxBuf1 = (OMX_PTR) pGrallocHandle->fd[1]; + DOMX_DEBUG("%s Gralloc=0x%x, Y-fd=%d, UV-fd=%d", __FUNCTION__, pGrallocHandle, + pGrallocHandle->fd[0], pGrallocHandle->fd[1]); + + pBufferHdr->nOffset = pVideoMetadataBuffer->offset; +#endif + } + else if(nMetadataBufferType == kMetadataBufferTypeGrallocSource) + { +#ifdef ENABLE_GRALLOC_BUFFER + buffer_handle_t tBufHandle; + DOMX_DEBUG("MetadataBufferType is kMetadataBufferTypeGrallocSource"); + + pTempBuffer++; + tBufHandle = *((buffer_handle_t *)pTempBuffer); + pGrallocHandle = (IMG_native_handle_t*) tBufHandle; + DOMX_DEBUG("Grallloc buffer recieved in metadata buffer 0x%x",pGrallocHandle ); + if( pGrallocHandle->iFormat != HAL_PIXEL_FORMAT_TI_NV12 && pProxy->gralloc_handle[0] == NULL ) { + DOMX_DEBUG("Allocating NV12 buffers internally within DOMX actual count: %d", pCompPrv->nAllocatedBuffers); + pProxy->nCurBufIndex = 0; + + while( (unsigned) pProxy->nCurBufIndex < pCompPrv->nAllocatedBuffers ) { + eError = COLORCONVERT_AllocateBuffer(hComponent, nStride); + PROXY_require(eError == OMX_ErrorNone, eError, "Error allocating buffers for color conversion"); + pProxy->nCurBufIndex++; + } + } + + pBufferHdr->pBuffer = (OMX_U8 *)(pGrallocHandle->fd[0]); + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)-> + pAuxBuf1 = (OMX_PTR) pGrallocHandle->fd[1]; + DOMX_DEBUG("%s Gralloc=0x%x, Y-fd=%d, UV-fd=%d", __FUNCTION__, pGrallocHandle, + pGrallocHandle->fd[0], pGrallocHandle->fd[1]); +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + if (pProxy->bAndroidOpaqueFormat && pGrallocHandle->iFormat != HAL_PIXEL_FORMAT_TI_NV12) + { + /* Dequeue NV12 buffer for encoder */ + eOSALStatus = TIMM_OSAL_ReadFromPipe(pProxy->hBufPipe, &nBufIndex, + sizeof(OMX_PTR), (TIMM_OSAL_U32 *)(&nSize), + TIMM_OSAL_SUSPEND); + PROXY_assert(eOSALStatus == TIMM_OSAL_ERR_NONE, OMX_ErrorBadParameter, NULL); + + if(nFilledLen != 0) + { + /* Get NV12 data after colorconv*/ + nRet = COLORCONVERT_PlatformOpaqueToNV12(pProxy->hCC, (void **) &pGrallocHandle, (void **) &pProxy->gralloc_handle[nBufIndex], + pGrallocHandle->iWidth, + pGrallocHandle->iHeight, + 4096, COLORCONVERT_BUFTYPE_GRALLOCOPAQUE, + COLORCONVERT_BUFTYPE_GRALLOCOPAQUE ); + + if(nRet != 0) + { + eOSALStatus = TIMM_OSAL_WriteToPipe(pProxy->hBufPipe, (void *) &nBufIndex, + sizeof(OMX_U32), TIMM_OSAL_SUSPEND); + PROXY_assert(0, OMX_ErrorBadParameter, "Color conversion routine failed"); + } + } + + /* Update pBufferHdr with NV12 buffers for OMX component */ + pBufferHdr->pBuffer= (OMX_U8 *)(pProxy->gralloc_handle[nBufIndex]->fd[0]); + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)->pAuxBuf1 = (OMX_PTR)(pProxy->gralloc_handle[nBufIndex]->fd[1]); + } +#endif +#endif + } + else + { + DOMX_ERROR("MetadataBufferType is unknow. Returning 'OMX_ErrorBadParameter'"); + eError = OMX_ErrorBadParameter; + goto EXIT; //need to restore lenght fields in pBufferHdr + } +#ifdef ENABLE_GRALLOC_BUFFER + eRPCError = RPC_RegisterBuffer(pCompPrv->hRemoteComp, pBufferHdr->pBuffer, + &pAuxBuf0, &pAuxBuf1, + GrallocPointers); + PROXY_checkRpcError(); + if (pAuxBuf0) + pBufferHdr->pBuffer = pAuxBuf0; + if (pAuxBuf1) + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)->pAuxBuf1 = pAuxBuf1; +#endif + } + + eError = PROXY_EmptyThisBuffer(hComponent, pBufferHdr); +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + if (pProxy->bAndroidOpaqueFormat +#ifdef ENABLE_GRALLOC_BUFFER +&& pGrallocHandle != NULL && pGrallocHandle->iFormat != HAL_PIXEL_FORMAT_TI_NV12 +#endif +) + { + /*Write buffer to end of pipe for re-circulation for future ETB()*/ + eOSALStatus = TIMM_OSAL_WriteToPipe(pProxy->hBufPipe, (void *) &nBufIndex, + sizeof(OMX_U32), TIMM_OSAL_SUSPEND); + PROXY_assert(eOSALStatus == TIMM_OSAL_ERR_NONE, OMX_ErrorBadParameter, "Pipe write failed"); + } +#endif + +EXIT: + if( pBufferHdr!=NULL && pCompPrv->proxyPortBuffers[pBufferHdr->nInputPortIndex].proxyBufferType == EncoderMetadataPointers) + { + pBufferHdr->pBuffer = pBufferOrig; + pBufferHdr->nFilledLen = nFilledLen; + pBufferHdr->nAllocLen = nAllocLen; +#ifdef ENABLE_GRALLOC_BUFFER + RPC_UnRegisterBuffer(pCompPrv->hRemoteComp, pAuxBuf0); + RPC_UnRegisterBuffer(pCompPrv->hRemoteComp, pAuxBuf1); +#endif + } + return eError; +} + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT +static OMX_ERRORTYPE LOCAL_PROXY_H264E_AllocateBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE ** ppBufferHdr, OMX_U32 nPortIndex, + OMX_PTR pAppPrivate, OMX_U32 nSizeBytes) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + int err, nStride; + + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; + + + eError = PROXY_AllocateBuffer(hComponent, ppBufferHdr, nPortIndex, + pAppPrivate, nSizeBytes); +EXIT: + return eError; +} + +static OMX_ERRORTYPE LOCAL_PROXY_H264E_FreeBuffer(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, OMX_IN OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_U32 nBufIndex, nSize, nCount=0; + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; + + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; + + if((nPortIndex == OMX_H264E_INPUT_PORT) && + (pProxy->bAndroidOpaqueFormat) && (pProxy->gralloc_handle[0] != NULL)) + { + pProxy->nCurBufIndex--; + PROXY_require(pProxy->nCurBufIndex >=0, + OMX_ErrorBadParameter, "Buffer index underflow"); + + if(pProxy->gralloc_handle[pProxy->nCurBufIndex]) + { + pProxy->mAllocDev->free(pProxy->mAllocDev, (buffer_handle_t)(pProxy->gralloc_handle[pProxy->nCurBufIndex])); + pProxy->gralloc_handle[pProxy->nCurBufIndex] = NULL; + } + + /*Clear the Bufindex pipe by dummy reads*/ + TIMM_OSAL_GetPipeReadyMessageCount(pProxy->hBufPipe, (TIMM_OSAL_U32 *)&nCount); + if(nCount) + { + TIMM_OSAL_ReadFromPipe(pProxy->hBufPipe, &nBufIndex, + sizeof(OMX_PTR), (TIMM_OSAL_U32 *)&nSize, TIMM_OSAL_NO_SUSPEND); + } + } + + eError = PROXY_FreeBuffer(hComponent, nPortIndex, pBufferHdr); + +EXIT: + return eError; +} + +int COLORCONVERT_AllocateBuffer(OMX_HANDLETYPE hComponent, OMX_U32 nStride) +{ + OMX_CONFIG_RECTTYPE tParam; + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + OMX_U32 err; + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; + + tParam.nSize = sizeof(OMX_CONFIG_RECTTYPE); + tParam.nVersion.s.nVersionMajor = 1; + tParam.nVersion.s.nVersionMinor = 1; + tParam.nVersion.s.nRevision = 0; + tParam.nVersion.s.nStep = 0; + tParam.nPortIndex = OMX_H264E_INPUT_PORT; + eError = PROXY_GetParameter(hComponent, (OMX_INDEXTYPE)OMX_TI_IndexParam2DBufferAllocDimension, &tParam); + PROXY_assert(eError == OMX_ErrorNone, eError, " Error in Proxy GetParameter"); + err = pProxy->mAllocDev->alloc(pProxy->mAllocDev, (int) tParam.nWidth, (int) tParam.nHeight, (int) HAL_PIXEL_FORMAT_TI_NV12, (int) GRALLOC_USAGE_HW_RENDER, (const struct native_handle_t * *)(&(pProxy->gralloc_handle[pProxy->nCurBufIndex])), (int *) &nStride); + PROXY_assert(!err, err, " Error in allocating Gralloc buffers"); + eOSALStatus = TIMM_OSAL_WriteToPipe(pProxy->hBufPipe, (void *) &pProxy->nCurBufIndex, sizeof(OMX_U32), TIMM_OSAL_SUSPEND); + PROXY_assert(eOSALStatus == TIMM_OSAL_ERR_NONE, OMX_ErrorBadParameter, "Pipe write failed"); + +EXIT: + return eError; +} +OMX_ERRORTYPE LOCAL_PROXY_H264E_ComponentDeInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + OMX_U32 i; + + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; + + if(pProxy->hBufPipe != NULL) + { + eOSALStatus = TIMM_OSAL_DeletePipe(pProxy->hBufPipe); + pProxy->hBufPipe = NULL; + + if(eOSALStatus != TIMM_OSAL_ERR_NONE) + { + DOMX_ERROR("Pipe deletion failed"); + } + } + + if(pProxy->bAndroidOpaqueFormat == OMX_TRUE) + { + /* Cleanup internal buffers in pipe if not freed on FreeBuffer */ + for(i=0; i<OMX_H264VE_NUM_INTERNAL_BUF; i++) + { + if(pProxy->gralloc_handle[i]) + { + pProxy->mAllocDev->free(pProxy->mAllocDev, (buffer_handle_t)(pProxy->gralloc_handle[i])); + pProxy->gralloc_handle[i] = NULL; + } + } + + + COLORCONVERT_close(pProxy->hCC,pCompPrv); + pProxy->bAndroidOpaqueFormat = OMX_FALSE; + + if(pCompPrv->pCompProxyPrv != NULL) + { + TIMM_OSAL_Free(pCompPrv->pCompProxyPrv); + pCompPrv->pCompProxyPrv = NULL; + } + } + + eError = PROXY_ComponentDeInit(hComponent); +EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +int COLORCONVERT_open(void **hCC, PROXY_COMPONENT_PRIVATE *pCompPrv) +{ + int nErr = -1; + hw_module_t const* module = NULL; + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; + + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; + nErr = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + + if (nErr == 0) + { + *hCC = (void *) ((IMG_gralloc_module_public_t const *)module); + } + else + { + DOMX_ERROR("FATAL: gralloc api hw_get_module() returned error: Can't find \ + %s module err = %x", GRALLOC_HARDWARE_MODULE_ID, nErr); + } + + gralloc_open(module, &(pProxy->mAllocDev)); + + return nErr; +} + +int COLORCONVERT_PlatformOpaqueToNV12(void *hCC, + void *pSrc[COLORCONVERT_MAX_SUB_BUFFERS], + void *pDst[COLORCONVERT_MAX_SUB_BUFFERS], + int nWidth, int nHeight, int nStride, + int nSrcBufType,int nDstBufType) +{ + IMG_gralloc_module_public_t const* module = hCC; + int nErr = -1; + + if((nSrcBufType == COLORCONVERT_BUFTYPE_GRALLOCOPAQUE) && (nDstBufType == COLORCONVERT_BUFTYPE_VIRTUAL)) + { + nErr = module->Blit(module, pSrc[0], pDst, HAL_PIXEL_FORMAT_TI_NV12); + } + else if((nSrcBufType == COLORCONVERT_BUFTYPE_GRALLOCOPAQUE) && (nDstBufType == COLORCONVERT_BUFTYPE_GRALLOCOPAQUE )) + { + nErr = module->Blit2(module, pSrc[0], pDst[0], nWidth, nHeight, 0, 0); + } + + return nErr; +} + +int COLORCONVERT_close(void *hCC,PROXY_COMPONENT_PRIVATE *pCompPrv) +{ + OMX_PROXY_H264E_PRIVATE *pProxy = NULL; + pProxy = (OMX_PROXY_H264E_PRIVATE *) pCompPrv->pCompProxyPrv; + if(pProxy && pProxy->mAllocDev) + { + gralloc_close(pProxy->mAllocDev); + } + return 0; +} +#endif diff --git a/domx/omx_proxy_component/omx_mpeg4_enc/Makefile b/domx/omx_proxy_component/omx_mpeg4_enc/Makefile new file mode 100644 index 0000000..f342e66 --- /dev/null +++ b/domx/omx_proxy_component/omx_mpeg4_enc/Makefile @@ -0,0 +1,103 @@ +# +# Copyright (C) Texas Instruments - http://www.ti.com/ +# +# 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. +# +# ---------------------------------------------------------------------------- +# Revision History +# +# +# REF=ORG +# Original version. +# ---------------------------------------------------------------------------- + + + +include $(PROJROOT)/make/start.mk + +# Do not change above "include" line(s) + +# Arguments to tools, will move to make system once finalized. + +CFLAGS = +CDEFS = +ifeq ($(BUILD),udeb) +CDEFS += DEBUG +endif +CDEFS += + +EXEC_ARGS = +ST_LIB_ARGS = +SH_LIB_ARGS = + +# Define this macro if target runs in kernel mode +#__KERNEL__ = 1 + +# Target name and extension +# static library (ST_LIB): filename.a +# shared library soname (SH_LIB): filename.so.maj_ver.min_ver +# executable (EXEC) : filename.out + +TARGETNAME = libOMX.TI.DUCATI1.VIDEO.MPEG4E.so + + +# TARGETTYPE must be EXEC, ST_LIB or SH_LIB in upper case. + +TARGETTYPE = SH_LIB + +# install directory relative to the HOSTTARGET directory +HOSTRELEASE = lib + +# install directory relative to the root filesystem +ROOTFSRELEASE = lib + +# Folders in which gmake will run before building current target + +SUBMODULES = \ + +# Filename must not begin with '.', '/' or '\' + +SOURCES = \ +src/omx_proxy_mpeg4enc.c \ + + + +# Search path for include files + +INCLUDES = \ + $(PROJROOT)/omx_core/inc \ + $(PROJROOT)/mm_osal/inc \ + $(PROJROOT)/domx \ + $(PROJROOT)/domx/omx_rpc/inc \ + + +# Libraries needed for linking. + +ST_LIBS = +#mm_osal domx +SH_LIBS = domx omx_core mm_osal +#pthread rt utils procmgr ipc rcm notify +#SH_LIBS += sysmgr sysmemmgr + + +# Search path for library (and linker command) files. +# Current folder and target folder are included by default. + +LIBINCLUDES = $(PROJROOT)/mm_osal \ + $(PROJROOT)/domx \ + $(PROJROOT)/omx_core + + +# Do not change below "include" line(s) + +include $(PROJROOT)/make/build.mk diff --git a/domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c b/domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c new file mode 100644 index 0000000..9767d89 --- /dev/null +++ b/domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c @@ -0,0 +1,1050 @@ +/* + * Copyright (c) 2010, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file omx_proxy_mpeg4enc.c + * This file contains methods that provides the functionality for + * the OpenMAX1.1 DOMX Framework Proxy component. + ********************************************************************************************* + This is the proxy specific wrapper that passes the component name to the generic proxy init() + The proxy wrapper also does some runtime/static time onfig on per proxy basis + This is a thin wrapper that is called when componentiit() of the proxy is called + static OMX_ERRORTYPE PROXY_Wrapper_init(OMX_HANDLETYPE hComponent, OMX_PTR pAppData); + this layer gets called first whenever a proxy's get handle is called + ************************************************************************************************ + * @path WTSD_DucatiMMSW\omx\omx_il_1_x\omx_proxy_component\src + * + * @rev 1.0 + */ + +/*============================================================== + *! Revision History + *! ============================ + * 31-August-2011 Lakshman N : Support for color conv at encoder + * input port + * + *! 20-August-2010 Sarthak Aggarwal sarthak@ti.com: Initial Version + *================================================================*/ + +/****************************************************************** + * INCLUDE FILES + ******************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include "omx_proxy_common.h" +#include <timm_osal_interfaces.h> +#include "OMX_TI_IVCommon.h" +#include "OMX_TI_Video.h" +#include "OMX_TI_Index.h" + +#include <MetadataBufferType.h> +#ifdef ENABLE_GRALLOC_BUFFER +#include "native_handle.h" +#include <hal_public.h> +#include <VideoMetadata.h> +#endif + +#include <stdlib.h> +#include <cutils/properties.h> + +#define COMPONENT_NAME "OMX.TI.DUCATI1.VIDEO.MPEG4E" +/* needs to be specific for every configuration wrapper */ + +#define OMX_MPEG4E_INPUT_PORT 0 +#define LINUX_PAGE_SIZE 4096 + +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES +/* Opaque color format requires below quirks to be enabled + * ENABLE_GRALLOC_BUFFER + * ANDROID_QUIRK_CHANGE_PORT_VALUES + */ +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_GetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct); + +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_SetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct); + +#endif + + +#define OMX_INIT_STRUCT(_s_, _name_) \ + memset(&(_s_), 0x0, sizeof(_name_)); \ + (_s_).nSize = sizeof(_name_); \ + (_s_).nVersion.s.nVersionMajor = 0x1; \ + (_s_).nVersion.s.nVersionMinor = 0x1; \ + (_s_).nVersion.s.nRevision = 0x0; \ + (_s_).nVersion.s.nStep = 0x0 + + +/* Params needed for Dynamic Frame Rate Control*/ +#define FRAME_RATE_THRESHOLD 1 /* Change in Frame rate to configure the encoder */ +OMX_U32 nFrameRateThreshold = 0;/* Frame Rate threshold for every frame rate update */ +OMX_U32 nPortFrameRate = 0; /* Port FPS initially set to the Encoder */ +OMX_U32 nFrameCounter = 0; /* Number of input frames recieved since last framerate calculation */ +OMX_TICKS nVideoTime = 0; /* Video duration since last framerate calculation */ +OMX_TICKS nLastFrameRateUpdateTime = 0; /*Time stamp at last frame rate update */ +OMX_U16 nBFrames = 0; /* Number of B Frames in H264 Encoder */ + + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT +#define OMX_MPEG4E_NUM_INTERNAL_BUF (8) +#define HAL_PIXEL_FORMAT_TI_NV12 (0x100) + +#define COLORCONVERT_MAX_SUB_BUFFERS (3) + +#define COLORCONVERT_BUFTYPE_VIRTUAL (0x0) +#define COLORCONVERT_BUFTYPE_ION (0x1) +#define COLORCONVERT_BUFTYPE_GRALLOCOPAQUE (0x2) + +int COLORCONVERT_open(void **hCC, PROXY_COMPONENT_PRIVATE *pCompPrv); +int COLORCONVERT_PlatformOpaqueToNV12(void *hCC, void *pSrc[], + void *pDst[], int nWidth, + int nHeight, int nStride, + int nSrcBufType, int nDstBufType); +int COLORCONVERT_close(void *hCC,PROXY_COMPONENT_PRIVATE *pCompPrv); + +static OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_AllocateBuffer(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); + +static OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_FreeBuffer(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, OMX_IN OMX_BUFFERHEADERTYPE * pBufferHdr); + +static OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_ComponentDeInit(OMX_HANDLETYPE hComponent); + +typedef struct _OMX_PROXY_MPEG4E_PRIVATE +{ + OMX_PTR hBufPipe; + OMX_BOOL bAndroidOpaqueFormat; + OMX_PTR hCC; + IMG_native_handle_t* gralloc_handle[OMX_MPEG4E_NUM_INTERNAL_BUF]; + OMX_S32 nCurBufIndex; + alloc_device_t* mAllocDev; +}OMX_PROXY_MPEG4E_PRIVATE; + +RPC_OMX_ERRORTYPE RPC_RegisterBuffer(OMX_HANDLETYPE hRPCCtx, int fd, + OMX_PTR *handle1, OMX_PTR *handle2, + PROXY_BUFFER_TYPE proxyBufferType); +RPC_OMX_ERRORTYPE RPC_UnRegisterBuffer(OMX_HANDLETYPE hRPCCtx, OMX_PTR handle); +#endif + +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, OMX_OUT OMX_INDEXTYPE * pIndexType); + +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr); + +static OMX_ERRORTYPE OMX_ConfigureDynamicFrameRate( OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_U32 nTargetFrameRate = 0; /* Target Frame Rate to be provided to Encoder */ + OMX_U32 nCurrentFrameRate = 0; /* Current Frame Rate currently set in Encoder */ + OMX_CONFIG_FRAMERATETYPE tFrameRate; + OMX_COMPONENTTYPE *pHandle; + if (hComponent == NULL){ + DOMX_ERROR("Component is invalid/ not present "); + return OMX_ErrorBadParameter; + } + pHandle = (OMX_COMPONENTTYPE *) hComponent; + + /* Initialise the OMX structures */ + OMX_INIT_STRUCT(tFrameRate,OMX_CONFIG_FRAMERATETYPE); + + /* Intialise nLastFrameRateUpdateTime for the 1st frame */ + if((!nFrameCounter) && (!nLastFrameRateUpdateTime)){ + nLastFrameRateUpdateTime = pBufferHdr-> nTimeStamp; + } + + /* Increment the Frame Counter and Calculate Frame Rate*/ + nFrameCounter++; + nVideoTime = pBufferHdr->nTimeStamp - nLastFrameRateUpdateTime; + + if(nVideoTime < 0) { + return OMX_ErrorBadParameter; + } + + /*Get Port Frame Rate if not read yet*/ + if(!nFrameRateThreshold) { + tFrameRate.nPortIndex = OMX_MPEG4E_INPUT_PORT; /* As per ducati support-set for input port */ + + /* Read Current FrameRate */ + eError = pHandle->GetConfig(hComponent,OMX_IndexConfigVideoFramerate,&tFrameRate); + if (eError != OMX_ErrorNone) + DOMX_ERROR ("pHandle->GetConfig OMX_IndexConfigVideoFramerate eError :0x%x \n",eError); + nFrameRateThreshold = tFrameRate.xEncodeFramerate >>16; + nPortFrameRate = nFrameRateThreshold; + DOMX_DEBUG(" Port Frame Rate is %d ", nPortFrameRate); + } + nCurrentFrameRate = nFrameRateThreshold; + + /* If Number of frames is less than the Threshold + * Frame Rate udpate is not necessary + */ + if(nFrameCounter < nFrameRateThreshold){ + DOMX_EXIT(" Threshold not reached, no update necessary"); + return OMX_ErrorNone; + } + + /*Calculate the new target Frame Rate*/ + if (nVideoTime != 0) + nTargetFrameRate = nFrameCounter * 1000000 / nVideoTime; + + /* For 1080p record, max FPS supported by Codec for profile 4.1 is 30. + * When Dynamic Frame Rate is enabled, there might be scenario when FPS + * calculated is more than 30. Hence adding the check so that Dynamic Frame + * Rate set is never greater than the port FPS initially set. + */ + if(nTargetFrameRate > nPortFrameRate){ + DOMX_DEBUG("Frame Rate Calculated is more than initial port set Frame Rate"); + nTargetFrameRate = nPortFrameRate; + } + + /* Difference in Frame Rate is more than Threshold - Only then update Frame Rate*/ + if((( (OMX_S32)nTargetFrameRate) -((OMX_S32) nCurrentFrameRate) >= FRAME_RATE_THRESHOLD) || + (((OMX_S32) nCurrentFrameRate) - ( (OMX_S32)nTargetFrameRate) >= FRAME_RATE_THRESHOLD)) { + + /* Now Send the new Frame Rate */ + tFrameRate.nPortIndex = OMX_MPEG4E_INPUT_PORT; /* As per ducati support-set for input port */ + tFrameRate.xEncodeFramerate = (OMX_U32)(nTargetFrameRate * (1 << 16)); + eError = pHandle->SetConfig(hComponent,OMX_IndexConfigVideoFramerate,&tFrameRate); + if(eError != OMX_ErrorNone){ + DOMX_ERROR(" Error while configuring Dynamic Frame Rate,Error info = %d",eError); + return eError; + } else { + DOMX_DEBUG("Dynamic Frame Rate configuration successful \n"); + } + nFrameRateThreshold = nTargetFrameRate; /*Update the threshold */ + } + + /* reset all params */ + nFrameCounter = 0 ; + nVideoTime = 0; + nLastFrameRateUpdateTime = pBufferHdr->nTimeStamp; + return OMX_ErrorNone; +} + +static OMX_ERRORTYPE ComponentPrivateEmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + + eError = OMX_ConfigureDynamicFrameRate(hComponent, pBufferHdr); + if( eError != OMX_ErrorNone) + DOMX_ERROR(" Error while configuring FrameRate Dynamically.Error info = %d",eError); + + DOMX_DEBUG("Redirection from ComponentPricateEmptyThisBuffer to PROXY_EmptyThisBuffer"); + return LOCAL_PROXY_MPEG4E_EmptyThisBuffer (hComponent,pBufferHdr); +} + +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *pHandle = NULL; + PROXY_COMPONENT_PRIVATE *pComponentPrivate = NULL; + pHandle = (OMX_COMPONENTTYPE *) hComponent; + OMX_TI_PARAM_ENHANCEDPORTRECONFIG tParamStruct; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; +#endif + char value[OMX_MAX_STRINGNAME_SIZE]; + OMX_U32 mEnableVFR = 1; /* Flag used to enable/disable VFR for Encoder */ + property_get("debug.vfr.enable", value, "1"); + mEnableVFR = atoi(value); + + DOMX_ENTER(""); + + DOMX_DEBUG("Component name provided is %s", COMPONENT_NAME); + + pHandle->pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) + TIMM_OSAL_Malloc(sizeof(PROXY_COMPONENT_PRIVATE), TIMM_OSAL_TRUE, + 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pHandle->pComponentPrivate != NULL, + OMX_ErrorInsufficientResources, + "ERROR IN ALLOCATING PROXY COMPONENT PRIVATE STRUCTURE"); + + pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate; + + TIMM_OSAL_Memset(pComponentPrivate, 0, + sizeof(PROXY_COMPONENT_PRIVATE)); + + pComponentPrivate->cCompName = + TIMM_OSAL_Malloc(MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8), + TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pComponentPrivate->cCompName != NULL, + OMX_ErrorInsufficientResources, + " Error in Allocating space for proxy component table"); + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pComponentPrivate->pCompProxyPrv = + (OMX_PROXY_MPEG4E_PRIVATE *) + TIMM_OSAL_Malloc(sizeof(OMX_PROXY_MPEG4E_PRIVATE), TIMM_OSAL_TRUE, + 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pComponentPrivate->pCompProxyPrv != NULL, + OMX_ErrorInsufficientResources, + " Could not allocate proxy component private"); + + TIMM_OSAL_Memset(pComponentPrivate->pCompProxyPrv, 0, + sizeof(OMX_PROXY_MPEG4E_PRIVATE)); + + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pComponentPrivate->pCompProxyPrv; + + /* Create Pipe of for encoder input buffers */ + eOSALStatus = TIMM_OSAL_CreatePipe(&pProxy->hBufPipe, sizeof(OMX_U32), + OMX_MPEG4E_NUM_INTERNAL_BUF, 1); + PROXY_assert(eOSALStatus == TIMM_OSAL_ERR_NONE, + OMX_ErrorInsufficientResources, + "Pipe creation failed"); + +#endif + + // Copying component Name - this will be picked up in the proxy common + PROXY_assert(strlen(COMPONENT_NAME) + 1 < MAX_COMPONENT_NAME_LENGTH, + OMX_ErrorInvalidComponentName, + "Length of component name is longer than the max allowed"); + TIMM_OSAL_Memcpy(pComponentPrivate->cCompName, COMPONENT_NAME, + strlen(COMPONENT_NAME) + 1); + + eError = OMX_ProxyCommonInit(hComponent); // Calling Proxy Common Init() +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES + pHandle->SetParameter = LOCAL_PROXY_MPEG4E_SetParameter; + pHandle->GetParameter = LOCAL_PROXY_MPEG4E_GetParameter; +#endif + pHandle->ComponentDeInit = LOCAL_PROXY_MPEG4E_ComponentDeInit; + pHandle->FreeBuffer = LOCAL_PROXY_MPEG4E_FreeBuffer; + pHandle->AllocateBuffer = LOCAL_PROXY_MPEG4E_AllocateBuffer; + + pComponentPrivate->IsLoadedState = OMX_TRUE; + pHandle->EmptyThisBuffer = LOCAL_PROXY_MPEG4E_EmptyThisBuffer; + pHandle->GetExtensionIndex = LOCAL_PROXY_MPEG4E_GetExtensionIndex; + + if(mEnableVFR) + pHandle->EmptyThisBuffer = ComponentPrivateEmptyThisBuffer; + + EXIT: + if (eError != OMX_ErrorNone) + { + DOMX_DEBUG("Error in Initializing Proxy"); + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + if(pProxy->hBufPipe != NULL) + { + TIMM_OSAL_DeletePipe(pProxy->hBufPipe); + pProxy->hBufPipe = NULL; + } + + if(pComponentPrivate->pCompProxyPrv != NULL) + { + TIMM_OSAL_Free(pComponentPrivate->pCompProxyPrv); + pComponentPrivate->pCompProxyPrv = NULL; + pProxy = NULL; + } +#endif + if (pComponentPrivate->cCompName != NULL) + { + TIMM_OSAL_Free(pComponentPrivate->cCompName); + pComponentPrivate->cCompName = NULL; + } + if (pComponentPrivate != NULL) + { + TIMM_OSAL_Free(pComponentPrivate); + pComponentPrivate = NULL; + } + } + return eError; +} + +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES + +/* ===========================================================================*/ +/** + * @name PROXY_MPEG4E_GetParameter() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_GetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PARAM_PORTDEFINITIONTYPE* pPortDef = NULL; + OMX_VIDEO_PARAM_PORTFORMATTYPE* pPortParam = NULL; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; +#endif + + PROXY_require((pParamStruct != NULL), OMX_ErrorBadParameter, NULL); + PROXY_assert((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pCompPrv->pCompProxyPrv; +#endif + + DOMX_ENTER + ("hComponent = %p, pCompPrv = %p, nParamIndex = %d, pParamStruct = %p", + hComponent, pCompPrv, nParamIndex, pParamStruct); + + eError = PROXY_GetParameter(hComponent,nParamIndex, pParamStruct); + + if(nParamIndex == OMX_IndexParamPortDefinition) + { + pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct; + + if(pPortDef->format.video.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar) + { +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + if(pProxy->bAndroidOpaqueFormat == OMX_TRUE) + { + pPortDef->format.video.eColorFormat = OMX_COLOR_FormatAndroidOpaque; + } + else +#endif + { + pPortDef->format.video.eColorFormat = OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; + } + } + } + else if (nParamIndex == OMX_IndexParamVideoPortFormat) + { + pPortParam = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pParamStruct; + + if((eError == OMX_ErrorNone) && + (pPortParam->eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar)) + { + pPortParam->eColorFormat = OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; + } +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + else if ((eError == OMX_ErrorNoMore) && (pPortParam->nIndex == 1)) + { + /* HACK:Remote OMX-MPEG4E supports only 1 color format (index 0). The + * OMX_COLOR_FormatAndroidOpaque is supported only at the proxy. + * Call GetParameter() to fill in defaults for parameters and + * override color format and index for the additional + * OMX_COLOR_FormatAndroidOpaque support*/ + pPortParam->nIndex = 0; + eError = PROXY_GetParameter(hComponent, nParamIndex, pParamStruct); + pPortParam->nIndex = 1; + pPortParam->eColorFormat = OMX_COLOR_FormatAndroidOpaque; + eError = OMX_ErrorNone; + } +#endif + } + + PROXY_assert((eError == OMX_ErrorNone) || (eError == OMX_ErrorNoMore), + eError," Error in Proxy GetParameter"); + + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +/* ===========================================================================*/ +/** + * @name PROXY_MPEG4E_SetParameter() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_SetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_IN OMX_PTR pParamStruct) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PARAM_PORTDEFINITIONTYPE* pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct; + OMX_VIDEO_PARAM_PORTFORMATTYPE* pPortParams = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pParamStruct; + OMX_VIDEO_STOREMETADATAINBUFFERSPARAMS* pStoreMetaData = (OMX_VIDEO_STOREMETADATAINBUFFERSPARAMS *) pParamStruct; + OMX_TI_PARAM_BUFFERPREANNOUNCE tParamSetNPA; + OMX_PARAM_PORTDEFINITIONTYPE sPortDef; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; +#endif + + DOMX_ENTER + ("hComponent = %p, pCompPrv = %p, nParamIndex = %d, pParamStruct = %p", + hComponent, pCompPrv, nParamIndex, pParamStruct); + + PROXY_require((pParamStruct != NULL), OMX_ErrorBadParameter, NULL); + PROXY_require((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pCompPrv->pCompProxyPrv; +#endif + + if(nParamIndex == OMX_IndexParamPortDefinition) + { + if(pPortDef->format.video.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) + { + pPortDef->format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + else if(pPortDef->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) + { + if(COLORCONVERT_open(&pProxy->hCC,pCompPrv) != 0) + { + PROXY_assert(0, OMX_ErrorInsufficientResources, + "Failed to open Color converting service"); + } + pProxy->bAndroidOpaqueFormat = OMX_TRUE; + pPortDef->format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } +#endif + } + else if(nParamIndex == OMX_IndexParamVideoPortFormat) + { + if(pPortParams->eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) + { + pPortParams->eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + else if(pPortParams->eColorFormat == OMX_COLOR_FormatAndroidOpaque) + { + if(COLORCONVERT_open(&pProxy->hCC,pCompPrv) != 0) + { + PROXY_assert(0, OMX_ErrorInsufficientResources, + "Failed to open Color converting service"); + } + pProxy->bAndroidOpaqueFormat = OMX_TRUE; + pPortParams->eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } +#endif + } + else if(nParamIndex == (OMX_INDEXTYPE) OMX_TI_IndexEncoderStoreMetadatInBuffers) + { + DOMX_DEBUG("Moving to Metadatamode"); + if (pStoreMetaData->nPortIndex == OMX_MPEG4E_INPUT_PORT && pStoreMetaData->bStoreMetaData == OMX_TRUE) + { + tParamSetNPA.nSize = sizeof(OMX_TI_PARAM_BUFFERPREANNOUNCE); + tParamSetNPA.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + tParamSetNPA.nVersion.s.nVersionMinor = OMX_VER_MINOR; + tParamSetNPA.nVersion.s.nRevision = 0x0; + tParamSetNPA.nVersion.s.nStep = 0x0; + tParamSetNPA.nPortIndex = OMX_MPEG4E_INPUT_PORT; + tParamSetNPA.bEnabled = OMX_TRUE; + //Call NPA on OMX encoder on ducati. + PROXY_SetParameter(hComponent,OMX_TI_IndexParamBufferPreAnnouncement, &tParamSetNPA); + pCompPrv->proxyPortBuffers[pStoreMetaData->nPortIndex].proxyBufferType = EncoderMetadataPointers; + DOMX_DEBUG("Moving to Metadatamode done"); + + /*Initializing Structure */ + sPortDef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + sPortDef.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + sPortDef.nVersion.s.nVersionMinor = OMX_VER_MINOR; + sPortDef.nVersion.s.nRevision = 0x0; + sPortDef.nVersion.s.nStep = 0x0; + sPortDef.nPortIndex = OMX_MPEG4E_INPUT_PORT; + + eError = PROXY_GetParameter(hComponent,OMX_IndexParamPortDefinition, &sPortDef); + PROXY_assert(eError == OMX_ErrorNone, eError," Error in Proxy GetParameter for Port Def"); + + sPortDef.format.video.nStride = LINUX_PAGE_SIZE; + + eError = PROXY_SetParameter(hComponent,OMX_IndexParamPortDefinition, &sPortDef); + + PROXY_assert(eError == OMX_ErrorNone, eError," Error in Proxy SetParameter for Port Def"); + } + goto EXIT; + } + + eError = PROXY_SetParameter(hComponent, nParamIndex, pParamStruct); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy SetParameter"); + + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +#endif + + +/* ===========================================================================*/ +/** + * @name PROXY_GetExtensionIndex() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, OMX_OUT OMX_INDEXTYPE * pIndexType) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = hComponent; + + PROXY_require((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + PROXY_require(cParameterName != NULL, OMX_ErrorBadParameter, NULL); + PROXY_require(pIndexType != NULL, OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + DOMX_ENTER("%s hComponent = %p, pCompPrv = %p, cParameterName = %s", + __FUNCTION__,hComponent, pCompPrv, cParameterName); + + // Check for NULL Parameters + PROXY_require((cParameterName != NULL && pIndexType != NULL), + OMX_ErrorBadParameter, NULL); + + // Ensure that String length is not greater than Max allowed length + PROXY_require(strlen(cParameterName) <= 127, OMX_ErrorBadParameter, NULL); + + if(strcmp(cParameterName, "OMX.google.android.index.storeMetaDataInBuffers") == 0) + { + // If Index type is 2D Buffer Allocated Dimension + *pIndexType = (OMX_INDEXTYPE) OMX_TI_IndexEncoderStoreMetadatInBuffers; + goto EXIT; + } + + eError = PROXY_GetExtensionIndex(hComponent, cParameterName, pIndexType); + + EXIT: + DOMX_EXIT("%s eError: %d",__FUNCTION__, eError); + return eError; +} + +/* ===========================================================================*/ +/** + * @name PROXY_MPEG4E_EmptyThisBuffer() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PTR pBufferOrig = NULL; + OMX_U32 nStride = 0, nNumLines = 0; + OMX_PARAM_PORTDEFINITIONTYPE tParamStruct; + OMX_U32 nFilledLen, nAllocLen; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + OMX_U32 nBufIndex = 0, nSize=0, nRet=0; +#endif +#ifdef ENABLE_GRALLOC_BUFFER + OMX_PTR pAuxBuf0 = NULL, pAuxBuf1 = NULL; + RPC_OMX_ERRORTYPE eRPCError = RPC_OMX_ErrorNone; + OMX_ERRORTYPE eCompReturn = OMX_ErrorNone; +#endif + + PROXY_require(pBufferHdr != NULL, OMX_ErrorBadParameter, NULL); + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + PROXY_CHK_VERSION(pBufferHdr, OMX_BUFFERHEADERTYPE); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pCompPrv->pCompProxyPrv; +#endif + + tParamStruct.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + tParamStruct.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + tParamStruct.nVersion.s.nVersionMinor = OMX_VER_MINOR; + tParamStruct.nVersion.s.nRevision = 0x0; + tParamStruct.nVersion.s.nStep = 0x0; + tParamStruct.nPortIndex = OMX_MPEG4E_INPUT_PORT; + + eError = PROXY_GetParameter(hComponent, OMX_IndexParamPortDefinition, &tParamStruct); + PROXY_require(eError == OMX_ErrorNone, OMX_ErrorBadParameter, "Error is Get Parameter for port def"); + nFilledLen = pBufferHdr->nFilledLen; + nAllocLen = pBufferHdr->nAllocLen; + if(nFilledLen != 0) + { + pBufferHdr->nFilledLen = tParamStruct.nBufferSize; + } + pBufferHdr->nAllocLen = tParamStruct.nBufferSize; + + DOMX_DEBUG + ("%s hComponent=%p, pCompPrv=%p, nFilledLen=%d, nOffset=%d, nFlags=%08x", + __FUNCTION__,hComponent, pCompPrv, pBufferHdr->nFilledLen, + pBufferHdr->nOffset, pBufferHdr->nFlags); + + if( pCompPrv->proxyPortBuffers[OMX_MPEG4E_INPUT_PORT].proxyBufferType == EncoderMetadataPointers + && nFilledLen != 0) + { + OMX_U32 *pTempBuffer; + OMX_U32 nMetadataBufferType; + DOMX_DEBUG("Passing meta data to encoder"); + + pBufferOrig = pBufferHdr->pBuffer; + + pTempBuffer = (OMX_U32 *) (pBufferHdr->pBuffer); + nMetadataBufferType = *pTempBuffer; + + if(nMetadataBufferType == kMetadataBufferTypeCameraSource) + { +#ifdef ENABLE_GRALLOC_BUFFER + IMG_native_handle_t* pGrallocHandle; + video_metadata_t* pVideoMetadataBuffer; + DOMX_DEBUG("MetadataBufferType is kMetadataBufferTypeCameraSource"); + + pVideoMetadataBuffer = (video_metadata_t*) ((OMX_U32 *)(pBufferHdr->pBuffer)); + pGrallocHandle = (IMG_native_handle_t*) (pVideoMetadataBuffer->handle); + DOMX_DEBUG("Grallloc buffer recieved in metadata buffer 0x%x",pGrallocHandle ); + + pBufferHdr->pBuffer = (OMX_U8 *)(pGrallocHandle->fd[0]); + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)-> + pAuxBuf1 = (OMX_PTR) pGrallocHandle->fd[1]; + DOMX_DEBUG("%s Gralloc=0x%x, Y-fd=%d, UV-fd=%d", __FUNCTION__, pGrallocHandle, + pGrallocHandle->fd[0], pGrallocHandle->fd[1]); + + pBufferHdr->nOffset = pVideoMetadataBuffer->offset; +#endif + } + else if(nMetadataBufferType == kMetadataBufferTypeGrallocSource) + { +#ifdef ENABLE_GRALLOC_BUFFER + IMG_native_handle_t* pGrallocHandle; + buffer_handle_t tBufHandle; + DOMX_DEBUG("MetadataBufferType is kMetadataBufferTypeGrallocSource"); + + pTempBuffer++; + tBufHandle = *((buffer_handle_t *)pTempBuffer); + pGrallocHandle = (IMG_native_handle_t*) tBufHandle; + DOMX_DEBUG("Grallloc buffer recieved in metadata buffer 0x%x",pGrallocHandle ); + + pBufferHdr->pBuffer = (OMX_U8 *)(pGrallocHandle->fd[0]); + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)-> + pAuxBuf1 = (OMX_PTR) pGrallocHandle->fd[1]; + DOMX_DEBUG("%s Gralloc=0x%x, Y-fd=%d, UV-fd=%d", __FUNCTION__, pGrallocHandle, + pGrallocHandle->fd[0], pGrallocHandle->fd[1]); +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + if (pProxy->bAndroidOpaqueFormat) + { + DOMX_DEBUG(" ++TIMM_OSAL_ReadFromPipe() "); + /* Dequeue NV12 buffer for encoder */ + eOSALStatus = TIMM_OSAL_ReadFromPipe(pProxy->hBufPipe, &nBufIndex, + sizeof(OMX_PTR), (TIMM_OSAL_U32 *)(&nSize), + TIMM_OSAL_SUSPEND); + PROXY_assert(eOSALStatus == TIMM_OSAL_ERR_NONE, OMX_ErrorBadParameter, NULL); + + /* Get NV12 data after colorconv*/ + nRet = COLORCONVERT_PlatformOpaqueToNV12(pProxy->hCC, (void **) &pGrallocHandle, (void **) &pProxy->gralloc_handle[nBufIndex], + pGrallocHandle->iWidth, + pGrallocHandle->iHeight, + 4096, COLORCONVERT_BUFTYPE_GRALLOCOPAQUE, + COLORCONVERT_BUFTYPE_GRALLOCOPAQUE ); + if(nRet != 0) + { + eOSALStatus = TIMM_OSAL_WriteToPipe(pProxy->hBufPipe, (void *) &nBufIndex, + sizeof(OMX_U32), TIMM_OSAL_SUSPEND); + PROXY_assert(0, OMX_ErrorBadParameter, "Color conversion routine failed"); + } + DOMX_DEBUG(" --COLORCONVERT_PlatformOpaqueToNV12() "); + + /* Update pBufferHdr with NV12 buffers for OMX component */ + pBufferHdr->pBuffer= (OMX_U8 *)(pProxy->gralloc_handle[nBufIndex]->fd[0]); + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)->pAuxBuf1 = (OMX_PTR)(pProxy->gralloc_handle[nBufIndex]->fd[1]); + } +#endif +#endif + } + else + { + return OMX_ErrorBadParameter; + } +#ifdef ENABLE_GRALLOC_BUFFER + eRPCError = RPC_RegisterBuffer(pCompPrv->hRemoteComp, pBufferHdr->pBuffer, + &pAuxBuf0, &pAuxBuf1, + GrallocPointers); + PROXY_checkRpcError(); + if (pAuxBuf0) + pBufferHdr->pBuffer = pAuxBuf0; + if (pAuxBuf1) + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)->pAuxBuf1 = pAuxBuf1; +#endif + } + + eError = PROXY_EmptyThisBuffer(hComponent, pBufferHdr); +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT + if (pProxy->bAndroidOpaqueFormat) + { + /*Write buffer to end of pipe for re-circulation for future ETB()*/ + eOSALStatus = TIMM_OSAL_WriteToPipe(pProxy->hBufPipe, (void *) &nBufIndex, + sizeof(OMX_U32), TIMM_OSAL_SUSPEND); + PROXY_assert(eOSALStatus == TIMM_OSAL_ERR_NONE, OMX_ErrorBadParameter, "Pipe write failed"); + } +#endif + + if( pCompPrv->proxyPortBuffers[pBufferHdr->nInputPortIndex].proxyBufferType == EncoderMetadataPointers) { + pBufferHdr->pBuffer = pBufferOrig; +#ifdef ENABLE_GRALLOC_BUFFER + RPC_UnRegisterBuffer(pCompPrv->hRemoteComp, pAuxBuf0); + RPC_UnRegisterBuffer(pCompPrv->hRemoteComp, pAuxBuf1); +#endif + } + EXIT: + return eError; +} + +#ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT +static OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_AllocateBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE ** ppBufferHdr, OMX_U32 nPortIndex, + OMX_PTR pAppPrivate, OMX_U32 nSizeBytes) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_CONFIG_RECTTYPE tParamRect; + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + DOMX_DEBUG(" ++LOCAL_PROXY_MPEG4E_AllocateBuffer"); + int err, nStride; + + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pCompPrv->pCompProxyPrv; + + if((nPortIndex == OMX_MPEG4E_INPUT_PORT) && + (pProxy->bAndroidOpaqueFormat)) + { + tParamRect.nSize = sizeof(OMX_CONFIG_RECTTYPE); + tParamRect.nVersion.s.nVersionMajor = 1; + tParamRect.nVersion.s.nVersionMinor = 1; + tParamRect.nVersion.s.nRevision = 0; + tParamRect.nVersion.s.nStep = 0; + tParamRect.nPortIndex = nPortIndex; + + eError = PROXY_GetParameter(hComponent, (OMX_INDEXTYPE)OMX_TI_IndexParam2DBufferAllocDimension, &tParamRect); + PROXY_assert(eError == OMX_ErrorNone, eError," Error in Proxy GetParameter from 2d index in allocate buffer"); + + err = pProxy->mAllocDev->alloc(pProxy->mAllocDev,(int) tParamRect.nWidth,(int) tParamRect.nHeight, + (int) HAL_PIXEL_FORMAT_TI_NV12,(int) GRALLOC_USAGE_HW_RENDER, + (const struct native_handle_t **)(&(pProxy->gralloc_handle[pProxy->nCurBufIndex])), &nStride); + } + + eError = PROXY_AllocateBuffer(hComponent, ppBufferHdr, nPortIndex, + pAppPrivate, nSizeBytes); +EXIT: + if((nPortIndex == OMX_MPEG4E_INPUT_PORT) && + (pProxy->bAndroidOpaqueFormat)) + { + if(eError != OMX_ErrorNone) + { + err = pProxy->mAllocDev->free(pProxy->mAllocDev, (buffer_handle_t)(pProxy->gralloc_handle[pProxy->nCurBufIndex])); + } + else + { + /*Populate buffer to pipe*/ + eOSALStatus = TIMM_OSAL_WriteToPipe(pProxy->hBufPipe, (void *) &pProxy->nCurBufIndex, + sizeof(OMX_U32), TIMM_OSAL_SUSPEND); + pProxy->nCurBufIndex++; + } + } + DOMX_DEBUG(" --LOCAL_PROXY_MPEG4E_AllocateBuffer"); + return eError; +} + +static OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_FreeBuffer(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, OMX_IN OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_U32 nBufIndex, nSize, nCount=0; + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; + + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pCompPrv->pCompProxyPrv; + + if((nPortIndex == OMX_MPEG4E_INPUT_PORT) && + (pProxy->bAndroidOpaqueFormat)) + { + pProxy->nCurBufIndex--; + PROXY_require(pProxy->nCurBufIndex >=0, + OMX_ErrorBadParameter, "Buffer index underflow"); + + if(pProxy->gralloc_handle[pProxy->nCurBufIndex]) + { + pProxy->mAllocDev->free(pProxy->mAllocDev, (buffer_handle_t)(pProxy->gralloc_handle[pProxy->nCurBufIndex])); + pProxy->gralloc_handle[pProxy->nCurBufIndex] = NULL; + } + + /*Clear the Bufindex pipe by dummy reads*/ + TIMM_OSAL_GetPipeReadyMessageCount(pProxy->hBufPipe, (TIMM_OSAL_U32 *)&nCount); + if(nCount) + { + TIMM_OSAL_ReadFromPipe(pProxy->hBufPipe, &nBufIndex, + sizeof(OMX_PTR), (TIMM_OSAL_U32 *)&nSize, TIMM_OSAL_NO_SUSPEND); + } + } + + eError = PROXY_FreeBuffer(hComponent, nPortIndex, pBufferHdr); + +EXIT: + return eError; +} + +OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_ComponentDeInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; + TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; + OMX_U32 i; + + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pCompPrv->pCompProxyPrv; + + if(pProxy->hBufPipe != NULL) + { + eOSALStatus = TIMM_OSAL_DeletePipe(pProxy->hBufPipe); + pProxy->hBufPipe = NULL; + + if(eOSALStatus != TIMM_OSAL_ERR_NONE) + { + DOMX_ERROR("Pipe deletion failed"); + } + } + + if(pProxy->bAndroidOpaqueFormat == OMX_TRUE) + { + /* Cleanup internal buffers in pipe if not freed on FreeBuffer */ + for(i=0; i<OMX_MPEG4E_NUM_INTERNAL_BUF; i++) + { + if(pProxy->gralloc_handle[i]) + { + pProxy->mAllocDev->free(pProxy->mAllocDev, (buffer_handle_t)(pProxy->gralloc_handle[i])); + pProxy->gralloc_handle[i] = NULL; + } + } + + COLORCONVERT_close(pProxy->hCC,pCompPrv); + pProxy->bAndroidOpaqueFormat = OMX_FALSE; + + if(pCompPrv->pCompProxyPrv != NULL) + { + TIMM_OSAL_Free(pCompPrv->pCompProxyPrv); + pCompPrv->pCompProxyPrv = NULL; + } + } + + eError = PROXY_ComponentDeInit(hComponent); +EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +int COLORCONVERT_open(void **hCC, PROXY_COMPONENT_PRIVATE *pCompPrv) +{ + int nErr = -1; + hw_module_t const* module = NULL; + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; + + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pCompPrv->pCompProxyPrv; + nErr = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + + if (nErr == 0) + { + *hCC = (void *) ((IMG_gralloc_module_public_t const *)module); + } + else + { + DOMX_ERROR("FATAL: gralloc api hw_get_module() returned error: Can't find \ + %s module err = %x", GRALLOC_HARDWARE_MODULE_ID, nErr); + } + + gralloc_open(module, &(pProxy->mAllocDev)); + + return nErr; +} + +int COLORCONVERT_PlatformOpaqueToNV12(void *hCC, + void *pSrc[COLORCONVERT_MAX_SUB_BUFFERS], + void *pDst[COLORCONVERT_MAX_SUB_BUFFERS], + int nWidth, int nHeight, int nStride, + int nSrcBufType,int nDstBufType) +{ + IMG_gralloc_module_public_t const* module = hCC; + int nErr = -1; + + if((nSrcBufType == COLORCONVERT_BUFTYPE_GRALLOCOPAQUE) && (nDstBufType == COLORCONVERT_BUFTYPE_VIRTUAL)) + { + nErr = module->Blit(module, pSrc[0], pDst, HAL_PIXEL_FORMAT_TI_NV12); + + } + else if((nSrcBufType == COLORCONVERT_BUFTYPE_GRALLOCOPAQUE) && (nDstBufType == COLORCONVERT_BUFTYPE_GRALLOCOPAQUE )) + { + nErr = module->Blit2(module, pSrc[0], pDst[0], nWidth, nHeight, 0, 0); + } + + return nErr; +} + +int COLORCONVERT_close(void *hCC,PROXY_COMPONENT_PRIVATE *pCompPrv) +{ + OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; + pProxy = (OMX_PROXY_MPEG4E_PRIVATE *) pCompPrv->pCompProxyPrv; + if(pProxy && pProxy->mAllocDev) + { + gralloc_close(pProxy->mAllocDev); + } + return 0; +} +#endif diff --git a/domx/omx_proxy_component/omx_sample/Makefile b/domx/omx_proxy_component/omx_sample/Makefile new file mode 100755 index 0000000..499d1a6 --- /dev/null +++ b/domx/omx_proxy_component/omx_sample/Makefile @@ -0,0 +1,103 @@ +# +# Copyright (C) Texas Instruments - http://www.ti.com/ +# +# 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. +# +# ---------------------------------------------------------------------------- +# Revision History +# +# +# REF=ORG +# Original version. +# ---------------------------------------------------------------------------- + + + +include $(PROJROOT)/make/start.mk + +# Do not change above "include" line(s) + +# Arguments to tools, will move to make system once finalized. + +CFLAGS = +CDEFS = +ifeq ($(BUILD),udeb) +CDEFS += DEBUG +endif +CDEFS += + +EXEC_ARGS = +ST_LIB_ARGS = +SH_LIB_ARGS = + +# Define this macro if target runs in kernel mode +#__KERNEL__ = 1 + +# Target name and extension +# static library (ST_LIB): filename.a +# shared library soname (SH_LIB): filename.so.maj_ver.min_ver +# executable (EXEC) : filename.out + +TARGETNAME = libOMX.TI.DUCATI1.MISC.SAMPLE.so + + +# TARGETTYPE must be EXEC, ST_LIB or SH_LIB in upper case. + +TARGETTYPE = SH_LIB + +# install directory relative to the HOSTTARGET directory +HOSTRELEASE = lib + +# install directory relative to the root filesystem +ROOTFSRELEASE = lib + +# Folders in which gmake will run before building current target + +SUBMODULES = \ + +# Filename must not begin with '.', '/' or '\' + +SOURCES = \ +src/omx_proxy_sample.c \ + + + +# Search path for include files + +INCLUDES = \ + $(PROJROOT)/omx_core/inc \ + $(PROJROOT)/mm_osal/inc \ + $(PROJROOT)/domx \ + $(PROJROOT)/domx/omx_rpc/inc \ + + +# Libraries needed for linking. + +ST_LIBS = +#mm_osal domx +SH_LIBS = domx omx_core mm_osal +#pthread rt utils procmgr ipc rcm notify +#SH_LIBS += sysmgr sysmemmgr + + +# Search path for library (and linker command) files. +# Current folder and target folder are included by default. + +LIBINCLUDES = $(PROJROOT)/mm_osal \ + $(PROJROOT)/domx \ + $(PROJROOT)/omx_core + + +# Do not change below "include" line(s) + +include $(PROJROOT)/make/build.mk diff --git a/domx/omx_proxy_component/omx_sample/src/omx_proxy_sample.c b/domx/omx_proxy_component/omx_sample/src/omx_proxy_sample.c new file mode 100755 index 0000000..b270186 --- /dev/null +++ b/domx/omx_proxy_component/omx_sample/src/omx_proxy_sample.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2010, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file omx_proxy_sample.c + * This file contains methods that provides the functionality for + * the OpenMAX1.1 DOMX Framework Tunnel Proxy component. + ********************************************************************************************* + This is the proxy specific wrapper that passes the component name to the generic proxy init() + The proxy wrapper also does some runtime/static time onfig on per proxy basis + This is a thin wrapper that is called when componentiit() of the proxy is called + static OMX_ERRORTYPE PROXY_Wrapper_init(OMX_HANDLETYPE hComponent, OMX_PTR pAppData); + this layer gets called first whenever a proxy s get handle is called + ************************************************************************************************ + * @path WTSD_DucatiMMSW\omx\omx_il_1_x\omx_proxy_component\src + * + * @rev 1.0 + */ + +/*============================================================== + *! Revision History + *! ============================ + *! 19-August-2009 B Ravi Kiran ravi.kiran@ti.com: Initial Version + *================================================================*/ + +/****************************************************************** + * INCLUDE FILES + ******************************************************************/ +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include "omx_proxy_common.h" +#include <timm_osal_interfaces.h> +//change to ducati1 later +#define COMPONENT_NAME "OMX.TI.DUCATI1.MISC.SAMPLE" // needs to be specific for every configuration wrapper + +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *pHandle = NULL; + PROXY_COMPONENT_PRIVATE *pComponentPrivate; + pHandle = (OMX_COMPONENTTYPE *) hComponent; + + DOMX_DEBUG + ("_____________________INSISDE PROXY WRAPPER__________________________\n"); + + pHandle->pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) + TIMM_OSAL_Malloc(sizeof(PROXY_COMPONENT_PRIVATE), TIMM_OSAL_TRUE, + 0, TIMMOSAL_MEM_SEGMENT_INT); + + pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate; + if (pHandle->pComponentPrivate == NULL) + { + DOMX_DEBUG + (" ERROR IN ALLOCATING PROXY COMPONENT PRIVATE STRUCTURE"); + eError = OMX_ErrorInsufficientResources; + goto EXIT; + } + pComponentPrivate->cCompName = + TIMM_OSAL_Malloc(MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8), + TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT); + // Copying component Name - this will be picked up in the proxy common + assert(strlen(COMPONENT_NAME) + 1 < MAX_COMPONENT_NAME_LENGTH); + TIMM_OSAL_Memcpy(pComponentPrivate->cCompName, COMPONENT_NAME, + strlen(COMPONENT_NAME) + 1); + eError = OMX_ProxyCommonInit(hComponent); // Calling Proxy Common Init() + + if (eError != OMX_ErrorNone) + { + DOMX_DEBUG("\Error in Initializing Proxy"); + TIMM_OSAL_Free(pComponentPrivate->cCompName); + TIMM_OSAL_Free(pComponentPrivate); + } + + + EXIT: + return eError; +} diff --git a/domx/omx_proxy_component/omx_video_dec/Makefile b/domx/omx_proxy_component/omx_video_dec/Makefile new file mode 100755 index 0000000..cbe5c56 --- /dev/null +++ b/domx/omx_proxy_component/omx_video_dec/Makefile @@ -0,0 +1,103 @@ +# +# Copyright (C) Texas Instruments - http://www.ti.com/ +# +# 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. +# +# ---------------------------------------------------------------------------- +# Revision History +# +# +# REF=ORG +# Original version. +# ---------------------------------------------------------------------------- + + + +include $(PROJROOT)/make/start.mk + +# Do not change above "include" line(s) + +# Arguments to tools, will move to make system once finalized. + +CFLAGS = +CDEFS = +ifeq ($(BUILD),udeb) +CDEFS += DEBUG +endif +CDEFS += + +EXEC_ARGS = +ST_LIB_ARGS = +SH_LIB_ARGS = + +# Define this macro if target runs in kernel mode +#__KERNEL__ = 1 + +# Target name and extension +# static library (ST_LIB): filename.a +# shared library soname (SH_LIB): filename.so.maj_ver.min_ver +# executable (EXEC) : filename.out + +TARGETNAME = libOMX.TI.DUCATI1.VIDEO.DECODER.so + + +# TARGETTYPE must be EXEC, ST_LIB or SH_LIB in upper case. + +TARGETTYPE = SH_LIB + +# install directory relative to the HOSTTARGET directory +HOSTRELEASE = lib + +# install directory relative to the root filesystem +ROOTFSRELEASE = lib + +# Folders in which gmake will run before building current target + +SUBMODULES = \ + +# Filename must not begin with '.', '/' or '\' + +SOURCES = \ +src/omx_proxy_videodec.c \ + + + +# Search path for include files + +INCLUDES = \ + $(PROJROOT)/omx_core/inc \ + $(PROJROOT)/mm_osal/inc \ + $(PROJROOT)/domx \ + $(PROJROOT)/domx/omx_rpc/inc \ + + +# Libraries needed for linking. + +ST_LIBS = +#mm_osal domx +SH_LIBS = domx omx_core mm_osal +#pthread rt utils procmgr ipc rcm notify +#SH_LIBS += sysmgr sysmemmgr + + +# Search path for library (and linker command) files. +# Current folder and target folder are included by default. + +LIBINCLUDES = $(PROJROOT)/mm_osal \ + $(PROJROOT)/domx \ + $(PROJROOT)/omx_core + + +# Do not change below "include" line(s) + +include $(PROJROOT)/make/build.mk diff --git a/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec.c b/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec.c new file mode 100755 index 0000000..8ac4c9d --- /dev/null +++ b/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec.c @@ -0,0 +1,797 @@ +/* + * Copyright (c) 2010, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file omx_proxy_videodecoder.c + * This file contains methods that provides the functionality for + * the OpenMAX1.1 DOMX Framework Tunnel Proxy component. + ********************************************************************************************* + This is the proxy specific wrapper that passes the component name to the generic proxy init() + The proxy wrapper also does some runtime/static time onfig on per proxy basis + This is a thin wrapper that is called when componentiit() of the proxy is called + static OMX_ERRORTYPE PROXY_Wrapper_init(OMX_HANDLETYPE hComponent, OMX_PTR pAppData); + this layer gets called first whenever a proxy's get handle is called + ************************************************************************************************ + * @path WTSD_DucatiMMSW\omx\omx_il_1_x\omx_proxy_component\src + * + * @rev 1.0 + */ + +/*============================================================== + *! Revision History + *! ============================ + *! 20-August-2010 Sarthak Aggarwal sarthak@ti.com: Initial Version + *================================================================*/ + +/****************************************************************** + * INCLUDE FILES + ******************************************************************/ +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include "omx_proxy_common.h" +#include <timm_osal_interfaces.h> +#include "OMX_TI_IVCommon.h" +#include "OMX_TI_Video.h" +#include "OMX_TI_Index.h" + +#ifdef ENABLE_RAW_BUFFERS_DUMP_UTILITY +#define LOG_TAG "OMXPROXYVIDEODEC" +#include <fcntl.h> +#include <cutils/properties.h> +#include <utils/Log.h> +#endif + +#define COMPONENT_NAME "OMX.TI.DUCATI1.VIDEO.DECODER" +/* needs to be specific for every configuration wrapper */ + +#ifdef USE_ENHANCED_PORTRECONFIG +//Define port indices in video decoder proxy +#define OMX_VIDEODECODER_INPUT_PORT 0 +#define OMX_VIDEODECODER_OUTPUT_PORT 1 +#endif + +#ifdef SET_STRIDE_PADDING_FROM_PROXY + +#define LINUX_PAGE_SIZE (4 * 1024) +#define TOTAL_DEC_PORTS 2 +#define HAL_NV12_PADDED_PIXEL_FORMAT (OMX_TI_COLOR_FormatYUV420PackedSemiPlanar - OMX_COLOR_FormatVendorStartUnused) + +static OMX_ERRORTYPE RPC_UTIL_SetStrideAndPadding(OMX_COMPONENTTYPE * hRemoteComp, PROXY_COMPONENT_PRIVATE * pCompPrv); + +OMX_ERRORTYPE PROXY_VIDDEC_SendCommand(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE eCmd, + OMX_IN OMX_U32 nParam, OMX_IN OMX_PTR pCmdData); + +OMX_ERRORTYPE PROXY_VIDDEC_EventHandler(OMX_HANDLETYPE hComponent, + OMX_PTR pAppData, OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2, + OMX_PTR pEventData); + +#endif //SET_STRIDE_PADDING_FROM_PROXY + +OMX_ERRORTYPE PROXY_VIDDEC_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, OMX_OUT OMX_INDEXTYPE * pIndexType); + +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES + +OMX_ERRORTYPE PROXY_VIDDEC_GetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct); + +OMX_ERRORTYPE PROXY_VIDDEC_SetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct); + +#endif + +#ifdef ANDROID_QUIRK_LOCK_BUFFER +#include <hardware/gralloc.h> +#include <hardware/hardware.h> +#include "hal_public.h" + +OMX_ERRORTYPE PROXY_VIDDEC_FillThisBuffer(OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE * pBufferHdr); +OMX_ERRORTYPE PROXY_VIDDEC_FillBufferDone(OMX_HANDLETYPE hComponent, + OMX_U32 remoteBufHdr, OMX_U32 nfilledLen, OMX_U32 nOffset, OMX_U32 nFlags, + OMX_TICKS nTimeStamp, OMX_HANDLETYPE hMarkTargetComponent, + OMX_PTR pMarkData); + +#endif +extern OMX_ERRORTYPE PrearrageEmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr); + +#ifdef ENABLE_RAW_BUFFERS_DUMP_UTILITY +extern void DumpVideoFrame(DebugFrame_Dump *frameInfo); +#endif + +OMX_ERRORTYPE OMX_ProxyViddecInit(OMX_HANDLETYPE hComponent); + +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *pHandle = NULL; + PROXY_COMPONENT_PRIVATE *pComponentPrivate = NULL; + pHandle = (OMX_COMPONENTTYPE *) hComponent; + + DOMX_ENTER(""); + + DOMX_DEBUG("Component name provided is %s", COMPONENT_NAME); + + pHandle->pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) + TIMM_OSAL_Malloc(sizeof(PROXY_COMPONENT_PRIVATE), TIMM_OSAL_TRUE, + 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pHandle->pComponentPrivate != NULL, + OMX_ErrorInsufficientResources, + "ERROR IN ALLOCATING PROXY COMPONENT PRIVATE STRUCTURE"); + + pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate; + + TIMM_OSAL_Memset(pComponentPrivate, 0, + sizeof(PROXY_COMPONENT_PRIVATE)); + + pComponentPrivate->cCompName = + TIMM_OSAL_Malloc(MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8), + TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pComponentPrivate->cCompName != NULL, + OMX_ErrorInsufficientResources, + " Error in Allocating space for proxy component table"); + + eError = OMX_ProxyViddecInit(hComponent); + +#ifdef ENABLE_RAW_BUFFERS_DUMP_UTILITY + if (eError == OMX_ErrorNone) + { + char value[PROPERTY_VALUE_MAX]; + property_get("debug.video.dumpframe", value, "0:0"); + /* -ve value for fromFrame would disable this automatically */ + pComponentPrivate->debugframeInfo.fromFrame = atoi(strtok(value, ":")); + pComponentPrivate->debugframeInfo.toFrame = atoi(strtok(NULL, ":")); + pComponentPrivate->debugframeInfo.runningFrame = pComponentPrivate->debugframeInfo.fromFrame; + } +#endif + EXIT: + if (eError != OMX_ErrorNone) + { + DOMX_DEBUG("Error in Initializing Proxy"); + if (pComponentPrivate->cCompName != NULL) + { + TIMM_OSAL_Free(pComponentPrivate->cCompName); + pComponentPrivate->cCompName = NULL; + } + if (pComponentPrivate != NULL) + { + TIMM_OSAL_Free(pComponentPrivate); + pComponentPrivate = NULL; + } + } + return eError; +} + +OMX_ERRORTYPE OMX_ProxyViddecInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *pHandle = NULL; + PROXY_COMPONENT_PRIVATE *pComponentPrivate = NULL; + pHandle = (OMX_COMPONENTTYPE *) hComponent; + OMX_TI_PARAM_ENHANCEDPORTRECONFIG tParamStruct; + +#ifdef ANDROID_QUIRK_LOCK_BUFFER + OMX_U32 err; + hw_module_t const* module; +#endif + DOMX_ENTER(""); + + DOMX_DEBUG("Component name provided is %s", COMPONENT_NAME); + + pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate; + + // Copying component Name - this will be picked up in the proxy common + PROXY_assert(strlen(COMPONENT_NAME) + 1 < MAX_COMPONENT_NAME_LENGTH, + OMX_ErrorInvalidComponentName, + "Length of component name is longer than the max allowed"); + TIMM_OSAL_Memcpy(pComponentPrivate->cCompName, COMPONENT_NAME, + strlen(COMPONENT_NAME) + 1); + + eError = OMX_ProxyCommonInit(hComponent); // Calling Proxy Common Init() + PROXY_assert(eError == OMX_ErrorNone, eError, "Proxy common init returned error"); +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES + pHandle->SetParameter = PROXY_VIDDEC_SetParameter; + pHandle->GetParameter = PROXY_VIDDEC_GetParameter; +#endif + pHandle->GetExtensionIndex = PROXY_VIDDEC_GetExtensionIndex; + +#ifdef SET_STRIDE_PADDING_FROM_PROXY + pHandle->SendCommand = PROXY_VIDDEC_SendCommand; + pComponentPrivate->proxyEventHandler = PROXY_VIDDEC_EventHandler; + pComponentPrivate->IsLoadedState = OMX_TRUE; +#endif + +#ifdef ANDROID_QUIRK_LOCK_BUFFER + pComponentPrivate->proxyFillBufferDone = PROXY_VIDDEC_FillBufferDone; + pHandle->FillThisBuffer = PROXY_VIDDEC_FillThisBuffer; + + err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + if (err == 0) + { + pComponentPrivate->grallocModule = (gralloc_module_t const *)module; + } + else + { + DOMX_ERROR("FATAL: gralloc api hw_get_module() returned error: Can't find \ + %s module err = %x", GRALLOC_HARDWARE_MODULE_ID, err); + eError = OMX_ErrorInsufficientResources; + return eError; + } +#endif + +#ifdef USE_ENHANCED_PORTRECONFIG + /*Initializing Structure */ + tParamStruct.nSize = sizeof(OMX_TI_PARAM_ENHANCEDPORTRECONFIG); + tParamStruct.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + tParamStruct.nVersion.s.nVersionMinor = OMX_VER_MINOR; + tParamStruct.nVersion.s.nRevision = 0x0; + tParamStruct.nVersion.s.nStep = 0x0; + tParamStruct.nPortIndex = OMX_VIDEODECODER_OUTPUT_PORT; + tParamStruct.bUsePortReconfigForCrop = OMX_TRUE; + tParamStruct.bUsePortReconfigForPadding = OMX_TRUE; + + eError = PROXY_SetParameter(hComponent,(OMX_INDEXTYPE)OMX_TI_IndexParamUseEnhancedPortReconfig, + &tParamStruct); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy SetParameter for Enhanced port reconfig usage"); +#endif + /* This is required to handle WMV/VC-1 content */ + pHandle->EmptyThisBuffer = PrearrageEmptyThisBuffer; + + EXIT: + return eError; +} + +/* ===========================================================================*/ +/** + * @name PROXY_VIDDEC_GetExtensionIndex() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE PROXY_VIDDEC_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, OMX_OUT OMX_INDEXTYPE * pIndexType) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + + PROXY_require((hComp->pComponentPrivate != NULL), OMX_ErrorBadParameter, NULL); + PROXY_require(cParameterName != NULL, OMX_ErrorBadParameter, NULL); + PROXY_require(pIndexType != NULL, OMX_ErrorBadParameter, NULL); + + DOMX_ENTER("hComponent = %p, cParameterName = %p", hComponent, cParameterName); + +#ifdef ENABLE_GRALLOC_BUFFERS + // Ensure that String length is not greater than Max allowed length + PROXY_require(strlen(cParameterName) <= 127, OMX_ErrorBadParameter, NULL); + + if (strcmp(cParameterName, "OMX.google.android.index.getAndroidNativeBufferUsage") == 0) + { + *pIndexType = (OMX_INDEXTYPE) OMX_TI_IndexAndroidNativeBufferUsage; + } + else + { + eError = PROXY_GetExtensionIndex(hComponent, cParameterName, pIndexType); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in PROXY_GetExtensionIndex"); + } +#else + eError = PROXY_GetExtensionIndex(hComponent, cParameterName, pIndexType); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in PROXY_GetExtensionIndex"); +#endif + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +#ifdef ANDROID_QUIRK_CHANGE_PORT_VALUES + +/* ===========================================================================*/ +/** + * @name PROXY_GetParameter() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE PROXY_VIDDEC_GetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pParamStruct) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PARAM_PORTDEFINITIONTYPE* pPortDef = NULL; + OMX_VIDEO_PARAM_PORTFORMATTYPE* pPortParam = NULL; + OMX_TI_PARAMNATIVEBUFFERUSAGE *pUsage = NULL; + + PROXY_require((pParamStruct != NULL), OMX_ErrorBadParameter, NULL); + PROXY_assert((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + DOMX_ENTER + ("hComponent = %p, pCompPrv = %p, nParamIndex = %d, pParamStruct = %p", + hComponent, pCompPrv, nParamIndex, pParamStruct); + +#ifdef ENABLE_GRALLOC_BUFFERS + if( nParamIndex == OMX_TI_IndexAndroidNativeBufferUsage) + { + pUsage = (OMX_TI_PARAMNATIVEBUFFERUSAGE*)pParamStruct; + if(pCompPrv->proxyPortBuffers[pUsage->nPortIndex].proxyBufferType == GrallocPointers) + { + PROXY_CHK_VERSION(pParamStruct, OMX_TI_PARAMNATIVEBUFFERUSAGE); + pUsage->nUsage = GRALLOC_USAGE_HW_RENDER; +#ifdef ENABLE_RAW_BUFFERS_DUMP_UTILITY + pUsage->nUsage |= GRALLOC_USAGE_SW_READ_RARELY; +#endif + goto EXIT; + } + } +#endif + eError = PROXY_GetParameter(hComponent,nParamIndex, pParamStruct); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy GetParameter"); + + if( nParamIndex == OMX_IndexParamPortDefinition) + { + PROXY_CHK_VERSION(pParamStruct, OMX_PARAM_PORTDEFINITIONTYPE); + pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct; + if(pPortDef->format.video.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar) + { + if(pCompPrv->proxyPortBuffers[pPortDef->nPortIndex].proxyBufferType == GrallocPointers) + { + pPortDef->format.video.eColorFormat = HAL_NV12_PADDED_PIXEL_FORMAT; + } + else + { + pPortDef->format.video.eColorFormat = OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; + } + } + } + else if ( nParamIndex == OMX_IndexParamVideoPortFormat) + { + PROXY_CHK_VERSION(pParamStruct, OMX_VIDEO_PARAM_PORTFORMATTYPE); + pPortParam = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pParamStruct; + if(pPortParam->eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar) + { + if(pCompPrv->proxyPortBuffers[pPortParam->nPortIndex].proxyBufferType == GrallocPointers) + { + pPortParam->eColorFormat = HAL_NV12_PADDED_PIXEL_FORMAT; + } + else + { + pPortParam->eColorFormat = OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; + } + } + } + + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +/* ===========================================================================*/ +/** + * @name PROXY_SetParameter() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE PROXY_VIDDEC_SetParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, OMX_IN OMX_PTR pParamStruct) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_PARAM_PORTDEFINITIONTYPE* pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct; + OMX_VIDEO_PARAM_PORTFORMATTYPE* pPortParams = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pParamStruct; + + PROXY_require((pParamStruct != NULL), OMX_ErrorBadParameter, NULL); + PROXY_require((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + DOMX_ENTER + ("hComponent = %p, pCompPrv = %p, nParamIndex = %d, pParamStruct = %p", + hComponent, pCompPrv, nParamIndex, pParamStruct); + if(nParamIndex == OMX_IndexParamPortDefinition) + { + if(pPortDef->format.video.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar + || pPortDef->format.video.eColorFormat == HAL_NV12_PADDED_PIXEL_FORMAT) + { + pPortDef->format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } + } + else if(nParamIndex == OMX_IndexParamVideoPortFormat) + { + if(pPortParams->eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar + || pPortParams->eColorFormat == HAL_NV12_PADDED_PIXEL_FORMAT) + { + pPortParams->eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; + } + } + + eError = PROXY_SetParameter(hComponent, nParamIndex, pParamStruct); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy SetParameter"); + + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +#endif + +#ifdef SET_STRIDE_PADDING_FROM_PROXY +/* ===========================================================================*/ +/** + * @name PROXY_VIDDEC_SendCommand() + * @brief + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE PROXY_VIDDEC_SendCommand(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE eCmd, + OMX_IN OMX_U32 nParam, OMX_IN OMX_PTR pCmdData) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + + PROXY_require((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + DOMX_ENTER + ("hComponent = %p, pCompPrv = %p, eCmd = %d, nParam = %d, pCmdData = %p", + hComponent, pCompPrv, eCmd, nParam, pCmdData); + + if(eCmd == OMX_CommandStateSet) + { + //Set appropriate stride before Loaded to Idle transition. + if((OMX_STATETYPE)nParam == OMX_StateIdle && pCompPrv->IsLoadedState == OMX_TRUE) + { + eError = RPC_UTIL_SetStrideAndPadding(hComponent, pCompPrv); + PROXY_require(eError == OMX_ErrorNone, eError, + "Stride and padding setting from proxy returned"); + pCompPrv->IsLoadedState = OMX_FALSE; + } + } + else if(eCmd == OMX_CommandPortEnable) + { + if(nParam == OMX_ALL || nParam == OMX_VIDEODECODER_OUTPUT_PORT) + { + eError = RPC_UTIL_SetStrideAndPadding(hComponent, pCompPrv); + PROXY_require(eError == OMX_ErrorNone, eError, + "Stride and padding setting from proxy returned"); + } + } + + eError = + PROXY_SendCommand(hComponent, eCmd, nParam, pCmdData); + + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +/* ===========================================================================*/ +/** + * @name PROXY_EventHandler() + * @brief + * @param void + * @return OMX_ErrorNone = Successful + * @sa TBD + * + */ +/* ===========================================================================*/ +OMX_ERRORTYPE PROXY_VIDDEC_EventHandler(OMX_HANDLETYPE hComponent, + OMX_PTR pAppData, OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2, + OMX_PTR pEventData) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + PROXY_require((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, + "This is fatal error, processing cant proceed - please debug"); + + DOMX_ENTER + ("hComponent=%p, pCompPrv=%p, eEvent=%p, nData1=%p, nData2=%p, pEventData=%p", + hComponent, pCompPrv, eEvent, nData1, nData2, pEventData); + + if((eEvent == OMX_EventCmdComplete) && ((OMX_COMMANDTYPE)nData1 == OMX_CommandStateSet)) + { + if((OMX_STATETYPE)nData2 == OMX_StateLoaded) + { + pCompPrv->IsLoadedState = OMX_TRUE; + } + } + eError = PROXY_EventHandler(hComponent, pAppData, eEvent, nData1, nData2, pEventData); + + EXIT: + return eError; +} + +/* ===========================================================================*/ +/** + * @name RPC_UTIL_RPC_UTIL_SetStrideAndPadding() + * @brief Gets stride on this port. Used to set stride on OMX to tell whether buffer is 1D or 2D + * @param hRemoteComp [IN] : Remote component handle. + * @return OMX_ErrorNone = Successful + */ +/* ===========================================================================*/ +OMX_ERRORTYPE RPC_UTIL_SetStrideAndPadding(OMX_COMPONENTTYPE * hComponent,PROXY_COMPONENT_PRIVATE * pCompPrv) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_PARAM_PORTDEFINITIONTYPE sPortDef; + OMX_CONFIG_RECTTYPE tParamStruct; + OMX_U32 nPortIndex = 0; + + for(nPortIndex=0; nPortIndex < TOTAL_DEC_PORTS ;nPortIndex++ ) + { + /*Initializing Structure */ + sPortDef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + sPortDef.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + sPortDef.nVersion.s.nVersionMinor = OMX_VER_MINOR; + sPortDef.nVersion.s.nRevision = 0x0; + sPortDef.nVersion.s.nStep = 0x0; + sPortDef.nPortIndex = nPortIndex; + + eError = PROXY_GetParameter(hComponent,OMX_IndexParamPortDefinition, + &sPortDef); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy GetParameter for Port Def"); + + if (sPortDef.eDomain == OMX_PortDomainVideo && sPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingUnused) + { + if(pCompPrv->proxyPortBuffers[nPortIndex].IsBuffer2D == OMX_TRUE) + { + sPortDef.format.video.nStride = LINUX_PAGE_SIZE; + } + else + { + tParamStruct.nSize = sizeof(OMX_CONFIG_RECTTYPE); + tParamStruct.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + tParamStruct.nVersion.s.nVersionMinor = OMX_VER_MINOR; + tParamStruct.nVersion.s.nRevision = 0x0; + tParamStruct.nVersion.s.nStep = 0x0; + tParamStruct.nPortIndex = nPortIndex; + + eError = PROXY_GetParameter(hComponent,(OMX_INDEXTYPE)OMX_TI_IndexParam2DBufferAllocDimension, + &tParamStruct); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy GetParameter for 2D index"); + + sPortDef.format.video.nStride = tParamStruct.nWidth; + } + eError = PROXY_SetParameter(hComponent,OMX_IndexParamPortDefinition, + &sPortDef); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy SetParameter for Port Def"); + } + } + + EXIT: + return eError; +} + +#endif + +#ifdef ANDROID_QUIRK_LOCK_BUFFER +/* ===========================================================================*/ +/** + * @name PROXY_VIDDEC_FillThisBuffer() + * @brief Gets stride on this port. Used to set stride on OMX to tell whether buffer is 1D or 2D + */ +/* ===========================================================================*/ +OMX_ERRORTYPE PROXY_VIDDEC_FillThisBuffer(OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone, eCompReturn = OMX_ErrorNone; + RPC_OMX_ERRORTYPE eRPCError = RPC_OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_U32 count = 0; + IMG_native_handle_t* grallocHandle; + OMX_PARAM_PORTDEFINITIONTYPE sPortDef; + + PROXY_require(pBufferHdr != NULL, OMX_ErrorBadParameter, NULL); + PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, + NULL); + PROXY_CHK_VERSION(pBufferHdr, OMX_BUFFERHEADERTYPE); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + if(pCompPrv->proxyPortBuffers[OMX_VIDEODECODER_OUTPUT_PORT].proxyBufferType + == GrallocPointers) + { + /* Lock the Gralloc buffer till it gets rendered completely */ + /* Extract the Gralloc handle from the Header and then call lock on that */ + /* Note# There is no error check for the pBufferHdr here*/ + grallocHandle = (IMG_native_handle_t*)pBufferHdr->pBuffer; + + /*Initializing Structure */ + sPortDef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + sPortDef.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + sPortDef.nVersion.s.nVersionMinor = OMX_VER_MINOR; + sPortDef.nVersion.s.nRevision = 0x0; + sPortDef.nVersion.s.nStep = 0x0; + sPortDef.nPortIndex = OMX_VIDEODECODER_INPUT_PORT; + eError = PROXY_GetParameter(hComponent,OMX_IndexParamPortDefinition, + &sPortDef); + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy GetParameter for Port Def"); + +#ifdef ENABLE_RAW_BUFFERS_DUMP_UTILITY + /* Get the Video frame crop window */ + OMX_CONFIG_RECTTYPE rect; + rect.nSize = sizeof(rect); + rect.nVersion.s.nVersionMajor = OMX_VER_MAJOR; + rect.nVersion.s.nVersionMinor = OMX_VER_MINOR; + rect.nVersion.s.nRevision = 0x0; + rect.nVersion.s.nStep = 0x0; + rect.nPortIndex = OMX_VIDEODECODER_OUTPUT_PORT; + + eError = PROXY_GetConfig(hComponent, OMX_IndexConfigCommonOutputCrop, &rect); + + PROXY_assert(eError == OMX_ErrorNone, + eError," Error while getting output crop"); + pCompPrv->debugframeInfo.frame_width = rect.nWidth; + pCompPrv->debugframeInfo.frame_height = rect.nHeight; + pCompPrv->debugframeInfo.frame_xoffset = rect.nLeft; + pCompPrv->debugframeInfo.frame_yoffset = rect.nTop; +#endif + pCompPrv->grallocModule->lock((gralloc_module_t const *) pCompPrv->grallocModule, + (buffer_handle_t)grallocHandle, GRALLOC_USAGE_HW_RENDER, + 0,0,sPortDef.format.video.nFrameWidth, sPortDef.format.video.nFrameHeight,NULL); + } + + eRPCError = PROXY_FillThisBuffer(hComponent, pBufferHdr); + + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in Proxy SetParameter for Port Def"); + + EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +/* ===========================================================================*/ +/** + * @name PROXY_VIDDEC_FillBufferDone() + * @brief Gets stride on this port. Used to set stride on OMX to tell whether buffer is 1D or 2D + */ +/* ===========================================================================*/ +OMX_ERRORTYPE PROXY_VIDDEC_FillBufferDone(OMX_HANDLETYPE hComponent, + OMX_U32 remoteBufHdr, OMX_U32 nfilledLen, OMX_U32 nOffset, OMX_U32 nFlags, + OMX_TICKS nTimeStamp, OMX_HANDLETYPE hMarkTargetComponent, + OMX_PTR pMarkData) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone, eCompReturn = OMX_ErrorNone; + RPC_OMX_ERRORTYPE eRPCError = RPC_OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_U32 count = 0; + IMG_native_handle_t* grallocHandle; + + PROXY_require((hComp->pComponentPrivate != NULL), + OMX_ErrorBadParameter, + "This is fatal error, processing cant proceed - please debug"); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + + /* Lock the Gralloc buffer till it gets rendered completely */ + /* Extract the Gralloc handle from the Header and then call lock on that */ + /* Note# There is no error check for the pBufferHdr here*/ + + if(pCompPrv->proxyPortBuffers[OMX_VIDEODECODER_OUTPUT_PORT].proxyBufferType + == GrallocPointers) { + for (count = 0; count < pCompPrv->nTotalBuffers; ++count) + { + if (pCompPrv->tBufList[count].pBufHeaderRemote == remoteBufHdr) + { + grallocHandle = (IMG_native_handle_t*)(pCompPrv->tBufList[count].pBufHeader)->pBuffer; + break; + } + } + + PROXY_assert((count != pCompPrv->nTotalBuffers), + OMX_ErrorBadParameter, + "Received invalid-buffer header from OMX component"); + pCompPrv->grallocModule->unlock((gralloc_module_t const *) pCompPrv->grallocModule, (buffer_handle_t)grallocHandle); + +#ifdef ENABLE_RAW_BUFFERS_DUMP_UTILITY + ALOGV("frm[%u] to[%u] run[%u]", pCompPrv->debugframeInfo.fromFrame, pCompPrv->debugframeInfo.toFrame, pCompPrv->debugframeInfo.runningFrame); + /* Fill buffer Done successed, hence start dumping if requested */ + OMX_BUFFERHEADERTYPE *pBufHdr = pCompPrv->tBufList[count].pBufHeader; + if ((pCompPrv->debugframeInfo.fromFrame == 0) && (pCompPrv->debugframeInfo.runningFrame <= pCompPrv->debugframeInfo.toFrame)) + { + /* Lock the buffer for SW read usage and then access it */ + pCompPrv->grallocModule->lock((gralloc_module_t const*) pCompPrv->grallocModule, + (buffer_handle_t)grallocHandle, + GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_SW_READ_RARELY, + pCompPrv->debugframeInfo.frame_xoffset, + pCompPrv->debugframeInfo.frame_yoffset, + pCompPrv->debugframeInfo.frame_width, + pCompPrv->debugframeInfo.frame_height, + (void*)pCompPrv->debugframeInfo.y_uv); + + DumpVideoFrame(&pCompPrv->debugframeInfo); + + pCompPrv->grallocModule->unlock((gralloc_module_t const *) pCompPrv->grallocModule, + (buffer_handle_t)grallocHandle); + pCompPrv->debugframeInfo.runningFrame++; + } + else if (pCompPrv->debugframeInfo.fromFrame > 0) + { + pCompPrv->debugframeInfo.fromFrame--; + } +#endif + } + + eRPCError = PROXY_FillBufferDone(hComponent,remoteBufHdr, nfilledLen, nOffset, nFlags, + nTimeStamp, hMarkTargetComponent, pMarkData); + + PROXY_assert(eError == OMX_ErrorNone, + eError," Error in PROXY FillBufferDone for Port Def"); + +EXIT: + DOMX_EXIT("eError: %d", eError); + return eError; +} + +#endif + diff --git a/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec_secure.c b/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec_secure.c new file mode 100644 index 0000000..473a7f0 --- /dev/null +++ b/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec_secure.c @@ -0,0 +1,157 @@ +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include "omx_proxy_common.h" +#include <timm_osal_interfaces.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define COMPONENT_NAME "OMX.TI.DUCATI1.VIDEO.DECODER.secure" + +extern OMX_U32 DUCATI_IN_SECURE_MODE; +extern OMX_U32 SECURE_COMPONENTS_RUNNING; + +extern OMX_ERRORTYPE OMX_ProxyViddecInit(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE PROXY_VIDDEC_Secure_ComponentDeInit(OMX_HANDLETYPE hComponent); + +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *pHandle = NULL; + PROXY_COMPONENT_PRIVATE *pComponentPrivate = NULL; + const OMX_U8 enable = 1, disable = 0; + OMX_U8 mode; + int ret; + + pHandle = (OMX_COMPONENTTYPE *) hComponent; + + DOMX_ENTER(""); + + DOMX_DEBUG("Component name provided is %s", COMPONENT_NAME); + + pHandle->pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) + TIMM_OSAL_Malloc(sizeof(PROXY_COMPONENT_PRIVATE), TIMM_OSAL_TRUE, + 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pHandle->pComponentPrivate != NULL, + OMX_ErrorInsufficientResources, + "ERROR IN ALLOCATING PROXY COMPONENT PRIVATE STRUCTURE"); + + pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate; + + TIMM_OSAL_Memset(pComponentPrivate, 0, + sizeof(PROXY_COMPONENT_PRIVATE)); + + pComponentPrivate->cCompName = + TIMM_OSAL_Malloc(MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8), + TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT); + + PROXY_assert(pComponentPrivate->cCompName != NULL, + OMX_ErrorInsufficientResources, + " Error in Allocating space for proxy component table"); + + // Copying component Name - this will be picked up in the proxy common + PROXY_assert(strlen(COMPONENT_NAME) + 1 < MAX_COMPONENT_NAME_LENGTH, + OMX_ErrorInvalidComponentName, + "Length of component name is longer than the max allowed"); + TIMM_OSAL_Memcpy(pComponentPrivate->cCompName, COMPONENT_NAME, + strlen(COMPONENT_NAME) + 1); + + pComponentPrivate->secure_misc_drv_fd = open("/dev/rproc_user", O_SYNC | O_RDWR); + if (pComponentPrivate->secure_misc_drv_fd < 0) + { + DOMX_ERROR("Can't open rproc_user device 0x%x\n", errno); + eError = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = write(pComponentPrivate->secure_misc_drv_fd, &enable, sizeof(enable)); + if(ret != 1) + { + DOMX_ERROR("errno from setting secure mode = %x",errno); + ret = write(pComponentPrivate->secure_misc_drv_fd, &disable, sizeof(disable)); + if (ret < 0) + { + DOMX_ERROR("Setting unsecure mode failed"); + } + + ret = close(pComponentPrivate->secure_misc_drv_fd); + if (ret < 0) + { + DOMX_ERROR("Can't close the driver"); + } + eError = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = read(pComponentPrivate->secure_misc_drv_fd, &mode, sizeof(mode)); + PROXY_assert(mode == enable, OMX_ErrorUndefined,"ERROR: We are not in secure mode"); + DOMX_DEBUG("secure mode recieved from Misc driver for secure playback = 0x%x\n", mode); + + eError = OMX_ProxyViddecInit(hComponent); + pHandle->ComponentDeInit = PROXY_VIDDEC_Secure_ComponentDeInit; + +#ifdef USE_ION + pComponentPrivate->bUseIon = OMX_TRUE; + pComponentPrivate->bMapIonBuffers = OMX_FALSE; +#endif + EXIT: + if (eError != OMX_ErrorNone) + { + DOMX_DEBUG("Error in Initializing Proxy"); + if (pComponentPrivate->cCompName != NULL) + { + TIMM_OSAL_Free(pComponentPrivate->cCompName); + pComponentPrivate->cCompName = NULL; + } + if (pComponentPrivate != NULL) + { + TIMM_OSAL_Free(pComponentPrivate); + pComponentPrivate = NULL; + } + } + return eError; +} + +OMX_ERRORTYPE PROXY_VIDDEC_Secure_ComponentDeInit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE *pHandle = NULL; + PROXY_COMPONENT_PRIVATE *pComponentPrivate = NULL; + int ret; + const OMX_U8 disable = 0; + int secure_misc_drv_fd; + + pHandle = (OMX_COMPONENTTYPE *) hComponent; + + pComponentPrivate = + (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate; + + secure_misc_drv_fd = pComponentPrivate->secure_misc_drv_fd; + + eError = PROXY_ComponentDeInit(hComponent); + if(eError != OMX_ErrorNone) + { + DOMX_ERROR("Proxy common deinit returned error = %x",eError); + } + pComponentPrivate = NULL; + + ret = write(secure_misc_drv_fd, &disable, sizeof(disable)); + if (ret < 0) + { + DOMX_ERROR("Setting unsecure mode failed"); + } + + ret = close(secure_misc_drv_fd); + if (ret < 0) + { + DOMX_ERROR("Can't close the driver"); + } + + return eError; +} + diff --git a/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec_utils.c b/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec_utils.c new file mode 100755 index 0000000..53922fd --- /dev/null +++ b/domx/omx_proxy_component/omx_video_dec/src/omx_proxy_videodec_utils.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2010, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*============================================================== + *! Revision History + *! ============================ + *! 21-Oct-2011 Rajesh vandanapu sarthav@ti.com: Initial Version + *================================================================*/ + +/****************************************************************** + * INCLUDE FILES + ******************************************************************/ +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include "omx_proxy_common.h" +#include <timm_osal_interfaces.h> +#include "OMX_TI_IVCommon.h" +#include "OMX_TI_Video.h" +#include "OMX_TI_Index.h" + +#ifdef ENABLE_RAW_BUFFERS_DUMP_UTILITY +#define LOG_TAG "OMXPROXYVIDEODEC" +#include <fcntl.h> +#include <cutils/properties.h> +#include <utils/Log.h> +#include <stdlib.h> +#include <errno.h> +#endif + +#define COMPONENT_NAME "OMX.TI.DUCATI1.VIDEO.DECODER" +/* needs to be specific for every configuration wrapper */ + +/* DEFINITIONS for parsing the config information & sequence header for WMV*/ +#define VIDDEC_GetUnalignedDword( pb, dw ) \ + (dw) = ((OMX_U32) *(pb + 3) << 24) + \ + ((OMX_U32) *(pb + 2) << 16) + \ + ((OMX_U16) *(pb + 1) << 8) + *pb; + +#define VIDDEC_GetUnalignedDwordEx( pb, dw ) VIDDEC_GetUnalignedDword( pb, dw ); (pb) += sizeof(OMX_U32); +#define VIDDEC_LoadDWORD( dw, p ) VIDDEC_GetUnalignedDwordEx( p, dw ) +#define VIDDEC_MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((OMX_U32)(OMX_U8)(ch0) | ((OMX_U32)(OMX_U8)(ch1) << 8) | \ + ((OMX_U32)(OMX_U8)(ch2) << 16) | ((OMX_U32)(OMX_U8)(ch3) << 24 )) + +#define VIDDEC_FOURCC(ch0, ch1, ch2, ch3) VIDDEC_MAKEFOURCC(ch0, ch1, ch2, ch3) + +#define FOURCC_WMV3 VIDDEC_FOURCC('W','M','V','3') +#define FOURCC_WMV2 VIDDEC_FOURCC('W','M','V','2') +#define FOURCC_WMV1 VIDDEC_FOURCC('W','M','V','1') +#define FOURCC_WVC1 VIDDEC_FOURCC('W','V','C','1') + +#define CSD_POSITION 51 /*Codec Specific Data position on the "stream propierties object"(ASF spec)*/ + +typedef struct VIDDEC_WMV_RCV_struct { + OMX_U32 nNumFrames : 24; + OMX_U32 nFrameType : 8; + OMX_U32 nID : 32; + OMX_U32 nStructData : 32; //STRUCT_C + OMX_U32 nVertSize; //STRUCT_A-1 + OMX_U32 nHorizSize; //STRUCT_A-2 + OMX_U32 nID2 : 32; + OMX_U32 nSequenceHdr : 32; //STRUCT_B +} VIDDEC_WMV_RCV_struct; + +typedef struct VIDDEC_WMV_VC1_struct { + OMX_U32 nNumFrames : 24; + OMX_U32 nFrameType : 8; + OMX_U32 nID : 32; + OMX_U32 nStructData : 32; //STRUCT_C + OMX_U32 nVertSize; //STRUCT_A-1 + OMX_U32 nHorizSize; //STRUCT_A-2 + OMX_U32 nID2 : 32; + OMX_U32 nSequenceHdr : 32; //STRUCT_B +} VIDDEC_WMV_VC1_struct; + + +OMX_ERRORTYPE PrearrageEmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + PROXY_COMPONENT_PRIVATE *pCompPrv = NULL; + OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; + OMX_U8* pBuffer = NULL; + OMX_U8* pData = NULL; + OMX_U32 nValue = 0; + OMX_U32 nWidth = 0; + OMX_U32 nHeight = 0; + OMX_U32 nActualCompression = 0; + OMX_U8* pCSD = NULL; + OMX_U32 nSize_CSD = 0; + DOMX_ENTER(""); + + PROXY_assert(pBufferHdr != NULL, OMX_ErrorBadParameter, NULL); + + if (pBufferHdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG){ + PROXY_assert(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, NULL); + + pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate; + /* Get component role */ + OMX_PARAM_COMPONENTROLETYPE compRole; + compRole.nSize = sizeof(OMX_PARAM_COMPONENTROLETYPE); + compRole.nVersion.s.nVersionMajor = 1; + compRole.nVersion.s.nVersionMinor = 1; //Ducati OMX version + compRole.nVersion.s.nRevision = 0; + compRole.nVersion.s.nStep = 0; + + eError = PROXY_GetParameter(hComp, OMX_IndexParamStandardComponentRole, &compRole); + if(eError != OMX_ErrorNone){ + DOMX_ERROR("Error getting OMX_IndexParamStandardComponentRole"); + } + + if(!strcmp((char *)(compRole.cRole), "video_decoder.wmv")){ + pBuffer = pBufferHdr->pBuffer; + + VIDDEC_WMV_RCV_struct sStructRCV; + + DOMX_DEBUG("nFlags: %x", pBufferHdr->nFlags); + + pData = pBufferHdr->pBuffer + 15; /*Position to Width & Height*/ + VIDDEC_LoadDWORD(nValue, pData); + nWidth = nValue; + VIDDEC_LoadDWORD(nValue, pData); + nHeight = nValue; + + pData += 4; /*Position to compression type*/ + VIDDEC_LoadDWORD(nValue, pData); + nActualCompression = nValue; + + /*Seting pCSD to proper position*/ + pCSD = pBufferHdr->pBuffer; + pCSD += CSD_POSITION; + nSize_CSD = pBufferHdr->nFilledLen - CSD_POSITION; + + if(nActualCompression == FOURCC_WMV3){ + + //From VC-1 spec: Table 265: Sequence Layer Data Structure + sStructRCV.nNumFrames = 0xFFFFFF; /*Infinite frame number*/ + sStructRCV.nFrameType = 0xc5; /*0x85 is the value given by ASF to rcv converter*/ + sStructRCV.nID = 0x04; /*WMV3*/ + sStructRCV.nStructData = 0x018a3106; /*0x06318a01zero fill 0x018a3106*/ + sStructRCV.nVertSize = nHeight; + sStructRCV.nHorizSize = nWidth; + sStructRCV.nID2 = 0x0c; /* Fix value */ + sStructRCV.nSequenceHdr = 0x00002a9f; /* This value is not provided by parser, so giving a value from a video*/ + + DOMX_DEBUG("initial: nStructData: %x", sStructRCV.nStructData); + DOMX_DEBUG("pCSD = %x", (OMX_U32)*pCSD); + + sStructRCV.nStructData = (OMX_U32)pCSD[0] << 0 | + pCSD[1] << 8 | + pCSD[2] << 16 | + pCSD[3] << 24; + + DOMX_DEBUG("FINAL: nStructData: %x", sStructRCV.nStructData); + + //Copy RCV structure to actual buffer + assert(pBufferHdr->nFilledLen < pBufferHdr->nAllocLen); + pBufferHdr->nFilledLen = sizeof(VIDDEC_WMV_RCV_struct); + TIMM_OSAL_Memcpy(pBufferHdr->pBuffer, (OMX_U8*)(&sStructRCV), + pBufferHdr->nFilledLen); + + } + else if (nActualCompression == FOURCC_WVC1){ + DOMX_DEBUG("VC-1 Advance Profile prearrange"); + pBufferHdr->nOffset = pBufferHdr->nOffset+52; + pBufferHdr->nFilledLen= pBufferHdr->nFilledLen-52; + } + } + } + + EXIT: + DOMX_EXIT("eError: %d", eError); + + return PROXY_EmptyThisBuffer(hComponent, pBufferHdr); +} + +#ifdef ENABLE_RAW_BUFFERS_DUMP_UTILITY +/** +* Usage# +* By default this feature is kept disabled to avoid security leaks. +* +* (1) Uncomment the below 2 lines from Android.mk +* #LOCAL_CFLAGS += -DENABLE_RAW_BUFFERS_DUMP_UTILITY +* #LOCAL_SHARED_LIBRARIES += libcutils +* And rebuild the omx proxy common component +* +* (2) Before start playback, make sure that "data" folder has r/w +* permissions. For this, execute the below +* mount -o rw,remount -t ext3 /dev/block/mmcblk0p1 /data/ +* chmod 777 /data/ +* +* (3) Set the property for number of frames to dump +* eg: setprop debug.video.dumpframe 10:20 +* would dump frames from 10 to 20. +* +* (4) Pull the frames to PC over adb +* adb pull /data/frame_10.txt +* +* (5) Analyse on PC tools. +*/ + +/* +* Method to convert NV12 to YUV420p for PC analysis +*/ +static void convertNV12ToYuv420(DebugFrame_Dump *frameInfo, void *dst) +{ + int stride = 4096; /* ARM Page size = 4k */ + uint32_t ybuf_offset = frameInfo->frame_yoffset * stride + frameInfo->frame_xoffset; + uint8_t* p1y = (uint8_t*)frameInfo->y_uv[0] + ybuf_offset; + uint8_t* p2y = (uint8_t*) dst; + int i, j, j1; + int width = frameInfo->frame_width; + int height = frameInfo->frame_height; + + LOGD("Coverting NV-12 to YUV420p Width[%d], Height[%d] and Stride[%d] offset[%d]", + width, height, stride, ybuf_offset); + + /* copy y-buffer, almost bytewise copy, except for stride jumps.*/ + for(i=0;i<height;i++) + { + /* copy whole row of Y pixels. source and desination will point to new row each time.*/ + memcpy(p2y+i*width, p1y+i*stride, width); + } + + /** copy uv buffers + * rearrange from packed planar [uvuvuv] to planar [uuu][vvvv] packages pixel wise + * calculate the offset for UV buffer + */ + uint32_t UV_offset = frameInfo->frame_xoffset + + (frameInfo->frame_yoffset * stride)/2; + + const uint8_t* p1uv = (uint8_t*)frameInfo->y_uv[1] + UV_offset; + + uint8_t* p2u = ((uint8_t*) dst + (width * height)); + uint8_t* p2v = ((uint8_t*) p2u + ((width/2) * (height/2))); + for(i=0;(i < height/2);i++) + { + for(j=0,j1=0;(j< width/2);j++,j1+=2) + { + p2u[j] = p1uv[j1]; + p2v[j] = p1uv[j1+1]; + } + p1uv+=stride; + p2u+=width/2; + p2v+=width/2; + } +} + +void DumpVideoFrame(DebugFrame_Dump *frameInfo) +{ + /* First convert the frame to 420p and then write to SD Card */ + OMX_U32 framesize = (frameInfo->frame_width * + frameInfo->frame_height * 3) / 2; + OMX_U8* localbuffer = malloc(framesize); + if (localbuffer == NULL) + { + LOGE("NO HEAP"); + goto EXIT; + } + convertNV12ToYuv420(frameInfo, localbuffer); + int filedes = -1; + char framenumber[100]; + sprintf(framenumber, "/data/frame_%ld.txt", frameInfo->runningFrame); + LOGD("file path %s",framenumber); + filedes = open(framenumber, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, 0777); + if(filedes < 0) + { + LOGE("\n!!!!!!!!!Error in file open!!!!!!!! [%d][%s]\n", filedes, strerror(errno)); + goto EXIT; + } + int ret = write (filedes, (void*)localbuffer, framesize); + if (ret < (int)framesize) + { + LOGE("File Write Failed"); + } +EXIT: + if (localbuffer) + { + free(localbuffer); + localbuffer = NULL; + } + if (filedes > 0) + { + close(filedes); + } +} + +#endif |