diff options
author | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-07-24 23:40:06 +0100 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-07-24 23:40:06 +0100 |
commit | eed2342115e57f53f19e05411715a10573a5d74d (patch) | |
tree | 50cb83e8943ea0905602c375a688f6a215dfd3c8 | |
parent | 320c939ef471644fcb618cd3b5688e68694170a9 (diff) | |
parent | 363cef472e275f4900dc4916acd03718c7d57284 (diff) | |
download | android_hardware_samsung_slsi_exynos5-eed2342115e57f53f19e05411715a10573a5d74d.tar.gz android_hardware_samsung_slsi_exynos5-eed2342115e57f53f19e05411715a10573a5d74d.tar.bz2 android_hardware_samsung_slsi_exynos5-eed2342115e57f53f19e05411715a10573a5d74d.zip |
Merge tag 'android-4.3_r2.1' into cm-10.2cm-10.2.1cm-10.2.0cm-10.2-M1stable/cm-10.2cm-10.2
Android 4.3 release 2.1
45 files changed, 1760 insertions, 447 deletions
diff --git a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/Android.mk b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/Android.mk index be5e4f9..8cd8248 100644 --- a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/Android.mk +++ b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/Android.mk @@ -8,7 +8,8 @@ LOCAL_SRC_FILES := \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ - hardware/samsung_slsi/exynos5/include + hardware/samsung_slsi/exynos5/include \ + hardware/samsung_slsi/exynos5/exynos_omx/openmax/exynos_omx/include/khronos LOCAL_MODULE := libExynosVideoApi LOCAL_MODULE_TAGS := optional diff --git a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c index 6259b0c..9dec8e1 100644 --- a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c +++ b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c @@ -40,6 +40,7 @@ #include "ExynosVideoApi.h" #include "ExynosVideoDec.h" +#include "OMX_Core.h" /* #define LOG_NDEBUG 0 */ #define LOG_TAG "ExynosVideoDecoder" @@ -1441,6 +1442,12 @@ static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf( buf.m.planes[i].bytesused = dataSize[i]; } + if ((((OMX_BUFFERHEADERTYPE *)pPrivate)->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + buf.flags |= V4L2_BUF_FLAG_LAST_FRAME; + ALOGD("%s: OMX_BUFFERFLAG_EOS => LAST_FRAME: 0x%x", __func__, + !!(buf.flags & V4L2_BUF_FLAG_LAST_FRAME)); + } + if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { ALOGE("%s: Failed to enqueue input buffer", __func__); pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; diff --git a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.c b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.c index fac8d52..cbf6a24 100644 --- a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.c +++ b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.c @@ -191,6 +191,7 @@ OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) { ret = Exynos_OMX_Get_Resource(pOMXComponent); if (ret != OMX_ErrorNone) { + Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent); goto EXIT; } } @@ -236,7 +237,7 @@ OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); pExynosComponent->pExynosPort[i].pauseEvent = NULL; if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) { - Exynos_OSAL_SignalTerminate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; } } @@ -281,7 +282,7 @@ OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); pExynosComponent->pExynosPort[i].pauseEvent = NULL; if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) { - Exynos_OSAL_SignalTerminate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; } } @@ -420,7 +421,7 @@ OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); pExynosComponent->pExynosPort[i].pauseEvent = NULL; if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) { - Exynos_OSAL_SignalTerminate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; } } diff --git a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.h b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.h index 9f9ed3d..bf7741e 100644 --- a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.h +++ b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.h @@ -95,7 +95,8 @@ typedef struct _EXYNOS_OMX_BASECOMPONENT OMX_BOOL reInputData; OMX_BOOL bUseFlagEOF; - OMX_BOOL bSaveFlagEOS; + OMX_BOOL bSaveFlagEOS; //bSaveFlagEOS is OMX_TRUE, if EOS flag is incoming. + OMX_BOOL bBehaviorEOS; //bBehaviorEOS is OMX_TRUE, if EOS flag with Data are incoming. /* Check for Old & New OMX Process type switch */ OMX_BOOL bMultiThreadProcess; diff --git a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Resourcemanager.c b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Resourcemanager.c index e8be83b..6645fb2 100644 --- a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Resourcemanager.c +++ b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Resourcemanager.c @@ -40,7 +40,7 @@ #define MAX_RESOURCE_VIDEO_DEC 3 /* for Android */ -#define MAX_RESOURCE_VIDEO_ENC 1 /* for Android */ +#define MAX_RESOURCE_VIDEO_ENC 2 /* for Android */ /* Max allowable video scheduler component instance */ static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoDecRMComponentList = NULL; diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.c index 2f8b72c..c40221b 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.c @@ -127,6 +127,46 @@ OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosCompo return ret; } +OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + /* Input port */ + pExynosInputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosInputPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosInputPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosInputPort->portDefinition.format.video.nSliceHeight = 0; + pExynosInputPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pExynosInputPort->portDefinition.format.video.pNativeRender = 0; + pExynosInputPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosInputPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosInputPort->portDefinition.bEnabled = OMX_TRUE; + pExynosInputPort->bufferProcessType = BUFFER_SHARE; + pExynosInputPort->portWayType = WAY2_PORT; + + /* Output port */ + pExynosOutputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosOutputPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosOutputPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosOutputPort->portDefinition.format.video.nSliceHeight = 0; + pExynosOutputPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosOutputPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + Exynos_OSAL_Memset(pExynosOutputPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosOutputPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosOutputPort->portDefinition.format.video.pNativeRender = 0; + pExynosOutputPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosOutputPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pExynosOutputPort->portDefinition.bEnabled = OMX_TRUE; + pExynosOutputPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE; + pExynosOutputPort->bIsANBEnabled = OMX_FALSE; + pExynosOutputPort->portWayType = WAY2_PORT; + + return ret; +} + OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData) { OMX_ERRORTYPE ret = OMX_ErrorNone; @@ -394,9 +434,9 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE"); - srcInputData->dataLen = 0; - srcInputData->remainDataLen = 0; pExynosComponent->bSaveFlagEOS = OMX_TRUE; + if (srcInputData->dataLen != 0) + pExynosComponent->bBehaviorEOS = OMX_TRUE; } if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { @@ -1008,6 +1048,9 @@ OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent) Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread); pVideoDec->hDstOutputThread = NULL; + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + EXIT: FunctionOut(); @@ -1062,6 +1105,7 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; pExynosComponent->bMultiThreadProcess = OMX_TRUE; /* Input port */ diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_VdecControl.c b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_VdecControl.c index 432a4a7..5aff7b1 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_VdecControl.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_VdecControl.c @@ -560,6 +560,7 @@ OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 n Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); pExynosComponent->getAllDelayBuffer = OMX_FALSE; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; pExynosComponent->reInputData = OMX_FALSE; } @@ -763,7 +764,6 @@ OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) } if ((bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - bufferHeader->nFilledLen = 0; Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"event OMX_BUFFERFLAG_EOS!!!"); pExynosComponent->pCallbacks->EventHandler(pOMXComponent, pExynosComponent->callbackData, @@ -809,7 +809,6 @@ OMX_ERRORTYPE Exynos_FlushOutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, E } if ((bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - bufferHeader->nFilledLen = 0; Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"event OMX_BUFFERFLAG_EOS!!!"); pExynosComponent->pCallbacks->EventHandler(pOMXComponent, pExynosComponent->callbackData, @@ -1100,33 +1099,49 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetParameter( pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; portDefinition = &pExynosPort->portDefinition; - switch (index) { - case supportFormat_0: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_1: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_2: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12TPhysicalAddress; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_3: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - default: - if (index > supportFormat_0) { - ret = OMX_ErrorNoMore; - goto EXIT; + if (pExynosPort->bIsANBEnabled == OMX_FALSE) { + switch (index) { + case supportFormat_0: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_1: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_2: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12TPhysicalAddress; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_3: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + default: + if (index > supportFormat_0) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + break; + } + } else { + switch (index) { + case supportFormat_0: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + default: + if (index > supportFormat_0) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + break; } - break; } } ret = OMX_ErrorNone; diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Android.mk index 5f8957d..94ced6a 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Android.mk @@ -29,7 +29,7 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler ifeq ($(BOARD_USES_MFC_FPS),true) diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c index 495fcae..8be2a22 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c @@ -1453,6 +1453,7 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE; pExynosComponent->bUseFlagEOF = OMX_TRUE; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; /* H.264 Codec Open */ ret = H264CodecOpen(pH264Dec); @@ -1524,6 +1525,7 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { pVideoDec->csc_handle = csc_init(CSC_METHOD_HW); csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2); + csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER); csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, pVideoDec->bDRMPlayerMode); } else { pVideoDec->csc_handle = csc_init(csc_method); @@ -1616,6 +1618,8 @@ OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) } H264CodecClose(pH264Dec); + Exynos_ResetAllPortConfig(pOMXComponent); + EXIT: FunctionOut(); @@ -1903,6 +1907,11 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags); pDstOutputData->remainDataLen = 0; + if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_TRUE)) { + pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; + pExynosComponent->bBehaviorEOS = OMX_FALSE; + } } else { pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; } diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Android.mk index 26876ee..5f2f98e 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Android.mk @@ -25,7 +25,7 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler ifeq ($(BOARD_USES_MFC_FPS),true) diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c index 761b1d2..d8cf096 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -1589,6 +1589,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE; pExynosComponent->bUseFlagEOF = OMX_TRUE; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; /* H.264 Codec Open */ ret = Mpeg4CodecOpen(pMpeg4Dec); @@ -1746,6 +1747,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) } Mpeg4CodecClose(pMpeg4Dec); + Exynos_ResetAllPortConfig(pOMXComponent); + EXIT: FunctionOut(); @@ -2032,6 +2035,11 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags); pDstOutputData->remainDataLen = 0; + if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_TRUE)) { + pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; + pExynosComponent->bBehaviorEOS = OMX_FALSE; + } } else { pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; } diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Android.mk index bd76dfc..54caa40 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Android.mk @@ -25,7 +25,7 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler ifeq ($(BOARD_USES_MFC_FPS),true) diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Exynos_OMX_Vp8dec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Exynos_OMX_Vp8dec.c index e8690e1..eb3f018 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Exynos_OMX_Vp8dec.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Exynos_OMX_Vp8dec.c @@ -1181,6 +1181,7 @@ OMX_ERRORTYPE Exynos_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE; pExynosComponent->bUseFlagEOF = OMX_TRUE; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; /* H.264 Codec Open */ ret = VP8CodecOpen(pVp8Dec); @@ -1338,6 +1339,8 @@ OMX_ERRORTYPE Exynos_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) } VP8CodecClose(pVp8Dec); + Exynos_ResetAllPortConfig(pOMXComponent); + EXIT: FunctionOut(); @@ -1624,6 +1627,11 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags); pDstOutputData->remainDataLen = 0; + if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_TRUE)) { + pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; + pExynosComponent->bBehaviorEOS = OMX_FALSE; + } } else { pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; } diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/enc/Android.mk index 7c1c436..2435e0f 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/Android.mk @@ -9,6 +9,8 @@ LOCAL_MODULE := libExynosOMX_Venc LOCAL_ARM_MODE := arm LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := -DUSE_CSC_G2D + LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ $(EXYNOS_OMX_INC)/exynos \ $(EXYNOS_OMX_TOP)/osal \ diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c b/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c index b3b2eb9..e59a555 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c @@ -104,6 +104,8 @@ OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosCo pData->buffer.multiPlaneBuffer.dataBuffer[0] = pInputCodecBuffer->pVirAddr[0]; pData->buffer.multiPlaneBuffer.dataBuffer[1] = pInputCodecBuffer->pVirAddr[1]; + pData->buffer.multiPlaneBuffer.fd[0] = pInputCodecBuffer->fd[0]; + pData->buffer.multiPlaneBuffer.fd[1] = pInputCodecBuffer->fd[1]; pData->allocSize = pInputCodecBuffer->bufferSize[0] + pInputCodecBuffer->bufferSize[1]; pData->dataLen = pInputCodecBuffer->dataSize; pData->usedDataLen = 0; @@ -189,8 +191,10 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA CSC_METHOD csc_method = CSC_METHOD_SW; unsigned int cacheable = 1; - unsigned char *pSrcBuf[3] = {NULL, }; - unsigned char *pDstBuf[3] = {NULL, }; + void *pSrcBuf[3] = {NULL, }; + void *pSrcFd[3] = {NULL, }; + void *pDstBuf[3] = {NULL, }; + void *pDstFd[3] = {NULL, }; CSC_ERRORCODE cscRet = CSC_ErrorNone; @@ -202,13 +206,6 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[1]; pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[2]; - csc_get_method(pVideoEnc->csc_handle, &csc_method); - if (csc_method == CSC_METHOD_HW) { - pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.fd[0]; - pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.fd[1]; - pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.fd[2]; - } - #ifdef USE_METADATABUFFERTYPE OMX_PTR ppBuf[MAX_BUFFER_PLANE]; @@ -221,28 +218,22 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { ExynosVideoPlane planes[MAX_BUFFER_PLANE]; - OMX_U32 stride; - int imageSize; + size_t i; + csc_src_color_format = omx_2_hal_pixel_format((unsigned int)Exynos_OSAL_GetANBColorFormat(ppBuf[0])); Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, planes); - imageSize = nFrameWidth * nFrameHeight * 3; /* RGB888 */ - - if (csc_method == CSC_METHOD_HW) - pSrcBuf[0] = (unsigned char *)planes[0].fd; - else - pSrcBuf[0] = planes[0].addr; - pSrcBuf[1] = NULL; - pSrcBuf[2] = NULL; + +#if defined(USE_CSC_GSCALER) || defined(USE_CSC_G2D) + csc_method = CSC_METHOD_HW; +#endif + pSrcBuf[0] = planes[0].addr; + pSrcFd[0] = (void *)planes[0].fd; + for (i = 0; i < 3; i++) + pDstFd[i] = (void *)srcInputData->buffer.multiPlaneBuffer.fd[i]; } } else #endif { - if (csc_method == CSC_METHOD_HW) { - pSrcBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, checkInputStream); - pSrcBuf[1] = NULL; - pSrcBuf[2] = NULL; - } - switch (eColorFormat) { case OMX_COLOR_FormatYUV420Planar: /* YUV420Planar converted to YUV420Semiplanar (interleaved UV plane) as per MFC spec.*/ @@ -261,6 +252,9 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA } } + csc_set_method( + pVideoEnc->csc_handle, + csc_method); csc_set_src_format( pVideoEnc->csc_handle, /* handle */ nFrameWidth, /* width */ @@ -281,12 +275,21 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA nFrameHeight, /* crop_height */ csc_dst_color_format, /* color_format */ cacheable); /* cacheable */ - csc_set_src_buffer( - pVideoEnc->csc_handle, /* handle */ - pSrcBuf); /* YUV Addr or FD */ - csc_set_dst_buffer( - pVideoEnc->csc_handle, /* handle */ - pDstBuf); /* YUV Addr or FD */ + if (csc_method == CSC_METHOD_SW) { + csc_set_src_buffer( + pVideoEnc->csc_handle, /* handle */ + pSrcBuf); + csc_set_dst_buffer( + pVideoEnc->csc_handle, /* handle */ + pDstBuf); + } else { + csc_set_src_buffer( + pVideoEnc->csc_handle, /* handle */ + pSrcFd); + csc_set_dst_buffer( + pVideoEnc->csc_handle, /* handle */ + pDstFd); + } cscRet = csc_convert(pVideoEnc->csc_handle); if (cscRet != CSC_ErrorNone) ret = OMX_FALSE; @@ -299,8 +302,6 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA } #endif - ret = OMX_TRUE; - EXIT: FunctionOut(); @@ -340,34 +341,43 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ OMX_PTR ppBuf[MAX_BUFFER_PLANE]; OMX_PTR allocSize[MAX_BUFFER_PLANE]; int plane = 0; - if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + + if (inputUseBuffer->dataLen <= 0) { + if (!(inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { + Exynos_InputBufferReturn(pOMXComponent); + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(inputUseBuffer); + } else { + /* Make EOS Buffer for MFC Processing scheme */ + /* Use ION Allocator */ + /*Alloc Y-Buffer */ + allocSize[0] = nFrameWidth * nFrameHeight; + srcInputData->buffer.multiPlaneBuffer.dataBuffer[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, allocSize[0], NORMAL_MEMORY); + srcInputData->buffer.multiPlaneBuffer.fd[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.dataBuffer[0]); + /*Alloc C-Buffer */ + allocSize[1] = nFrameWidth * nFrameHeight >> 1; + srcInputData->buffer.multiPlaneBuffer.dataBuffer[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, allocSize[1], NORMAL_MEMORY); + srcInputData->buffer.multiPlaneBuffer.fd[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + /* input buffers are 2 plane. */ + srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; + srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; + } + } else { Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); - ExynosVideoPlane planes[MAX_BUFFER_PLANE]; - Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatYUV420SemiPlanar, planes); + if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + ExynosVideoPlane planes[MAX_BUFFER_PLANE]; - srcInputData->buffer.multiPlaneBuffer.fd[0] = planes[0].fd; - srcInputData->buffer.multiPlaneBuffer.fd[1] = planes[1].fd; - allocSize[0] = nFrameWidth * nFrameHeight; - allocSize[1] = nFrameWidth * nFrameHeight >> 1; + Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatYUV420SemiPlanar, planes); - for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { - srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = - Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.fd[plane]); - if(srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL) { - srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = - Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, allocSize[plane], srcInputData->buffer.multiPlaneBuffer.fd[plane]); - } + srcInputData->buffer.multiPlaneBuffer.fd[0] = planes[0].fd; + srcInputData->buffer.multiPlaneBuffer.fd[1] = planes[1].fd; + } else { + /* kMetadataBufferTypeCameraSource */ + srcInputData->buffer.multiPlaneBuffer.fd[0] = ppBuf[0]; + srcInputData->buffer.multiPlaneBuffer.fd[1] = ppBuf[1]; } - /* input buffers are 2 plane. */ - srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; - srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[0]); - } else { - /* kMetadataBufferTypeCameraSource */ - Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); - srcInputData->buffer.multiPlaneBuffer.fd[0] = ppBuf[0]; - srcInputData->buffer.multiPlaneBuffer.fd[1] = ppBuf[1]; allocSize[0] = nFrameWidth * nFrameHeight; allocSize[1] = nFrameWidth * nFrameHeight >> 1; @@ -382,7 +392,6 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ /* input buffers are 2 plane. */ srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[0]); } } #endif @@ -403,18 +412,30 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE"); if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) { - Exynos_CSC_InputData(pOMXComponent, srcInputData); - - inputUseBuffer->dataLen -= copySize; - inputUseBuffer->remainDataLen -= copySize; - inputUseBuffer->usedDataLen += copySize; - - srcInputData->dataLen += copySize; - srcInputData->remainDataLen += copySize; - - srcInputData->timeStamp = inputUseBuffer->timeStamp; - srcInputData->nFlags = inputUseBuffer->nFlags; - srcInputData->bufferHeader = inputUseBuffer->bufferHeader; + if ((copySize > 0) || (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { + ret = OMX_TRUE; + if (copySize > 0) + ret = Exynos_CSC_InputData(pOMXComponent, srcInputData); + if (ret) { + inputUseBuffer->dataLen -= copySize; + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + srcInputData->dataLen += copySize; + srcInputData->remainDataLen += copySize; + + srcInputData->timeStamp = inputUseBuffer->timeStamp; + srcInputData->nFlags = inputUseBuffer->nFlags; + srcInputData->bufferHeader = inputUseBuffer->bufferHeader; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_CSC_InputData() failure"); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, OMX_EventError, + OMX_ErrorUndefined, 0, NULL ); + } + } else { + ret = OMX_FALSE; + } } else { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length"); pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, @@ -433,9 +454,9 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE"); - srcInputData->dataLen = 0; - srcInputData->remainDataLen = 0; pExynosComponent->bSaveFlagEOS = OMX_TRUE; + if (srcInputData->dataLen != 0) + pExynosComponent->bBehaviorEOS = OMX_TRUE; } if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { @@ -546,7 +567,6 @@ OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent) int i = 0; OMX_PTR ppBuf[MAX_BUFFER_PLANE]; - /* kMetadataBufferTypeGrallocSource */ if (exynosInputPort->bStoreMetaData == OMX_TRUE) { Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)srcInputUseBuffer->bufferHeader->pBuffer, ppBuf); @@ -589,9 +609,9 @@ OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent) pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1; pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0; - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); } @@ -604,7 +624,6 @@ OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent) } } - EXIT: return ret; @@ -661,6 +680,10 @@ OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent) if ((bCheckInputData == OMX_FALSE) && (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { ret = Exynos_InputBufferGetQueue(pExynosComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + break; + } #ifdef USE_METADATABUFFERTYPE if ((pVideoEnc->bFirstInput == OMX_TRUE) && (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { @@ -1071,6 +1094,9 @@ OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent) Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstOutputThread); pVideoEnc->hDstOutputThread = NULL; + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + EXIT: FunctionOut(); @@ -1085,6 +1111,8 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone EXYNOS_OMX_BASEPORT *pExynosPort = NULL; EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + CSC_METHOD csc_method = CSC_METHOD_SW; + FunctionIn(); if (hComponent == NULL) { @@ -1125,6 +1153,7 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; pVideoEnc->bFirstInput = OMX_FALSE; pVideoEnc->bFirstOutput = OMX_FALSE; @@ -1133,6 +1162,24 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter + pVideoEnc->csc_handle = csc_init(csc_method); + if (pVideoEnc->csc_handle == NULL) { + Exynos_OSAL_Free(pVideoEnc); + Exynos_OMX_BaseComponent_Destructor(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + pVideoEnc->csc_set_format = OMX_FALSE; +#if defined(USE_CSC_GSCALER) && defined(USE_CSC_G2D) +#error USE_CSC_GSCALER and USE_CSC_G2D are mutually exclusive +#elif defined(USE_CSC_GSCALER) + csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, CSC_GSCALER_IDX); + csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER); +#elif defined(USE_CSC_G2D) + csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_G2D); +#endif + pExynosComponent->bMultiThreadProcess = OMX_TRUE; /* Input port */ @@ -1229,6 +1276,11 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hCompo pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + if (pVideoEnc->csc_handle != NULL) { + csc_deinit(pVideoEnc->csc_handle); + pVideoEnc->csc_handle = NULL; + } + Exynos_OSAL_Free(pVideoEnc); pExynosComponent->hComponentHandle = pVideoEnc = NULL; diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_VencControl.c b/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_VencControl.c index 42bcc38..aa1315b 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_VencControl.c +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_VencControl.c @@ -548,6 +548,7 @@ OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 n Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); pExynosComponent->getAllDelayBuffer = OMX_FALSE; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; pExynosComponent->reInputData = OMX_FALSE; } @@ -751,7 +752,6 @@ OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) } if ((bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - bufferHeader->nFilledLen = 0; Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"event OMX_BUFFERFLAG_EOS!!!"); pExynosComponent->pCallbacks->EventHandler(pOMXComponent, pExynosComponent->callbackData, @@ -797,7 +797,6 @@ OMX_ERRORTYPE Exynos_FlushOutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, E } if ((bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - bufferHeader->nFilledLen = 0; Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"event OMX_BUFFERFLAG_EOS!!!"); pExynosComponent->pCallbacks->EventHandler(pOMXComponent, pExynosComponent->callbackData, diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Android.mk index 9a9174e..074d506 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Android.mk @@ -22,7 +22,7 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c b/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c index d25503d..497366b 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c @@ -1533,7 +1533,6 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) ExynosVideoEncBufferOps *pInbufOps = NULL; ExynosVideoEncBufferOps *pOutbufOps = NULL; - CSC_METHOD csc_method = CSC_METHOD_SW; int i = 0; FunctionIn(); @@ -1542,6 +1541,7 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE; pExynosComponent->bUseFlagEOF = OMX_TRUE; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat; if (pExynosInputPort->bStoreMetaData == OMX_TRUE) { @@ -1596,9 +1596,9 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1; pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0; - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); } @@ -1632,16 +1632,6 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; -#if 0//defined(USE_CSC_GSCALER) - csc_method = CSC_METHOD_HW; //in case of Use ION buffer. -#endif - pVideoEnc->csc_handle = csc_init(csc_method); - if (pVideoEnc->csc_handle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoEnc->csc_set_format = OMX_FALSE; - EXIT: FunctionOut(); @@ -1667,11 +1657,6 @@ OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) FunctionIn(); - if (pVideoEnc->csc_handle != NULL) { - csc_deinit(pVideoEnc->csc_handle); - pVideoEnc->csc_handle = NULL; - } - Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent); pH264Enc->hDestinationStartEvent = NULL; pH264Enc->bDestinationStart = OMX_FALSE; @@ -2010,10 +1995,14 @@ OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX } if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || - ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_FALSE))) { Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags); pDstOutputData->remainDataLen = 0; } + if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_TRUE)) + pExynosComponent->bBehaviorEOS = OMX_FALSE; ret = OMX_ErrorNone; diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Android.mk index dbd44f5..e1c5af6 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Android.mk @@ -21,7 +21,7 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c b/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c index f58ee45..51c20b7 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c @@ -1749,7 +1749,6 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) ExynosVideoEncBufferOps *pInbufOps = NULL; ExynosVideoEncBufferOps *pOutbufOps = NULL; - CSC_METHOD csc_method = CSC_METHOD_SW; int i = 0; FunctionIn(); @@ -1758,6 +1757,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE; pExynosComponent->bUseFlagEOF = OMX_TRUE; pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat; if (pExynosInputPort->bStoreMetaData == OMX_TRUE) { @@ -1812,9 +1812,9 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1; pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0; - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); } @@ -1848,16 +1848,6 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; -#if 0//defined(USE_CSC_GSCALER) - csc_method = CSC_METHOD_HW; //in case of Use ION buffer. -#endif - pVideoEnc->csc_handle = csc_init(csc_method); - if (pVideoEnc->csc_handle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoEnc->csc_set_format = OMX_FALSE; - EXIT: FunctionOut(); @@ -1883,11 +1873,6 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) FunctionIn(); - if (pVideoEnc->csc_handle != NULL) { - csc_deinit(pVideoEnc->csc_handle); - pVideoEnc->csc_handle = NULL; - } - Exynos_OSAL_SignalTerminate(pMpeg4Enc->hDestinationStartEvent); pMpeg4Enc->hDestinationStartEvent = NULL; pMpeg4Enc->bDestinationStart = OMX_FALSE; @@ -2213,10 +2198,14 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM } if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || - ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_FALSE))) { Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags); pDstOutputData->remainDataLen = 0; } + if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_TRUE)) + pExynosComponent->bBehaviorEOS = OMX_FALSE; ret = OMX_ErrorNone; diff --git a/exynos_omx/openmax/exynos_omx/core/Android.mk b/exynos_omx/openmax/exynos_omx/core/Android.mk index 0e0bcb6..7de591d 100644 --- a/exynos_omx/openmax/exynos_omx/core/Android.mk +++ b/exynos_omx/openmax/exynos_omx/core/Android.mk @@ -15,7 +15,7 @@ LOCAL_CFLAGS := LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_OSAL libExynosOMX_Basecomponent -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils \ +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog \ libExynosOMX_Resourcemanager LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ @@ -24,4 +24,3 @@ LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ $(EXYNOS_OMX_TOP)/component/common include $(BUILD_SHARED_LIBRARY) - diff --git a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp index 142580c..3a823f6 100644 --- a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp +++ b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp @@ -612,7 +612,8 @@ OMX_COLOR_FORMATTYPE Exynos_OSAL_Hal2OMXPixelFormat( case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; break; - case HAL_PIXEL_FORMAT_ARGB888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: omx_format = OMX_COLOR_Format32bitARGB8888; break; default: @@ -643,7 +644,7 @@ unsigned int Exynos_OSAL_OMX2HalPixelFormat( hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; break; case OMX_COLOR_Format32bitARGB8888: - hal_format = HAL_PIXEL_FORMAT_ARGB888; + hal_format = HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888; break; default: hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; diff --git a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.h b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.h index cfe8c36..ee1e342 100644 --- a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.h +++ b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.h @@ -37,6 +37,8 @@ extern "C" { #endif +OMX_COLOR_FORMATTYPE Exynos_OSAL_GetANBColorFormat(OMX_IN OMX_U32 handle); + OMX_ERRORTYPE Exynos_OSAL_GetANBParameter(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_INDEXTYPE nIndex, OMX_INOUT OMX_PTR ComponentParameterStructure); diff --git a/gralloc/framebuffer.cpp b/gralloc/framebuffer.cpp index c1d4ce9..ce409ce 100644 --- a/gralloc/framebuffer.cpp +++ b/gralloc/framebuffer.cpp @@ -105,6 +105,52 @@ static int fb_close(struct hw_device_t *dev) return 0; } +static void get_screen_res(const char *fbname, int32_t *xres, int32_t *yres, + int32_t *refresh) +{ + char *path; + int fd; + char buf[128]; + int ret; + unsigned int _x, _y, _r; + + asprintf(&path, "/sys/class/graphics/%s/modes", fbname); + if (!path) + goto err_asprintf; + fd = open(path, O_RDONLY); + if (fd < 0) + goto err_open; + ret = read(fd, buf, sizeof(buf)); + if (ret <= 0) + goto err_read; + buf[sizeof(buf)-1] = '\0'; + + ret = sscanf(buf, "U:%ux%up-%u", &_x, &_y, &_r); + if (ret != 3) + goto err_sscanf; + + ALOGI("Using %ux%u %uHz resolution for '%s' from modes list\n", + _x, _y, _r, fbname); + + *xres = (int32_t)_x; + *yres = (int32_t)_y; + *refresh = (int32_t)_r; + + close(fd); + free(path); + return; + +err_sscanf: +err_read: + close(fd); +err_open: + free(path); +err_asprintf: + *xres = 2560; + *yres = 1600; + *refresh = 60; +} + int init_fb(struct private_module_t* module) { char const * const device_template[] = { @@ -135,19 +181,13 @@ int init_fb(struct private_module_t* module) return -errno; } - int refreshRate = 1000000000000000LLU / - ( - uint64_t( info.upper_margin + info.lower_margin + info.yres ) - * ( info.left_margin + info.right_margin + info.xres ) - * info.pixclock - ); - + int32_t refreshRate; + get_screen_res("fb0", &module->xres, &module->yres, &refreshRate); if (refreshRate == 0) - refreshRate = 60*1000; /* 60 Hz */ + refreshRate = 60; /* 60 Hz */ - float xdpi = (info.xres * 25.4f) / info.width; - float ydpi = (info.yres * 25.4f) / info.height; - float fps = refreshRate / 1000.0f; + float xdpi = (module->xres * 25.4f) / info.width; + float ydpi = (module->yres * 25.4f) / info.height; ALOGI("using (id=%s)\n" "xres = %d px\n" @@ -155,15 +195,13 @@ int init_fb(struct private_module_t* module) "width = %d mm (%f dpi)\n" "height = %d mm (%f dpi)\n" "refresh rate = %.2f Hz\n", - finfo.id, info.xres, info.yres, info.width, xdpi, info.height, ydpi, - fps); + finfo.id, module->xres, module->yres, info.width, xdpi, info.height, + ydpi, (float)refreshRate); - module->xres = 2560; - module->yres = 1600; - module->line_length = 2560; + module->line_length = module->xres * 4; module->xdpi = xdpi; module->ydpi = ydpi; - module->fps = fps; + module->fps = (float)refreshRate; return 0; } diff --git a/gralloc/gralloc.cpp b/gralloc/gralloc.cpp index f3610f3..cdfa70f 100644 --- a/gralloc/gralloc.cpp +++ b/gralloc/gralloc.cpp @@ -44,10 +44,13 @@ #include "exynos_format.h" #include "gr.h" -#define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4) +#define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4) #define ION_EXYNOS_FIMD_VIDEO_MASK (1 << 28) #define ION_EXYNOS_MFC_OUTPUT_MASK (1 << 26) #define ION_EXYNOS_MFC_INPUT_MASK (1 << 25) +#define ION_HEAP_SYSTEM_ID 0 +#define ION_HEAP_EXYNOS_CONTIG_ID 4 +#define ION_HEAP_CHUNK_ID 6 #define MB_1 (1024*1024) @@ -121,9 +124,9 @@ static unsigned int _select_heap(int usage) unsigned int heap_mask; if (usage & GRALLOC_USAGE_PROTECTED) - heap_mask = ION_HEAP_EXYNOS_CONTIG_MASK; + heap_mask = (1 << ION_HEAP_EXYNOS_CONTIG_ID); else - heap_mask = ION_HEAP_SYSTEM_MASK; + heap_mask = (1 << ION_HEAP_SYSTEM_ID) | (1 << ION_HEAP_CHUNK_ID); return heap_mask; } @@ -160,7 +163,7 @@ static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int usage, } if (format != HAL_PIXEL_FORMAT_BLOB) { - bpr = ALIGN(w*bpp, 16); + bpr = ALIGN(w*bpp, 64); vstride = ALIGN(h, 16); if (vstride < h + 2) size = bpr * (h + 2); @@ -189,6 +192,7 @@ static int gralloc_alloc_framework_yuv(int ionfd, int w, int h, int format, { size_t size; int err, fd; + unsigned int heap_mask = _select_heap(usage); switch (format) { case HAL_PIXEL_FORMAT_YV12: @@ -204,8 +208,7 @@ static int gralloc_alloc_framework_yuv(int ionfd, int w, int h, int format, return -EINVAL; } - err = ion_alloc_fd(ionfd, size, 0, 1 << ION_HEAP_TYPE_SYSTEM, - ion_flags, &fd); + err = ion_alloc_fd(ionfd, size, 0, heap_mask, ion_flags, &fd); if (err) return err; @@ -297,6 +300,16 @@ static int gralloc_alloc_yuv(int ionfd, int w, int h, int format, *stride, luma_vstride); } } + // Set chroma & gamut fields + if (!err && *hnd) { + if (usage & GRALLOC_USAGE_PRIVATE_CHROMA) { + (*hnd)->chroma = HAL_PIXEL_CHROMA_BT601_8; + (*hnd)->gamut = HAL_PIXEL_GAMUT_NARROW_8; + } else { + (*hnd)->chroma = HAL_PIXEL_CHROMA_BT709_8; + (*hnd)->gamut = HAL_PIXEL_GAMUT_WIDE_8; + } + } return err; err2: diff --git a/include/exynos_format.h b/include/exynos_format.h index f4c0466..aca1103 100644 --- a/include/exynos_format.h +++ b/include/exynos_format.h @@ -30,7 +30,7 @@ enum { HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x105, HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x106, HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED = 0x107, - HAL_PIXEL_FORMAT_ARGB888 = 0x108, + HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888 = 0x108, // support custom format for zero copy HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP = 0x110, HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP = 0x111, @@ -48,6 +48,24 @@ enum { HAL_PIXEL_FORMAT_CUSTOM_MAX }; +// Gamut (colorspace range) +enum { + HAL_PIXEL_GAMUT_DEFAULT = 0, + // Values range 0-255 + HAL_PIXEL_GAMUT_WIDE_8, + // Values range 16-235 + HAL_PIXEL_GAMUT_NARROW_8 +}; + +// Chromaticities (colorspace parameters) +enum { + HAL_PIXEL_CHROMA_DEFAULT = 0, + // BT.601 "Standard Definition" color space + HAL_PIXEL_CHROMA_BT601_8, + // BT.709 "High Definition" color space + HAL_PIXEL_CHROMA_BT709_8 +}; + struct ADDRS { unsigned int addr_y; unsigned int addr_cbcr; diff --git a/include/fimg2d.h b/include/fimg2d.h new file mode 100644 index 0000000..59da4a6 --- /dev/null +++ b/include/fimg2d.h @@ -0,0 +1,262 @@ +/**************************************************************************** + **************************************************************************** + *** + *** This header was automatically generated from a Linux kernel header + *** of the same name, to make information necessary for userspace to + *** call into the kernel available to libc. It contains only constants, + *** structures, and macros generated from the original header, and thus, + *** contains no copyrightable information. + *** + *** To edit the content of this header, modify the corresponding + *** source file (e.g. under external/kernel-headers/original/) then + *** run bionic/libc/kernel/tools/update_all.py + *** + *** Any manual change here will be lost the next time this script will + *** be run. You've been warned! + *** + **************************************************************************** + ****************************************************************************/ +#ifndef __FIMG2D_H +#define __FIMG2D_H __FILE__ +#define FIMG2D_MAX_PLANES 2 +#define FIMG2D_IOCTL_MAGIC 'F' +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define FIMG2D_BITBLT_BLIT _IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit) +#define FIMG2D_BITBLT_SYNC _IOW(FIMG2D_IOCTL_MAGIC, 1, int) +#define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version) +struct fimg2d_version { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + unsigned int hw; + unsigned int sw; +}; +enum blit_sync { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_SYNC, + BLIT_ASYNC, +}; +enum addr_space { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + ADDR_NONE = 0, + ADDR_DMA_BUF, +}; +enum pixel_order { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + AX_RGB = 0, + RGB_AX, + AX_BGR, + BGR_AX, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + ARGB_ORDER_END, + P1_CRY1CBY0, + P1_CBY1CRY0, + P1_Y1CRY0CB, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + P1_Y1CBY0CR, + P1_ORDER_END, + P2_CRCB, + P2_CBCR, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + P2_ORDER_END, +}; +enum color_format { + CF_XRGB_8888 = 0, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + CF_ARGB_8888, + CF_RGB_565, + CF_XRGB_1555, + CF_ARGB_1555, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + CF_XRGB_4444, + CF_ARGB_4444, + CF_RGB_888, + CF_YCBCR_444, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + CF_YCBCR_422, + CF_YCBCR_420, + CF_A8, + CF_L8, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + SRC_DST_FORMAT_END, + CF_MSK_1BIT, + CF_MSK_4BIT, + CF_MSK_8BIT, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + CF_MSK_16BIT_565, + CF_MSK_16BIT_1555, + CF_MSK_16BIT_4444, + CF_MSK_32BIT_8888, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + MSK_FORMAT_END, +}; +enum rotation { + ORIGIN, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + ROT_90, + ROT_180, + ROT_270, + XFLIP, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + YFLIP, +}; +enum repeat { + NO_REPEAT = 0, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + REPEAT_NORMAL, + REPEAT_PAD, + REPEAT_REFLECT, REPEAT_MIRROR = REPEAT_REFLECT, + REPEAT_CLAMP, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +enum scaling { + NO_SCALING, + SCALING_NEAREST, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + SCALING_BILINEAR, +}; +enum scaling_factor { + SCALING_PIXELS, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + SCALING_RATIO, +}; +enum premultiplied { + PREMULTIPLIED, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + NON_PREMULTIPLIED, +}; +enum bluescreen { + OPAQUE, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + TRANSP, + BLUSCR, +}; +enum blit_op { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_SOLID_FILL = 0, + BLIT_OP_CLR, + BLIT_OP_SRC, BLIT_OP_SRC_COPY = BLIT_OP_SRC, + BLIT_OP_DST, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_SRC_OVER, + BLIT_OP_DST_OVER, BLIT_OP_OVER_REV = BLIT_OP_DST_OVER, + BLIT_OP_SRC_IN, + BLIT_OP_DST_IN, BLIT_OP_IN_REV = BLIT_OP_DST_IN, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_SRC_OUT, + BLIT_OP_DST_OUT, BLIT_OP_OUT_REV = BLIT_OP_DST_OUT, + BLIT_OP_SRC_ATOP, + BLIT_OP_DST_ATOP, BLIT_OP_ATOP_REV = BLIT_OP_DST_ATOP, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_XOR, + BLIT_OP_ADD, + BLIT_OP_MULTIPLY, + BLIT_OP_SCREEN, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_DARKEN, + BLIT_OP_LIGHTEN, + BLIT_OP_DISJ_SRC_OVER, + BLIT_OP_DISJ_DST_OVER, BLIT_OP_SATURATE = BLIT_OP_DISJ_DST_OVER, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_DISJ_SRC_IN, + BLIT_OP_DISJ_DST_IN, BLIT_OP_DISJ_IN_REV = BLIT_OP_DISJ_DST_IN, + BLIT_OP_DISJ_SRC_OUT, + BLIT_OP_DISJ_DST_OUT, BLIT_OP_DISJ_OUT_REV = BLIT_OP_DISJ_DST_OUT, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_DISJ_SRC_ATOP, + BLIT_OP_DISJ_DST_ATOP, BLIT_OP_DISJ_ATOP_REV = BLIT_OP_DISJ_DST_ATOP, + BLIT_OP_DISJ_XOR, + BLIT_OP_CONJ_SRC_OVER, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_CONJ_DST_OVER, BLIT_OP_CONJ_OVER_REV = BLIT_OP_CONJ_DST_OVER, + BLIT_OP_CONJ_SRC_IN, + BLIT_OP_CONJ_DST_IN, BLIT_OP_CONJ_IN_REV = BLIT_OP_CONJ_DST_IN, + BLIT_OP_CONJ_SRC_OUT, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_CONJ_DST_OUT, BLIT_OP_CONJ_OUT_REV = BLIT_OP_CONJ_DST_OUT, + BLIT_OP_CONJ_SRC_ATOP, + BLIT_OP_CONJ_DST_ATOP, BLIT_OP_CONJ_ATOP_REV = BLIT_OP_CONJ_DST_ATOP, + BLIT_OP_CONJ_XOR, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + BLIT_OP_USER_COEFF, + BLIT_OP_USER_SRC_GA, + BLIT_OP_END, +}; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define MAX_FIMG2D_BLIT_OP (int)BLIT_OP_END +struct fimg2d_addr { + enum addr_space type; + int fd[FIMG2D_MAX_PLANES]; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +struct fimg2d_rect { + int x1; + int y1; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + int x2; + int y2; +}; +struct fimg2d_scale { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + enum scaling mode; + int src_w, src_h; + int dst_w, dst_h; +}; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +struct fimg2d_clip { + __u32 enable; + int x1; + int y1; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + int x2; + int y2; +}; +struct fimg2d_repeat { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + enum repeat mode; + unsigned long pad_color; +}; +struct fimg2d_bluscr { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + enum bluescreen mode; + unsigned long bs_color; + unsigned long bg_color; +}; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +struct fimg2d_image { + int width; + int height; + int stride; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + enum pixel_order order; + enum color_format fmt; + struct fimg2d_addr addr; + struct fimg2d_rect rect; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +struct fimg2d_param { + unsigned long solid_color; + unsigned char g_alpha; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 dither; + enum rotation rotate; + enum premultiplied premult; + struct fimg2d_scale scaling; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + struct fimg2d_repeat repeat; + struct fimg2d_bluscr bluscr; + struct fimg2d_clip clipping; +}; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +struct fimg2d_blit { + enum blit_op op; + struct fimg2d_param param; + struct fimg2d_image *src; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + struct fimg2d_image *msk; + struct fimg2d_image *tmp; + struct fimg2d_image *dst; + enum blit_sync sync; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + unsigned int seq_no; +}; +#endif + diff --git a/include/gralloc_priv.h b/include/gralloc_priv.h index 7cec618..bf2940e 100644 --- a/include/gralloc_priv.h +++ b/include/gralloc_priv.h @@ -37,7 +37,7 @@ struct private_handle_t; struct private_module_t { gralloc_module_t base; - private_handle_t* framebuffer; + struct private_handle_t* framebuffer; uint32_t flags; uint32_t numBuffers; uint32_t bufferMask; @@ -65,6 +65,9 @@ struct private_handle_t { struct native_handle nativeHandle; #endif +// set if using video encoding colorspace +#define GRALLOC_USAGE_PRIVATE_CHROMA (GRALLOC_USAGE_PRIVATE_0) + enum { PRIV_FLAGS_FRAMEBUFFER = 0x00000001, PRIV_FLAGS_USES_UMP = 0x00000002, @@ -86,6 +89,8 @@ struct private_handle_t { int height; int stride; int vstride; + int gamut; + int chroma; // FIXME: the attributes below should be out-of-line void *base; @@ -97,7 +102,7 @@ struct private_handle_t { #ifdef __cplusplus static const int sNumFds = 3; - static const int sNumInts = 15; + static const int sNumInts = 17; static const int sMagic = 0x3141592; @@ -105,7 +110,8 @@ struct private_handle_t { int h, int format, int stride, int vstride) : fd(fd), fd1(-1), fd2(-1), magic(sMagic), flags(flags), size(size), offset(0), format(format), width(w), height(h), stride(stride), - vstride(vstride), base(0), handle(0), handle1(0), handle2(0) + vstride(vstride), gamut(0), chroma(0), base(0), handle(0), handle1(0), + handle2(0) { version = sizeof(native_handle); numInts = sNumInts + 2; @@ -116,8 +122,8 @@ struct private_handle_t { int h, int format, int stride, int vstride) : fd(fd), fd1(fd1), fd2(-1), magic(sMagic), flags(flags), size(size), offset(0), format(format), width(w), height(h), stride(stride), - vstride(vstride), base(0), base1(0), base2(0), handle(0), handle1(0), - handle2(0) + vstride(vstride), gamut(0), chroma(0), base(0), base1(0), base2(0), + handle(0), handle1(0), handle2(0) { version = sizeof(native_handle); numInts = sNumInts + 1; @@ -128,8 +134,8 @@ struct private_handle_t { int h, int format, int stride, int vstride) : fd(fd), fd1(fd1), fd2(fd2), magic(sMagic), flags(flags), size(size), offset(0), format(format), width(w), height(h), stride(stride), - vstride(vstride), base(0), base1(0), base2(0), handle(0), handle1(0), - handle2(0) + vstride(vstride), gamut(0), chroma(0), base(0), base1(0), base2(0), + handle(0), handle1(0), handle2(0) { version = sizeof(native_handle); numInts = sNumInts; diff --git a/include/ion.h b/include/ion.h index 0c6045e..e790cb4 100644 --- a/include/ion.h +++ b/include/ion.h @@ -20,6 +20,7 @@ #include <unistd.h> /* size_t */ #define ION_FLAG_CACHED 1 +#define ION_FLAG_CACHED_NEEDS_SYNC 2 #define ION_HEAP_SYSTEM_MASK (1 << 0) #define ION_HEAP_SYSTEM_CONTIG_MASK (1 << 1) diff --git a/include/videodev2.h b/include/videodev2.h index f3ca644..c1c8cd0 100644 --- a/include/videodev2.h +++ b/include/videodev2.h @@ -680,6 +680,8 @@ struct v4l2_buffer { #define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000 /* Expects and returns a sync fence */ #define V4L2_BUF_FLAG_USE_SYNC 0x2000 +/* Buffer is end of stream */ +#define V4L2_BUF_FLAG_LAST_FRAME 0x4000 /* * O V E R L A Y P R E V I E W diff --git a/libcamera2/ExynosCamera2.cpp b/libcamera2/ExynosCamera2.cpp index 100f0a8..3ae6590 100644 --- a/libcamera2/ExynosCamera2.cpp +++ b/libcamera2/ExynosCamera2.cpp @@ -88,7 +88,7 @@ const nsecs_t Sensor::kExposureTimeRange[2] = const nsecs_t Sensor::kFrameDurationRange[2] = {33331760L, 30000000000L}; // ~1/30 s - 30 sec -const uint8_t Sensor::kColorFilterArrangement = ANDROID_SENSOR_RGGB; +const uint8_t Sensor::kColorFilterArrangement = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB; const uint32_t kAvailableFormats[5] = { HAL_PIXEL_FORMAT_RAW_SENSOR, @@ -149,38 +149,38 @@ const int32_t jpegResolutionS5K4E5[] = const uint8_t availableAfModesS5K4E5[] = { - ANDROID_CONTROL_AF_OFF, - ANDROID_CONTROL_AF_AUTO, - ANDROID_CONTROL_AF_MACRO, - ANDROID_CONTROL_AF_CONTINUOUS_PICTURE, - ANDROID_CONTROL_AF_CONTINUOUS_VIDEO + ANDROID_CONTROL_AF_MODE_OFF, + ANDROID_CONTROL_AF_MODE_AUTO, + ANDROID_CONTROL_AF_MODE_MACRO, + ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE, + ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO }; const uint8_t sceneModeOverridesS5K4E5[] = { // ANDROID_CONTROL_SCENE_MODE_ACTION - ANDROID_CONTROL_AE_ON, - ANDROID_CONTROL_AWB_AUTO, - ANDROID_CONTROL_AF_CONTINUOUS_PICTURE, + ANDROID_CONTROL_AE_MODE_ON, + ANDROID_CONTROL_AWB_MODE_AUTO, + ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE, // ANDROID_CONTROL_SCENE_MODE_NIGHT - ANDROID_CONTROL_AE_ON, - ANDROID_CONTROL_AWB_AUTO, - ANDROID_CONTROL_AF_CONTINUOUS_PICTURE, + ANDROID_CONTROL_AE_MODE_ON, + ANDROID_CONTROL_AWB_MODE_AUTO, + ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE, // ANDROID_CONTROL_SCENE_MODE_SUNSET - ANDROID_CONTROL_AE_ON, - ANDROID_CONTROL_AWB_DAYLIGHT, - ANDROID_CONTROL_AF_CONTINUOUS_PICTURE, + ANDROID_CONTROL_AE_MODE_ON, + ANDROID_CONTROL_AWB_MODE_DAYLIGHT, + ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE, // ANDROID_CONTROL_SCENE_MODE_PARTY - ANDROID_CONTROL_AE_ON_AUTO_FLASH, - ANDROID_CONTROL_AWB_AUTO, - ANDROID_CONTROL_AF_CONTINUOUS_PICTURE + ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH, + ANDROID_CONTROL_AWB_MODE_AUTO, + ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE }; const uint8_t availableAeModesS5K4E5[] = { - ANDROID_CONTROL_AE_OFF, - ANDROID_CONTROL_AE_ON, - ANDROID_CONTROL_AE_ON_AUTO_FLASH + ANDROID_CONTROL_AE_MODE_OFF, + ANDROID_CONTROL_AE_MODE_ON, + ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH }; ExynosCamera2InfoS5K4E5::ExynosCamera2InfoS5K4E5() @@ -245,33 +245,33 @@ const int32_t jpegResolutionS5K6A3[] = const uint8_t availableAfModesS5K6A3[] = { - ANDROID_CONTROL_AF_OFF + ANDROID_CONTROL_AF_MODE_OFF }; const uint8_t sceneModeOverridesS5K6A3[] = { // ANDROID_CONTROL_SCENE_MODE_ACTION - ANDROID_CONTROL_AE_ON, - ANDROID_CONTROL_AWB_AUTO, - ANDROID_CONTROL_AF_OFF, + ANDROID_CONTROL_AE_MODE_ON, + ANDROID_CONTROL_AWB_MODE_AUTO, + ANDROID_CONTROL_AF_MODE_OFF, // ANDROID_CONTROL_SCENE_MODE_NIGHT - ANDROID_CONTROL_AE_ON, - ANDROID_CONTROL_AWB_AUTO, - ANDROID_CONTROL_AF_OFF, + ANDROID_CONTROL_AE_MODE_ON, + ANDROID_CONTROL_AWB_MODE_AUTO, + ANDROID_CONTROL_AF_MODE_OFF, // ANDROID_CONTROL_SCENE_MODE_SUNSET - ANDROID_CONTROL_AE_ON, - ANDROID_CONTROL_AWB_DAYLIGHT, - ANDROID_CONTROL_AF_OFF, + ANDROID_CONTROL_AE_MODE_ON, + ANDROID_CONTROL_AWB_MODE_DAYLIGHT, + ANDROID_CONTROL_AF_MODE_OFF, // ANDROID_CONTROL_SCENE_MODE_PARTY - ANDROID_CONTROL_AE_ON, - ANDROID_CONTROL_AWB_AUTO, - ANDROID_CONTROL_AF_OFF + ANDROID_CONTROL_AE_MODE_ON, + ANDROID_CONTROL_AWB_MODE_AUTO, + ANDROID_CONTROL_AF_MODE_OFF }; const uint8_t availableAeModesS5K6A3[] = { - ANDROID_CONTROL_AE_OFF, - ANDROID_CONTROL_AE_ON + ANDROID_CONTROL_AE_MODE_OFF, + ANDROID_CONTROL_AE_MODE_ON }; ExynosCamera2InfoS5K6A3::ExynosCamera2InfoS5K6A3() @@ -392,33 +392,39 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, if ( ( ret = addOrSize(*info, sizeRequest, &entryCount, &dataCount, \ tag, data, count) ) != OK ) return ret + // android.info + + int32_t hardwareLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL; + ADD_OR_SIZE(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, + &hardwareLevel, 1); + // android.lens - ADD_OR_SIZE(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, + ADD_OR_SIZE(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &(m_curCameraInfo->minFocusDistance), 1); - ADD_OR_SIZE(ANDROID_LENS_HYPERFOCAL_DISTANCE, + ADD_OR_SIZE(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, &(m_curCameraInfo->minFocusDistance), 1); - ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS, + ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &m_curCameraInfo->focalLength, 1); - ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_APERTURES, + ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_APERTURES, &m_curCameraInfo->aperture, 1); static const float filterDensity = 0; - ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_FILTER_DENSITY, + ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES, &filterDensity, 1); static const uint8_t availableOpticalStabilization = - ANDROID_LENS_OPTICAL_STABILIZATION_OFF; - ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_OPTICAL_STABILIZATION, + ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; + ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, &availableOpticalStabilization, 1); static const int32_t lensShadingMapSize[] = {1, 1}; - ADD_OR_SIZE(ANDROID_LENS_SHADING_MAP_SIZE, lensShadingMapSize, + ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize, sizeof(lensShadingMapSize)/sizeof(int32_t)); static const float lensShadingMap[3 * 1 * 1 ] = { 1.f, 1.f, 1.f }; - ADD_OR_SIZE(ANDROID_LENS_SHADING_MAP, lensShadingMap, + ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP, lensShadingMap, sizeof(lensShadingMap)/sizeof(float)); int32_t lensFacing = cameraId ? @@ -426,31 +432,32 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, ADD_OR_SIZE(ANDROID_LENS_FACING, &lensFacing, 1); // android.sensor - ADD_OR_SIZE(ANDROID_SENSOR_EXPOSURE_TIME_RANGE, + ADD_OR_SIZE(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, Sensor::kExposureTimeRange, 2); - ADD_OR_SIZE(ANDROID_SENSOR_MAX_FRAME_DURATION, + ADD_OR_SIZE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, &Sensor::kFrameDurationRange[1], 1); - ADD_OR_SIZE(ANDROID_SENSOR_AVAILABLE_SENSITIVITIES, + ADD_OR_SIZE(ANDROID_SENSOR_INFO_AVAILABLE_SENSITIVITIES, Sensor::kAvailableSensitivities, sizeof(Sensor::kAvailableSensitivities) /sizeof(uint32_t)); - ADD_OR_SIZE(ANDROID_SENSOR_COLOR_FILTER_ARRANGEMENT, + ADD_OR_SIZE(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, &Sensor::kColorFilterArrangement, 1); - static const float sensorPhysicalSize[2] = {3.20f, 2.40f}; // mm - ADD_OR_SIZE(ANDROID_SENSOR_PHYSICAL_SIZE, + // Empirically derived to get correct FOV measurements + static const float sensorPhysicalSize[2] = {3.50f, 2.625f}; // mm + ADD_OR_SIZE(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, sensorPhysicalSize, 2); int32_t pixelArraySize[2] = { m_curCameraInfo->sensorW, m_curCameraInfo->sensorH }; - ADD_OR_SIZE(ANDROID_SENSOR_PIXEL_ARRAY_SIZE, pixelArraySize, 2); - ADD_OR_SIZE(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, pixelArraySize,2); + ADD_OR_SIZE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArraySize, 2); + ADD_OR_SIZE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, pixelArraySize,2); - ADD_OR_SIZE(ANDROID_SENSOR_WHITE_LEVEL, + ADD_OR_SIZE(ANDROID_SENSOR_INFO_WHITE_LEVEL, &Sensor::kMaxRawValue, 1); static const int32_t blackLevelPattern[4] = { @@ -468,10 +475,10 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, flashAvailable = 1; else flashAvailable = 0; - ADD_OR_SIZE(ANDROID_FLASH_AVAILABLE, &flashAvailable, 1); + ADD_OR_SIZE(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1); static const int64_t flashChargeDuration = 0; - ADD_OR_SIZE(ANDROID_FLASH_CHARGE_DURATION, &flashChargeDuration, 1); + ADD_OR_SIZE(ANDROID_FLASH_INFO_CHARGE_DURATION, &flashChargeDuration, 1); // android.tonemap @@ -511,7 +518,7 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, sizeof(kAvailableJpegMinDurations)/sizeof(uint64_t)); static const float maxZoom = 4; - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, &maxZoom, 1); + ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxZoom, 1); // android.jpeg @@ -532,31 +539,31 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, // android.stats static const uint8_t availableFaceDetectModes[] = { - ANDROID_STATS_FACE_DETECTION_OFF, - ANDROID_STATS_FACE_DETECTION_FULL + ANDROID_STATISTICS_FACE_DETECT_MODE_OFF, + ANDROID_STATISTICS_FACE_DETECT_MODE_FULL }; - ADD_OR_SIZE(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES, + ADD_OR_SIZE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, availableFaceDetectModes, sizeof(availableFaceDetectModes)); m_curCameraInfo->maxFaceCount = CAMERA2_MAX_FACES; - ADD_OR_SIZE(ANDROID_STATS_MAX_FACE_COUNT, + ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &(m_curCameraInfo->maxFaceCount), 1); static const int32_t histogramSize = 64; - ADD_OR_SIZE(ANDROID_STATS_HISTOGRAM_BUCKET_COUNT, + ADD_OR_SIZE(ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT, &histogramSize, 1); static const int32_t maxHistogramCount = 1000; - ADD_OR_SIZE(ANDROID_STATS_MAX_HISTOGRAM_COUNT, + ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT, &maxHistogramCount, 1); static const int32_t sharpnessMapSize[2] = {64, 64}; - ADD_OR_SIZE(ANDROID_STATS_SHARPNESS_MAP_SIZE, + ADD_OR_SIZE(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE, sharpnessMapSize, sizeof(sharpnessMapSize)/sizeof(int32_t)); static const int32_t maxSharpnessMapValue = 1000; - ADD_OR_SIZE(ANDROID_STATS_MAX_SHARPNESS_MAP_VALUE, + ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE, &maxSharpnessMapValue, 1); // android.control @@ -571,7 +578,7 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, availableSceneModes, sizeof(availableSceneModes)); static const uint8_t availableEffects[] = { - ANDROID_CONTROL_EFFECT_OFF + ANDROID_CONTROL_EFFECT_MODE_OFF }; ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_EFFECTS, availableEffects, sizeof(availableEffects)); @@ -586,11 +593,11 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, static const camera_metadata_rational exposureCompensationStep = { 1, 1 }; - ADD_OR_SIZE(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, + ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_STEP, &exposureCompensationStep, 1); int32_t exposureCompensationRange[] = {-3, 3}; - ADD_OR_SIZE(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, + ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_RANGE, exposureCompensationRange, sizeof(exposureCompensationRange)/sizeof(int32_t)); @@ -602,19 +609,19 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, sizeof(availableTargetFpsRanges)/sizeof(int32_t)); static const uint8_t availableAntibandingModes[] = { - ANDROID_CONTROL_AE_ANTIBANDING_OFF, - ANDROID_CONTROL_AE_ANTIBANDING_AUTO + ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF, + ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO }; ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, availableAntibandingModes, sizeof(availableAntibandingModes)); static const uint8_t availableAwbModes[] = { - ANDROID_CONTROL_AWB_OFF, - ANDROID_CONTROL_AWB_AUTO, - ANDROID_CONTROL_AWB_INCANDESCENT, - ANDROID_CONTROL_AWB_FLUORESCENT, - ANDROID_CONTROL_AWB_DAYLIGHT, - ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT + ANDROID_CONTROL_AWB_MODE_OFF, + ANDROID_CONTROL_AWB_MODE_AUTO, + ANDROID_CONTROL_AWB_MODE_INCANDESCENT, + ANDROID_CONTROL_AWB_MODE_FLUORESCENT, + ANDROID_CONTROL_AWB_MODE_DAYLIGHT, + ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT }; ADD_OR_SIZE(ANDROID_CONTROL_AWB_AVAILABLE_MODES, availableAwbModes, sizeof(availableAwbModes)); @@ -623,8 +630,8 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info, m_curCameraInfo->availableAfModes, m_curCameraInfo->numAvailableAfModes); static const uint8_t availableVstabModes[] = { - ANDROID_CONTROL_VIDEO_STABILIZATION_OFF, - ANDROID_CONTROL_VIDEO_STABILIZATION_ON + ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF, + ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON }; ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, availableVstabModes, sizeof(availableVstabModes)); @@ -681,7 +688,7 @@ status_t ExynosCamera2::constructDefaultRequest( /** android.request */ - static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_NONE; + static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_NONE; ADD_OR_SIZE(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1); static const int32_t id = 0; @@ -707,7 +714,7 @@ status_t ExynosCamera2::constructDefaultRequest( ADD_OR_SIZE(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1); static const uint8_t opticalStabilizationMode = - ANDROID_LENS_OPTICAL_STABILIZATION_OFF; + ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; ADD_OR_SIZE(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &opticalStabilizationMode, 1); @@ -721,7 +728,7 @@ status_t ExynosCamera2::constructDefaultRequest( /** android.flash */ - static const uint8_t flashMode = ANDROID_FLASH_OFF; + static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF; ADD_OR_SIZE(ANDROID_FLASH_MODE, &flashMode, 1); static const uint8_t flashPower = 10; @@ -739,89 +746,53 @@ status_t ExynosCamera2::constructDefaultRequest( uint8_t colorMode = 0; uint8_t tonemapMode = 0; uint8_t edgeMode = 0; - uint8_t vstabMode = 0; + uint8_t vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; switch (request_template) { - case CAMERA2_TEMPLATE_PREVIEW: - hotPixelMode = ANDROID_PROCESSING_FAST; - demosaicMode = ANDROID_PROCESSING_FAST; - noiseMode = ANDROID_PROCESSING_FAST; - shadingMode = ANDROID_PROCESSING_FAST; - geometricMode = ANDROID_PROCESSING_FAST; - colorMode = ANDROID_PROCESSING_FAST; - tonemapMode = ANDROID_PROCESSING_FAST; - edgeMode = ANDROID_PROCESSING_FAST; - vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_OFF; - break; - case CAMERA2_TEMPLATE_STILL_CAPTURE: - hotPixelMode = ANDROID_PROCESSING_HIGH_QUALITY; - demosaicMode = ANDROID_PROCESSING_HIGH_QUALITY; - noiseMode = ANDROID_PROCESSING_HIGH_QUALITY; - shadingMode = ANDROID_PROCESSING_HIGH_QUALITY; - geometricMode = ANDROID_PROCESSING_HIGH_QUALITY; - colorMode = ANDROID_PROCESSING_HIGH_QUALITY; - tonemapMode = ANDROID_PROCESSING_HIGH_QUALITY; - edgeMode = ANDROID_PROCESSING_HIGH_QUALITY; - vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_OFF; - break; - case CAMERA2_TEMPLATE_VIDEO_RECORD: - hotPixelMode = ANDROID_PROCESSING_FAST; - demosaicMode = ANDROID_PROCESSING_FAST; - noiseMode = ANDROID_PROCESSING_FAST; - shadingMode = ANDROID_PROCESSING_FAST; - geometricMode = ANDROID_PROCESSING_FAST; - colorMode = ANDROID_PROCESSING_FAST; - tonemapMode = ANDROID_PROCESSING_FAST; - edgeMode = ANDROID_PROCESSING_FAST; - vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_ON; - break; case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT: - hotPixelMode = ANDROID_PROCESSING_HIGH_QUALITY; - demosaicMode = ANDROID_PROCESSING_HIGH_QUALITY; - noiseMode = ANDROID_PROCESSING_HIGH_QUALITY; - shadingMode = ANDROID_PROCESSING_HIGH_QUALITY; - geometricMode = ANDROID_PROCESSING_HIGH_QUALITY; - colorMode = ANDROID_PROCESSING_HIGH_QUALITY; - tonemapMode = ANDROID_PROCESSING_HIGH_QUALITY; - edgeMode = ANDROID_PROCESSING_HIGH_QUALITY; - vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_ON; - break; + vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON; + // fall-through + case CAMERA2_TEMPLATE_STILL_CAPTURE: + // fall-through case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG: - hotPixelMode = ANDROID_PROCESSING_HIGH_QUALITY; - demosaicMode = ANDROID_PROCESSING_HIGH_QUALITY; - noiseMode = ANDROID_PROCESSING_HIGH_QUALITY; - shadingMode = ANDROID_PROCESSING_HIGH_QUALITY; - geometricMode = ANDROID_PROCESSING_HIGH_QUALITY; - colorMode = ANDROID_PROCESSING_HIGH_QUALITY; - tonemapMode = ANDROID_PROCESSING_HIGH_QUALITY; - edgeMode = ANDROID_PROCESSING_HIGH_QUALITY; - vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_OFF; + hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY; + demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY; + noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY; + shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY; + geometricMode = ANDROID_GEOMETRIC_MODE_HIGH_QUALITY; + colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY; + tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY; + edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY; break; + case CAMERA2_TEMPLATE_VIDEO_RECORD: + vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON; + // fall-through + case CAMERA2_TEMPLATE_PREVIEW: + // fall-through default: - hotPixelMode = ANDROID_PROCESSING_FAST; - demosaicMode = ANDROID_PROCESSING_FAST; - noiseMode = ANDROID_PROCESSING_FAST; - shadingMode = ANDROID_PROCESSING_FAST; - geometricMode = ANDROID_PROCESSING_FAST; - colorMode = ANDROID_PROCESSING_FAST; - tonemapMode = ANDROID_PROCESSING_FAST; - edgeMode = ANDROID_PROCESSING_FAST; - vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_OFF; + hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST; + demosaicMode = ANDROID_DEMOSAIC_MODE_FAST; + noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST; + shadingMode = ANDROID_SHADING_MODE_FAST; + geometricMode = ANDROID_GEOMETRIC_MODE_FAST; + colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST; + tonemapMode = ANDROID_TONEMAP_MODE_FAST; + edgeMode = ANDROID_EDGE_MODE_FAST; break; } ADD_OR_SIZE(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1); ADD_OR_SIZE(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1); - ADD_OR_SIZE(ANDROID_NOISE_MODE, &noiseMode, 1); + ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1); ADD_OR_SIZE(ANDROID_SHADING_MODE, &shadingMode, 1); ADD_OR_SIZE(ANDROID_GEOMETRIC_MODE, &geometricMode, 1); - ADD_OR_SIZE(ANDROID_COLOR_MODE, &colorMode, 1); + ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1); ADD_OR_SIZE(ANDROID_TONEMAP_MODE, &tonemapMode, 1); ADD_OR_SIZE(ANDROID_EDGE_MODE, &edgeMode, 1); ADD_OR_SIZE(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1); /** android.noise */ static const uint8_t noiseStrength = 5; - ADD_OR_SIZE(ANDROID_NOISE_STRENGTH, &noiseStrength, 1); + ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_STRENGTH, &noiseStrength, 1); /** android.color */ static const float colorTransform[9] = { @@ -829,7 +800,7 @@ status_t ExynosCamera2::constructDefaultRequest( 0.f, 1.f, 0.f, 0.f, 0.f, 1.f }; - ADD_OR_SIZE(ANDROID_COLOR_TRANSFORM, colorTransform, 9); + ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9); /** android.tonemap */ static const float tonemapCurve[4] = { @@ -878,14 +849,14 @@ status_t ExynosCamera2::constructDefaultRequest( /** android.stats */ - static const uint8_t faceDetectMode = ANDROID_STATS_FACE_DETECTION_FULL; - ADD_OR_SIZE(ANDROID_STATS_FACE_DETECT_MODE, &faceDetectMode, 1); + static const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_FULL; + ADD_OR_SIZE(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1); - static const uint8_t histogramMode = ANDROID_STATS_OFF; - ADD_OR_SIZE(ANDROID_STATS_HISTOGRAM_MODE, &histogramMode, 1); + static const uint8_t histogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF; + ADD_OR_SIZE(ANDROID_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1); - static const uint8_t sharpnessMapMode = ANDROID_STATS_OFF; - ADD_OR_SIZE(ANDROID_STATS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1); + static const uint8_t sharpnessMapMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF; + ADD_OR_SIZE(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1); /** android.control */ @@ -893,36 +864,36 @@ status_t ExynosCamera2::constructDefaultRequest( uint8_t controlIntent = 0; switch (request_template) { case CAMERA2_TEMPLATE_PREVIEW: - controlIntent = ANDROID_CONTROL_INTENT_PREVIEW; + controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; break; case CAMERA2_TEMPLATE_STILL_CAPTURE: - controlIntent = ANDROID_CONTROL_INTENT_STILL_CAPTURE; + controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; break; case CAMERA2_TEMPLATE_VIDEO_RECORD: - controlIntent = ANDROID_CONTROL_INTENT_VIDEO_RECORD; + controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; break; case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT: - controlIntent = ANDROID_CONTROL_INTENT_VIDEO_SNAPSHOT; + controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; break; case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG: - controlIntent = ANDROID_CONTROL_INTENT_ZERO_SHUTTER_LAG; + controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG; break; default: - controlIntent = ANDROID_CONTROL_INTENT_CUSTOM; + controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM; break; } ADD_OR_SIZE(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1); - static const uint8_t controlMode = ANDROID_CONTROL_AUTO; + static const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO; ADD_OR_SIZE(ANDROID_CONTROL_MODE, &controlMode, 1); - static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_OFF; + static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF; ADD_OR_SIZE(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1); static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED; ADD_OR_SIZE(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1); - static const uint8_t aeMode = ANDROID_CONTROL_AE_ON; + static const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON; ADD_OR_SIZE(ANDROID_CONTROL_AE_MODE, &aeMode, 1); int32_t controlRegions[5] = { @@ -931,7 +902,7 @@ status_t ExynosCamera2::constructDefaultRequest( ADD_OR_SIZE(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5); static const int32_t aeExpCompensation = 0; - ADD_OR_SIZE(ANDROID_CONTROL_AE_EXP_COMPENSATION, &aeExpCompensation, 1); + ADD_OR_SIZE(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExpCompensation, 1); static const int32_t aeTargetFpsRange[2] = { 15, 30 @@ -939,11 +910,11 @@ status_t ExynosCamera2::constructDefaultRequest( ADD_OR_SIZE(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2); static const uint8_t aeAntibandingMode = - ANDROID_CONTROL_AE_ANTIBANDING_AUTO; + ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO; ADD_OR_SIZE(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1); static const uint8_t awbMode = - ANDROID_CONTROL_AWB_AUTO; + ANDROID_CONTROL_AWB_MODE_AUTO; ADD_OR_SIZE(ANDROID_CONTROL_AWB_MODE, &awbMode, 1); ADD_OR_SIZE(ANDROID_CONTROL_AWB_REGIONS, controlRegions, 5); @@ -951,22 +922,22 @@ status_t ExynosCamera2::constructDefaultRequest( uint8_t afMode = 0; switch (request_template) { case CAMERA2_TEMPLATE_PREVIEW: - afMode = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE; + afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; break; case CAMERA2_TEMPLATE_STILL_CAPTURE: - afMode = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE; + afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; break; case CAMERA2_TEMPLATE_VIDEO_RECORD: - afMode = ANDROID_CONTROL_AF_CONTINUOUS_VIDEO; + afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; break; case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT: - afMode = ANDROID_CONTROL_AF_CONTINUOUS_VIDEO; + afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; break; case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG: - afMode = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE; + afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; break; default: - afMode = ANDROID_CONTROL_AF_AUTO; + afMode = ANDROID_CONTROL_AF_MODE_AUTO; break; } ADD_OR_SIZE(ANDROID_CONTROL_AF_MODE, &afMode, 1); diff --git a/libcamera2/ExynosCameraHWInterface2.cpp b/libcamera2/ExynosCameraHWInterface2.cpp index ea90d05..714edb7 100644 --- a/libcamera2/ExynosCameraHWInterface2.cpp +++ b/libcamera2/ExynosCameraHWInterface2.cpp @@ -309,6 +309,7 @@ RequestManager::~RequestManager() void RequestManager::ResetEntry() { Mutex::Autolock lock(m_requestMutex); + Mutex::Autolock lock2(m_numOfEntriesLock); for (int i=0 ; i<NUM_MAX_REQUEST_MGR_ENTRY; i++) { memset(&(entries[i]), 0x00, sizeof(request_manager_entry_t)); entries[i].internal_shot.shot.ctl.request.frameCount = -1; @@ -321,6 +322,7 @@ void RequestManager::ResetEntry() int RequestManager::GetNumEntries() { + Mutex::Autolock lock(m_numOfEntriesLock); return m_numOfEntries; } @@ -332,6 +334,7 @@ void RequestManager::SetDefaultParameters(int cropX) bool RequestManager::IsRequestQueueFull() { Mutex::Autolock lock(m_requestMutex); + Mutex::Autolock lock2(m_numOfEntriesLock); if (m_numOfEntries>=NUM_MAX_REQUEST_MGR_ENTRY) return true; else @@ -343,6 +346,7 @@ void RequestManager::RegisterRequest(camera_metadata_t * new_request, int * afMo ALOGV("DEBUG(%s):", __FUNCTION__); Mutex::Autolock lock(m_requestMutex); + Mutex::Autolock lock2(m_numOfEntriesLock); request_manager_entry * newEntry = NULL; int newInsertionIndex = GetNextIndex(m_entryInsertionIndex); @@ -386,6 +390,7 @@ void RequestManager::DeregisterRequest(camera_metadata_t ** deregistered_request request_manager_entry * currentEntry; Mutex::Autolock lock(m_requestMutex); + Mutex::Autolock lock2(m_numOfEntriesLock); frame_index = GetCompletedIndex(); currentEntry = &(entries[frame_index]); @@ -454,6 +459,7 @@ int RequestManager::MarkProcessingRequest(ExynosBuffer* buf) static int count = 0; Mutex::Autolock lock(m_requestMutex); + Mutex::Autolock lock2(m_numOfEntriesLock); if (m_numOfEntries == 0) { CAM_LOGD("DEBUG(%s): Request Manager Empty ", __FUNCTION__); return -1; @@ -899,6 +905,7 @@ void RequestManager::Dump(void) { int i = 0; request_manager_entry * currentEntry; + Mutex::Autolock lock(m_numOfEntriesLock); ALOGD("## Dump totalentry(%d), insert(%d), processing(%d), frame(%d)", m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex); @@ -949,6 +956,7 @@ ExynosCameraHWInterface2::ExynosCameraHWInterface2(int cameraId, camera2_device_ m_IsAfModeUpdateRequired(false), m_IsAfTriggerRequired(false), m_IsAfLockRequired(false), + m_serviceAfState(ANDROID_CONTROL_AF_STATE_INACTIVE), m_sccLocalBufferValid(false), m_wideAspect(false), m_scpOutputSignalCnt(0), @@ -1026,11 +1034,13 @@ ExynosCameraHWInterface2::ExynosCameraHWInterface2(int cameraId, camera2_device_ if (m_exynosPictureCSC == NULL) ALOGE("ERR(%s): csc_init() fail", __FUNCTION__); csc_set_hw_property(m_exynosPictureCSC, CSC_HW_PROPERTY_FIXED_NODE, PICTURE_GSC_NODE_NUM); + csc_set_hw_property(m_exynosPictureCSC, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER); m_exynosVideoCSC = csc_init(cscMethod); if (m_exynosVideoCSC == NULL) ALOGE("ERR(%s): csc_init() fail", __FUNCTION__); csc_set_hw_property(m_exynosVideoCSC, CSC_HW_PROPERTY_FIXED_NODE, VIDEO_GSC_NODE_NUM); + csc_set_hw_property(m_exynosVideoCSC, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER); m_setExifFixedAttribute(); @@ -1275,10 +1285,19 @@ int ExynosCameraHWInterface2::InitializeISPChain() m_camera_info.sensor.memory = V4L2_MEMORY_DMABUF; for(i = 0; i < m_camera_info.sensor.buffers; i++){ + int res; initCameraMemory(&m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes); m_camera_info.sensor.buffer[i].size.extS[0] = m_camera_info.sensor.width*m_camera_info.sensor.height*2; m_camera_info.sensor.buffer[i].size.extS[1] = 8*1024; // HACK, driver use 8*1024, should be use predefined value - allocCameraMemory(m_ionCameraClient, &m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes, 1<<1); + res = allocCameraMemory(m_ionCameraClient, &m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes, 1<<1); + if (res) { + ALOGE("ERROR(%s): failed to allocateCameraMemory for sensor buffer %d", __FUNCTION__, i); + // Free allocated sensor buffers + for (int j = 0; j < i; j++) { + freeCameraMemory(&m_camera_info.sensor.buffer[j], m_camera_info.sensor.planes); + } + return false; + } } m_camera_info.isp.width = m_camera_info.sensor.width; @@ -1611,10 +1630,17 @@ int ExynosCameraHWInterface2::setFrameQueueDstOps(const camera2_frame_queue_dst_ int ExynosCameraHWInterface2::getInProgressCount() { - int inProgressCount = m_requestManager->GetNumEntries(); + int inProgressJpeg; + int inProgressCount; + + { + Mutex::Autolock lock(m_jpegEncoderLock); + inProgressJpeg = m_jpegEncodingCount; + inProgressCount = m_requestManager->GetNumEntries(); + } ALOGV("DEBUG(%s): # of dequeued req (%d) jpeg(%d) = (%d)", __FUNCTION__, - inProgressCount, m_jpegEncodingCount, (inProgressCount + m_jpegEncodingCount)); - return (inProgressCount + m_jpegEncodingCount); + inProgressCount, inProgressJpeg, (inProgressCount + inProgressJpeg)); + return (inProgressCount + inProgressJpeg); } int ExynosCameraHWInterface2::flushCapturesInProgress() @@ -1700,6 +1726,8 @@ int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, in *format_actual = HAL_PIXEL_FORMAT_EXYNOS_YV12; *usage = GRALLOC_USAGE_SW_WRITE_OFTEN; + if (m_wideAspect) + *usage |= GRALLOC_USAGE_PRIVATE_CHROMA; *max_buffers = 6; newParameters.width = width; @@ -1745,6 +1773,8 @@ int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, in *format_actual = HAL_PIXEL_FORMAT_YCbCr_420_SP; // NV12M *usage = GRALLOC_USAGE_SW_WRITE_OFTEN; + if (m_wideAspect) + *usage |= GRALLOC_USAGE_PRIVATE_CHROMA; *max_buffers = 6; subParameters->type = SUBSTREAM_TYPE_RECORD; @@ -1793,6 +1823,8 @@ int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, in *format_actual = HAL_PIXEL_FORMAT_YCbCr_422_I; // YUYV *usage = GRALLOC_USAGE_SW_WRITE_OFTEN; + if (m_wideAspect) + *usage |= GRALLOC_USAGE_PRIVATE_CHROMA; *max_buffers = 6; newParameters.width = width; @@ -1846,6 +1878,8 @@ int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, in *format_actual = HAL_PIXEL_FORMAT_YCbCr_422_I; // YUYV *usage = GRALLOC_USAGE_SW_WRITE_OFTEN; + if (m_wideAspect) + *usage |= GRALLOC_USAGE_PRIVATE_CHROMA; *max_buffers = 6; newParameters.width = width; @@ -1898,6 +1932,8 @@ int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, in *format_actual = HAL_PIXEL_FORMAT_BLOB; *usage = GRALLOC_USAGE_SW_WRITE_OFTEN; + if (m_wideAspect) + *usage |= GRALLOC_USAGE_PRIVATE_CHROMA; *max_buffers = 4; subParameters->type = SUBSTREAM_TYPE_JPEG; @@ -1934,6 +1970,8 @@ int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, in *format_actual = format; *usage = GRALLOC_USAGE_SW_WRITE_OFTEN; + if (m_wideAspect) + *usage |= GRALLOC_USAGE_PRIVATE_CHROMA; *max_buffers = 6; subParameters->type = SUBSTREAM_TYPE_PRVCB; @@ -4117,7 +4155,6 @@ void ExynosCameraHWInterface2::m_streamThreadFunc(SignalDrivenThread * self) } int ExynosCameraHWInterface2::m_jpegCreator(StreamThread *selfThread, ExynosBuffer *srcImageBuf, nsecs_t frameTimeStamp) { - Mutex::Autolock lock(m_jpegEncoderLock); stream_parameters_t *selfStreamParms = &(selfThread->m_parameters); substream_parameters_t *subParms = &m_subStreams[STREAM_ID_JPEG]; status_t res; @@ -4149,7 +4186,10 @@ int ExynosCameraHWInterface2::m_jpegCreator(StreamThread *selfThread, ExynosBuff return 1; } - m_jpegEncodingCount++; + { + Mutex::Autolock lock(m_jpegEncoderLock); + m_jpegEncodingCount++; + } m_getRatioSize(selfStreamParms->width, selfStreamParms->height, m_streamThreads[0]->m_parameters.width, m_streamThreads[0]->m_parameters.height, @@ -4313,7 +4353,10 @@ int ExynosCameraHWInterface2::m_jpegCreator(StreamThread *selfThread, ExynosBuff subParms->svcBufIndex, subParms->svcBufStatus[subParms->svcBufIndex]); } } - m_jpegEncodingCount--; + { + Mutex::Autolock lock(m_jpegEncoderLock); + m_jpegEncodingCount--; + } return 0; } @@ -6046,11 +6089,11 @@ int ExynosCameraHWInterface2::allocCameraMemory(ion_client ionClient, ExynosBuff break; } if (1 << i & cacheFlag) - flag = ION_FLAG_CACHED; + flag = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; else flag = 0; buf->fd.extFd[i] = ion_alloc(ionClient, \ - buf->size.extS[i], 0, ION_HEAP_EXYNOS_MASK, flag); + buf->size.extS[i], 0, ION_HEAP_SYSTEM_MASK, flag); if ((buf->fd.extFd[i] == -1) ||(buf->fd.extFd[i] == 0)) { ALOGE("[%s]ion_alloc(%d) failed\n", __FUNCTION__, buf->size.extS[i]); buf->fd.extFd[i] = -1; diff --git a/libcamera2/ExynosCameraHWInterface2.h b/libcamera2/ExynosCameraHWInterface2.h index 027322f..b54d77a 100644 --- a/libcamera2/ExynosCameraHWInterface2.h +++ b/libcamera2/ExynosCameraHWInterface2.h @@ -315,6 +315,7 @@ private: MetadataConverter *m_metadataConverter; SignalDrivenThread *m_mainThread; + Mutex m_numOfEntriesLock; int m_numOfEntries; int m_entryInsertionIndex; int m_entryProcessingIndex; diff --git a/libcamera2/MetadataConverter.cpp b/libcamera2/MetadataConverter.cpp index d3dd2b3..386c62a 100644 --- a/libcamera2/MetadataConverter.cpp +++ b/libcamera2/MetadataConverter.cpp @@ -172,9 +172,9 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c case ANDROID_SCALER_CROP_REGION: - if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 3)) + if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 4)) break; - for (i=0 ; i<curr_entry.count ; i++) + for (i=0 ; i<3; i++) dst->ctl.scaler.cropRegion[i] = ALIGN(curr_entry.data.i32[i], 2); break; @@ -230,7 +230,7 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c - case ANDROID_STATS_FACE_DETECT_MODE: + case ANDROID_STATISTICS_FACE_DETECT_MODE: if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1)) break; dst->ctl.stats.faceDetectMode = (enum facedetect_mode)(curr_entry.data.u8[0] + 1); @@ -271,7 +271,7 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c dst_ext->ae_lock = (enum ae_lockmode)(curr_entry.data.u8[0]); break; - case ANDROID_CONTROL_AE_EXP_COMPENSATION: + case ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION: if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 1)) break; dst->ctl.aa.aeExpCompensation = curr_entry.data.i32[0] + 5; @@ -570,17 +570,17 @@ status_t MetadataConverter::ToDynamicMetadata(struct camera2_shot_ext * metadata return NO_MEMORY; intData = metadata->ctl.aa.aeExpCompensation - 5; - if (0 != add_camera_metadata_entry(dst, ANDROID_CONTROL_AE_EXP_COMPENSATION, + if (0 != add_camera_metadata_entry(dst, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &intData, 1)) return NO_MEMORY; byteData = metadata->dm.stats.faceDetectMode - 1; - if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_DETECT_MODE, + if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_DETECT_MODE, &byteData, 1)) return NO_MEMORY; int maxFacecount = CAMERA2_MAX_FACES; - if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_MAX_FACE_COUNT, + if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFacecount, 1)) return NO_MEMORY; @@ -601,19 +601,19 @@ status_t MetadataConverter::ToDynamicMetadata(struct camera2_shot_ext * metadata } if (tempFaceCount > 0) { - if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_RECTANGLES, + if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_RECTANGLES, &metaFaceRectangles, 4 * tempFaceCount)) return NO_MEMORY; - if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_LANDMARKS, + if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_LANDMARKS, &mataFaceLandmarks, 6 * tempFaceCount)) return NO_MEMORY; - if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_IDS, + if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_IDS, &mataFaceIds, tempFaceCount)) return NO_MEMORY; - if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_SCORES, + if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_SCORES, &metaFaceScores, tempFaceCount)) return NO_MEMORY; } @@ -621,9 +621,15 @@ status_t MetadataConverter::ToDynamicMetadata(struct camera2_shot_ext * metadata &metadata->dm.aa.isoValue, 1)) return NO_MEMORY; - + // Need a four-entry crop region + uint32_t cropRegion[4] = { + metadata->ctl.scaler.cropRegion[0], + metadata->ctl.scaler.cropRegion[1], + metadata->ctl.scaler.cropRegion[2], + 0 + }; if (0 != add_camera_metadata_entry(dst, ANDROID_SCALER_CROP_REGION, - &metadata->ctl.scaler.cropRegion, 3)) + cropRegion, 4)) return NO_MEMORY; byteData = metadata->dm.aa.aeState - 1; diff --git a/libcsc/Android.mk b/libcsc/Android.mk index 8074695..bbf0ece 100644 --- a/libcsc/Android.mk +++ b/libcsc/Android.mk @@ -56,7 +56,7 @@ LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../include -LOCAL_CFLAGS += -DENABLE_GSCALER +LOCAL_CFLAGS += -DENABLE_GSCALER -DENABLE_G2D LOCAL_SHARED_LIBRARIES += libexynosgscaler LOCAL_CFLAGS += -DUSE_ION diff --git a/libcsc/csc.c b/libcsc/csc.c index 4f2aac6..0831f61 100644 --- a/libcsc/csc.c +++ b/libcsc/csc.c @@ -53,6 +53,19 @@ #include "exynos_gscaler.h" #endif +#ifdef ENABLE_G2D +#include <fcntl.h> +#include <sys/ioctl.h> +#include "fimg2d.h" + +typedef struct +{ + struct fimg2d_image src; + struct fimg2d_image dst; + int fd; +} g2d_data; +#endif + #define GSCALER_IMG_ALIGN 16 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) @@ -64,11 +77,6 @@ typedef enum _CSC_PLANE { CSC_V_PLANE = 2 } CSC_PLANE; -typedef enum _CSC_HW_TYPE { - CSC_HW_TYPE_FIMC = 0, - CSC_HW_TYPE_GSCALER -} CSC_HW_TYPE; - typedef struct _CSC_FORMAT { unsigned int width; unsigned int height; @@ -265,7 +273,7 @@ static CSC_ERRORCODE conv_sw( case HAL_PIXEL_FORMAT_YCbCr_420_SP: ret = conv_sw_src_yuv420sp(handle); break; - case HAL_PIXEL_FORMAT_ARGB888: + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: ret = conv_sw_src_argb888(handle); break; default: @@ -314,6 +322,29 @@ static CSC_ERRORCODE conv_hw( } break; #endif +#ifdef ENABLE_G2D + case CSC_HW_TYPE_G2D: + { + g2d_data *g2d = (g2d_data *)handle->csc_hw_handle; + struct fimg2d_blit blit; + int err; + + memset(&blit, 0, sizeof(blit)); + blit.op = BLIT_OP_SRC_COPY; + blit.param.g_alpha = 0xFF; + blit.src = &g2d->src; + blit.dst = &g2d->dst; + blit.sync = BLIT_SYNC; + + err = ioctl(g2d->fd, FIMG2D_BITBLT_BLIT, &blit); + if (err < 0) { + ALOGE("FIMG2D_BITBLT_BLIT ioctl failed: %s", strerror(errno)); + ret = CSC_Error; + } + + break; + } +#endif default: ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type); ret = CSC_ErrorNotImplemented; @@ -331,12 +362,6 @@ static CSC_ERRORCODE csc_init_hw( csc_handle = (CSC_HANDLE *)handle; if (csc_handle->csc_method == CSC_METHOD_HW) { -#ifdef ENABLE_FIMC - csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC; -#endif -#ifdef ENABLE_GSCALER - csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER; -#endif switch (csc_handle->csc_hw_type) { #ifdef ENABLE_FIMC case CSC_HW_TYPE_FIMC: @@ -353,9 +378,27 @@ static CSC_ERRORCODE csc_init_hw( ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__); break; #endif +#ifdef ENABLE_G2D + case CSC_HW_TYPE_G2D: + { + g2d_data *g2d = calloc(1, sizeof(g2d_data)); + if (!g2d) { + ALOGE("failed to allocate G2D data"); + break; + } + g2d->fd = open("/dev/fimg2d", O_RDWR); + if (g2d->fd < 0) { + ALOGE("failed to open G2D: %s", strerror(errno)); + free(g2d); + } else { + csc_handle->csc_hw_handle = g2d; + } + break; + } +#endif default: ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__); - csc_handle->csc_hw_handle == NULL; + csc_handle->csc_hw_handle = NULL; break; } } @@ -363,8 +406,7 @@ static CSC_ERRORCODE csc_init_hw( if (csc_handle->csc_method == CSC_METHOD_HW) { if (csc_handle->csc_hw_handle == NULL) { ALOGE("%s:: CSC_METHOD_HW can't open HW", __func__); - free(csc_handle); - csc_handle = NULL; + ret = CSC_Error; } } @@ -415,6 +457,42 @@ static CSC_ERRORCODE csc_set_format( 0); break; #endif +#ifdef ENABLE_G2D + case CSC_HW_TYPE_G2D: + { + g2d_data *g2d = (g2d_data *)csc_handle->csc_hw_handle; + + g2d->src.width = ALIGN(csc_handle->src_format.width, + GSCALER_IMG_ALIGN); + g2d->src.height = csc_handle->src_format.height; + g2d->src.stride = g2d->src.width * + hal_2_g2d_bpp(csc_handle->src_format.color_format) >> 3; + g2d->src.order = hal_2_g2d_pixel_order(csc_handle->src_format.color_format); + g2d->src.fmt = hal_2_g2d_color_format(csc_handle->src_format.color_format); + g2d->src.rect.x1 = csc_handle->src_format.crop_left; + g2d->src.rect.y1 = csc_handle->src_format.crop_top; + g2d->src.rect.x2 = csc_handle->src_format.crop_left + + csc_handle->src_format.crop_width; + g2d->src.rect.y2 = csc_handle->src_format.crop_top + + csc_handle->src_format.crop_height; + + g2d->dst.width = ALIGN(csc_handle->dst_format.width, + GSCALER_IMG_ALIGN); + g2d->dst.height = csc_handle->dst_format.height; + g2d->dst.stride = g2d->dst.width * + hal_2_g2d_bpp(csc_handle->dst_format.color_format) >> 3; + g2d->dst.order = hal_2_g2d_pixel_order(csc_handle->dst_format.color_format); + g2d->dst.fmt = hal_2_g2d_color_format(csc_handle->dst_format.color_format); + g2d->dst.rect.x1 = csc_handle->dst_format.crop_left; + g2d->dst.rect.y1 = csc_handle->dst_format.crop_top; + g2d->dst.rect.x2 = csc_handle->dst_format.crop_left + + csc_handle->dst_format.crop_width; + g2d->dst.rect.y2 = csc_handle->dst_format.crop_top + + csc_handle->dst_format.crop_height; + + break; + } +#endif default: ALOGE("%s:: unsupported csc_hw_type", __func__); break; @@ -444,6 +522,22 @@ static CSC_ERRORCODE csc_set_buffer( exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, -1); break; #endif +#ifdef ENABLE_G2D + case CSC_HW_TYPE_G2D: + { + g2d_data *g2d = (g2d_data *)csc_handle->csc_hw_handle; + + g2d->src.addr.type = ADDR_DMA_BUF; + g2d->src.addr.fd[0] = (int)csc_handle->src_buffer.planes[0]; + g2d->src.addr.fd[1] = (int)csc_handle->src_buffer.planes[1]; + + g2d->dst.addr.type = ADDR_DMA_BUF; + g2d->dst.addr.fd[0] = (int)csc_handle->dst_buffer.planes[0]; + g2d->dst.addr.fd[1] = (int)csc_handle->dst_buffer.planes[1]; + + break; + } +#endif default: ALOGE("%s:: unsupported csc_hw_type", __func__); break; @@ -476,7 +570,7 @@ CSC_ERRORCODE csc_deinit( CSC_HANDLE *csc_handle; csc_handle = (CSC_HANDLE *)handle; - if (csc_handle->csc_method == CSC_METHOD_HW) { + if (csc_handle->csc_hw_handle) { switch (csc_handle->csc_hw_type) { #ifdef ENABLE_FIMC case CSC_HW_TYPE_FIMC: @@ -488,6 +582,15 @@ CSC_ERRORCODE csc_deinit( exynos_gsc_destroy(csc_handle->csc_hw_handle); break; #endif +#ifdef ENABLE_G2D + case CSC_HW_TYPE_G2D: + { + g2d_data *g2d = (g2d_data *)csc_handle->csc_hw_handle; + close(g2d->fd); + free(g2d); + break; + } +#endif default: ALOGE("%s:: unsupported csc_hw_type", __func__); break; @@ -518,6 +621,22 @@ CSC_ERRORCODE csc_get_method( return ret; } +CSC_ERRORCODE csc_set_method( + void *handle, + CSC_METHOD method) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + csc_handle->csc_method = method; + + return ret; +} + CSC_ERRORCODE csc_set_hw_property( void *handle, CSC_HW_PROPERTY_TYPE property, @@ -530,6 +649,12 @@ CSC_ERRORCODE csc_set_hw_property( return CSC_ErrorNotInit; csc_handle = (CSC_HANDLE *)handle; + + if (csc_handle->csc_hw_handle) { + ALOGE("%s:: cannot set hw property after hw is already initialized", __func__); + return CSC_ErrorUnsupportFormat; + } + switch (property) { case CSC_HW_PROPERTY_FIXED_NODE: csc_handle->hw_property.fixed_node = value; @@ -537,6 +662,9 @@ CSC_ERRORCODE csc_set_hw_property( case CSC_HW_PROPERTY_MODE_DRM: csc_handle->hw_property.mode_drm = value; break; + case CSC_HW_PROPERTY_HW_TYPE: + csc_handle->csc_hw_type = value; + break; default: ALOGE("%s:: not supported hw property", __func__); ret = CSC_ErrorUnsupportFormat; @@ -711,11 +839,19 @@ CSC_ERRORCODE csc_convert( return CSC_ErrorNotInit; if ((csc_handle->csc_method == CSC_METHOD_HW) && - (csc_handle->csc_hw_handle == NULL)) - csc_init_hw(handle); + (csc_handle->csc_hw_handle == NULL)) { + ret = csc_init_hw(handle); + if (ret != CSC_ErrorNone) + return ret; + } + + ret = csc_set_format(csc_handle); + if (ret != CSC_ErrorNone) + return ret; - csc_set_format(csc_handle); - csc_set_buffer(csc_handle); + ret = csc_set_buffer(csc_handle); + if (ret != CSC_ErrorNone) + return ret; if (csc_handle->csc_method == CSC_METHOD_HW) ret = conv_hw(csc_handle); diff --git a/libcsc/csc.h b/libcsc/csc.h index 5fc50a2..9372610 100644 --- a/libcsc/csc.h +++ b/libcsc/csc.h @@ -53,8 +53,16 @@ typedef enum _CSC_METHOD { typedef enum _CSC_HW_PROPERTY_TYPE { CSC_HW_PROPERTY_FIXED_NODE = 0, CSC_HW_PROPERTY_MODE_DRM, + CSC_HW_PROPERTY_HW_TYPE, } CSC_HW_PROPERTY_TYPE; +typedef enum _CSC_HW_TYPE { + CSC_HW_TYPE_NONE = 0, + CSC_HW_TYPE_FIMC, + CSC_HW_TYPE_GSCALER, + CSC_HW_TYPE_G2D, +} CSC_HW_TYPE; + /* * change hal pixel format to omx pixel format * @@ -80,6 +88,40 @@ unsigned int omx_2_hal_pixel_format( unsigned int omx_format); /* + * change hal pixel format to g2d color format + * + * @param hal_format + * hal pixel format[in] + * + * @return + * g2d color format + */ +unsigned int hal_2_g2d_color_format(unsigned int hal_format); + +/* + * change hal pixel format to g2d pixel order + * + * @param hal_format + * hal pixel format[in] + * + * @return + * g2d pixel order + */ +unsigned int hal_2_g2d_pixel_order(unsigned int hal_format); + +/* + * change hal pixel format to g2d "bpp" (actual bpp for RGB formats, 8 bpp for + * YUV formats) + * + * @param hal_format + * hal pixel format[in] + * + * @return + * g2d bpp + */ +size_t hal_2_g2d_bpp(unsigned int hal_format); + +/* * Init CSC handle * * @return @@ -117,6 +159,22 @@ CSC_ERRORCODE csc_get_method( CSC_METHOD *method); /* + * set color space converter method + * + * @param handle + * CSC handle[in] + * + * @param method + * CSC method[in] + * + * @return + * error code + */ +CSC_ERRORCODE csc_set_method( + void *handle, + CSC_METHOD method); + +/* * Set hw property * * @param handle diff --git a/libcsc/csc_helper.c b/libcsc/csc_helper.c index 9f13d62..eb853f3 100644 --- a/libcsc/csc_helper.c +++ b/libcsc/csc_helper.c @@ -24,6 +24,7 @@ #include "csc.h" #include "exynos_format.h" +#include "fimg2d.h" OMX_COLOR_FORMATTYPE hal_2_omx_pixel_format( unsigned int hal_format) @@ -45,7 +46,8 @@ OMX_COLOR_FORMATTYPE hal_2_omx_pixel_format( case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: omx_format = OMX_SEC_COLOR_FormatNV12Tiled; break; - case HAL_PIXEL_FORMAT_ARGB888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: omx_format = OMX_COLOR_Format32bitARGB8888; break; default: @@ -76,7 +78,7 @@ unsigned int omx_2_hal_pixel_format( hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; break; case OMX_COLOR_Format32bitARGB8888: - hal_format = HAL_PIXEL_FORMAT_ARGB888; + hal_format = HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888; break; default: hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; @@ -84,3 +86,89 @@ unsigned int omx_2_hal_pixel_format( } return hal_format; } + +unsigned int hal_2_g2d_color_format(unsigned int hal_format) +{ + switch (hal_format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: + return CF_ARGB_8888; + + case HAL_PIXEL_FORMAT_RGBX_8888: + return CF_XRGB_8888; + + case HAL_PIXEL_FORMAT_RGB_888: + return CF_RGB_888; + + case HAL_PIXEL_FORMAT_RGB_565: + return CF_RGB_565; + + case HAL_PIXEL_FORMAT_RGBA_5551: + return CF_ARGB_1555; + + case HAL_PIXEL_FORMAT_RGBA_4444: + return CF_ARGB_4444; + + case HAL_PIXEL_FORMAT_YCbCr_422_I: + return CF_YCBCR_422; + + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + return CF_YCBCR_420; + + default: + return SRC_DST_FORMAT_END; + } +} + +unsigned int hal_2_g2d_pixel_order(unsigned int hal_format) +{ + switch (hal_format) { + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: + return AX_RGB; + + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + return RGB_AX; + + case HAL_PIXEL_FORMAT_YCbCr_422_I: + return P1_Y1CBY0CR; + + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + return P2_CRCB; + + default: + return ARGB_ORDER_END; + } +} + +size_t hal_2_g2d_bpp(unsigned int hal_format) +{ + switch (hal_format) { + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + return 32; + + case HAL_PIXEL_FORMAT_RGB_888: + return 24; + + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + return 16; + + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + return 8; + + default: + return 0; + } +} diff --git a/libexynosutils/exynos5_format_v4l2.c b/libexynosutils/exynos5_format_v4l2.c index 8b05717..824f133 100644 --- a/libexynosutils/exynos5_format_v4l2.c +++ b/libexynosutils/exynos5_format_v4l2.c @@ -52,6 +52,7 @@ int HAL_PIXEL_FORMAT_2_V4L2_PIX( switch (hal_pixel_format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: v4l2_pixel_format = V4L2_PIX_FMT_RGB32; break; @@ -281,6 +282,7 @@ unsigned int FRAME_SIZE( case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_BGRA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: frame_size = GET_32BPP_FRAME_SIZE(width, height); break; diff --git a/libhwc/Android.mk b/libhwc/Android.mk index 0463494..5ef9373 100644 --- a/libhwc/Android.mk +++ b/libhwc/Android.mk @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -ifneq ($(filter manta full_manta,$(TARGET_DEVICE)),) - LOCAL_PATH:= $(call my-dir) # HAL module implemenation, not prelinked and stored in # hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.product.board>.so @@ -31,8 +29,6 @@ LOCAL_C_INCLUDES := \ LOCAL_SRC_FILES := hwc.cpp -LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM) +LOCAL_MODULE := hwcomposer.exynos5 LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) - -endif diff --git a/libhwc/hwc.cpp b/libhwc/hwc.cpp index 1a3d4a5..f0050d0 100644 --- a/libhwc/hwc.cpp +++ b/libhwc/hwc.cpp @@ -199,6 +199,22 @@ inline int HEIGHT(const hwc_rect &rect) { return rect.bottom - rect.top; } template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; } template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; } +static int dup_or_warn(int fence) +{ + int dup_fd = dup(fence); + if (dup_fd < 0) + ALOGW("fence dup failed: %s", strerror(errno)); + return dup_fd; +} + +static int merge_or_warn(const char *name, int f1, int f2) +{ + int merge_fd = sync_merge(name, f1, f2); + if (merge_fd < 0) + ALOGW("fence merge failed: %s", strerror(errno)); + return merge_fd; +} + template<typename T> void align_crop_and_center(T &w, T &h, hwc_rect_t *crop, size_t alignment) { @@ -549,6 +565,10 @@ static void hdmi_show_layer(struct exynos5_hwc_composer_device_1_t *dev, static int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev) { + /* hdmi not supported */ + if (dev->hdmi_mixer0 < 0) + return 0; + if (dev->hdmi_enabled) return 0; @@ -750,10 +770,10 @@ err: bool exynos5_is_offscreen(hwc_layer_1_t &layer, struct exynos5_hwc_composer_device_1_t *pdev) { - return layer.sourceCrop.left > pdev->xres || - layer.sourceCrop.right < 0 || - layer.sourceCrop.top > pdev->yres || - layer.sourceCrop.bottom < 0; + return layer.displayFrame.left > pdev->xres || + layer.displayFrame.right < 0 || + layer.displayFrame.top > pdev->yres || + layer.displayFrame.bottom < 0; } size_t exynos5_visible_width(hwc_layer_1_t &layer, int format, @@ -1509,9 +1529,7 @@ static int exynos5_set_fimd(exynos5_hwc_composer_device_1_t *pdev, if (pdev->bufs.overlay_map[i] != -1) { hwc_layer_1_t &layer = contents->hwLayers[pdev->bufs.overlay_map[i]]; - int dup_fd = dup(fence); - if (dup_fd < 0) - ALOGW("release fence dup failed: %s", strerror(errno)); + int dup_fd = dup_or_warn(fence); if (pdev->bufs.gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) { int gsc_idx = pdev->bufs.gsc_map[i].idx; exynos5_gsc_data_t &gsc = pdev->gsc[gsc_idx]; @@ -1522,7 +1540,7 @@ static int exynos5_set_fimd(exynos5_hwc_composer_device_1_t *pdev, } } } - close(fence); + contents->retireFenceFd = fence; return err; } @@ -1578,6 +1596,14 @@ static int exynos5_set_hdmi(exynos5_hwc_composer_device_1_t *pdev, gsc.dst_buf_fence[gsc.current_buf] = releaseFenceFd; gsc.current_buf = (gsc.current_buf + 1) % NUM_GSC_DST_BUFS; + if (contents->retireFenceFd < 0) + contents->retireFenceFd = dup_or_warn(releaseFenceFd); + else { + int merged = merge_or_warn("hdmi", + contents->retireFenceFd, layer.releaseFenceFd); + close(contents->retireFenceFd); + contents->retireFenceFd = merged; + } } if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) { @@ -1589,6 +1615,15 @@ static int exynos5_set_hdmi(exynos5_hwc_composer_device_1_t *pdev, hdmi_show_layer(pdev, pdev->hdmi_layers[1]); hdmi_output(pdev, pdev->hdmi_layers[1], layer, h, layer.acquireFenceFd, &layer.releaseFenceFd); + + if (contents->retireFenceFd < 0) + contents->retireFenceFd = dup_or_warn(layer.releaseFenceFd); + else { + int merged = merge_or_warn("hdmi", + contents->retireFenceFd, layer.releaseFenceFd); + close(contents->retireFenceFd); + contents->retireFenceFd = merged; + } } else { hdmi_hide_layer(pdev, pdev->hdmi_layers[1]); } @@ -1980,6 +2015,52 @@ static int exynos5_getDisplayAttributes(struct hwc_composer_device_1 *dev, static int exynos5_close(hw_device_t* device); +static void get_screen_res(const char *fbname, int32_t *xres, int32_t *yres, + int32_t *refresh) +{ + char *path; + int fd; + char buf[128]; + int ret; + unsigned int _x, _y, _r; + + asprintf(&path, "/sys/class/graphics/%s/modes", fbname); + if (!path) + goto err_asprintf; + fd = open(path, O_RDONLY); + if (fd < 0) + goto err_open; + ret = read(fd, buf, sizeof(buf)); + if (ret <= 0) + goto err_read; + buf[sizeof(buf)-1] = '\0'; + + ret = sscanf(buf, "U:%ux%up-%u", &_x, &_y, &_r); + if (ret != 3) + goto err_sscanf; + + ALOGI("Using %ux%u %uHz resolution for '%s' from modes list\n", + _x, _y, _r, fbname); + + *xres = (int32_t)_x; + *yres = (int32_t)_y; + *refresh = (int32_t)_r; + + close(fd); + free(path); + return; + +err_sscanf: +err_read: + close(fd); +err_open: + free(path); +err_asprintf: + *xres = 2560; + *yres = 1600; + *refresh = 60; +} + static int exynos5_open(const struct hw_module_t *module, const char *name, struct hw_device_t **device) { @@ -2023,22 +2104,14 @@ static int exynos5_open(const struct hw_module_t *module, const char *name, goto err_ioctl; } - refreshRate = 1000000000000LLU / - ( - uint64_t( info.upper_margin + info.lower_margin + info.yres ) - * ( info.left_margin + info.right_margin + info.xres ) - * info.pixclock - ); - + get_screen_res("fb0", &dev->xres, &dev->yres, &refreshRate); if (refreshRate == 0) { ALOGW("invalid refresh rate, assuming 60 Hz"); refreshRate = 60; } - dev->xres = 2560; - dev->yres = 1600; - dev->xdpi = 1000 * (info.xres * 25.4f) / info.width; - dev->ydpi = 1000 * (info.yres * 25.4f) / info.height; + dev->xdpi = 1000 * (dev->xres * 25.4f) / info.width; + dev->ydpi = 1000 * (dev->yres * 25.4f) / info.height; dev->vsync_period = 1000000000 / refreshRate; ALOGV("using\n" @@ -2055,11 +2128,8 @@ static int exynos5_open(const struct hw_module_t *module, const char *name, dev->gsc[i].dst_buf_fence[j] = -1; dev->hdmi_mixer0 = open("/dev/v4l-subdev7", O_RDWR); - if (dev->hdmi_mixer0 < 0) { + if (dev->hdmi_mixer0 < 0) ALOGE("failed to open hdmi mixer0 subdev"); - ret = dev->hdmi_mixer0; - goto err_ioctl; - } dev->hdmi_layers[0].id = 0; dev->hdmi_layers[0].fd = open("/dev/video16", O_RDWR); @@ -2129,7 +2199,8 @@ static int exynos5_open(const struct hw_module_t *module, const char *name, err_vsync: close(dev->vsync_fd); err_mixer0: - close(dev->hdmi_mixer0); + if (dev->hdmi_mixer0 >= 0) + close(dev->hdmi_mixer0); err_hdmi1: close(dev->hdmi_layers[0].fd); err_hdmi0: @@ -2153,7 +2224,8 @@ static int exynos5_close(hw_device_t *device) exynos5_cleanup_gsc_m2m(dev, i); gralloc_close(dev->alloc_device); close(dev->vsync_fd); - close(dev->hdmi_mixer0); + if (dev->hdmi_mixer0 >= 0) + close(dev->hdmi_mixer0); close(dev->hdmi_layers[0].fd); close(dev->hdmi_layers[1].fd); close(dev->fd); diff --git a/libkeymaster/Android.mk b/libkeymaster/Android.mk index 975af6a..fa1950e 100644 --- a/libkeymaster/Android.mk +++ b/libkeymaster/Android.mk @@ -23,12 +23,11 @@ LOCAL_MODULE := keystore.exynos5 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/hw LOCAL_SRC_FILES := keymaster_mobicore.cpp tlcTeeKeymaster_if.c LOCAL_C_INCLUDES := \ - system/security/keystore \ external/openssl/include \ $(MOBICORE_PATH)/daemon/ClientLib/public \ $(MOBICORE_PATH)/common/MobiCore/inc/ LOCAL_C_FLAGS = -fvisibility=hidden -Wall -Werror -LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_client libMcClient +LOCAL_SHARED_LIBRARIES := libcrypto liblog libMcClient LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := SHARED_LIBRARIES diff --git a/libkeymaster/keymaster_mobicore.cpp b/libkeymaster/keymaster_mobicore.cpp index b0a4e8d..f2d5d55 100644 --- a/libkeymaster/keymaster_mobicore.cpp +++ b/libkeymaster/keymaster_mobicore.cpp @@ -19,8 +19,6 @@ #include <string.h> #include <stdint.h> -#include <keystore.h> - #include <hardware/hardware.h> #include <hardware/keymaster.h> @@ -362,8 +360,12 @@ static int exynos_km_sign_data(const keymaster_device_t* dev, *signedDataLength = RSA_KEY_MAX_SIZE; - ret = TEE_RSASign(keyBlob, keyBlobLength, data, dataLength, signedDataPtr.get(), + /* binder gives us read-only mappings we can't use with mobicore */ + void *tmpData = malloc(dataLength); + memcpy(tmpData, data, dataLength); + ret = TEE_RSASign(keyBlob, keyBlobLength, (const uint8_t *)tmpData, dataLength, signedDataPtr.get(), signedDataLength, TEE_RSA_NODIGEST_NOPADDING); + free(tmpData); if (ret != TEE_ERR_NONE) { ALOGE("TEE_RSASign() is failed: %d", ret); return -1; @@ -399,8 +401,14 @@ static int exynos_km_verify_data(const keymaster_device_t* dev, return -1; } - ret = TEE_RSAVerify(keyBlob, keyBlobLength, signedData, signedDataLength, signature, + void *tmpSignedData = malloc(signedDataLength); + memcpy(tmpSignedData, signedData, signedDataLength); + void *tmpSig = malloc(signatureLength); + memcpy(tmpSig, signature, signatureLength); + ret = TEE_RSAVerify(keyBlob, keyBlobLength, (const uint8_t*)tmpSignedData, signedDataLength, (const uint8_t *)tmpSig, signatureLength, TEE_RSA_NODIGEST_NOPADDING, &result); + free(tmpSignedData); + free(tmpSig); if (ret != TEE_ERR_NONE) { ALOGE("TEE_RSAVerify() is failed: %d", ret); return -1; @@ -432,7 +440,7 @@ static int exynos_km_open(const hw_module_t* module, const char* name, dev->common.module = (struct hw_module_t*) module; dev->common.close = exynos_km_close; - dev->flags = KEYMASTER_SOFTWARE_ONLY; + dev->flags = 0; dev->generate_keypair = exynos_km_generate_keypair; dev->import_keypair = exynos_km_import_keypair; diff --git a/libstagefrighthw/Android.mk b/libstagefrighthw/Android.mk index a8af63c..91e3fb1 100644 --- a/libstagefrighthw/Android.mk +++ b/libstagefrighthw/Android.mk @@ -29,6 +29,7 @@ LOCAL_SHARED_LIBRARIES := \ libbinder \ libutils \ libcutils \ + liblog \ libui \ libdl \ libstagefright_foundation diff --git a/original-kernel-headers/linux/fimg2d.h b/original-kernel-headers/linux/fimg2d.h new file mode 100644 index 0000000..ceda93c --- /dev/null +++ b/original-kernel-headers/linux/fimg2d.h @@ -0,0 +1,465 @@ +/* linux/drivers/media/video/samsung/fimg2d4x/fimg2d.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Samsung Graphics 2D driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __FIMG2D_H +#define __FIMG2D_H __FILE__ + +#ifdef __KERNEL__ + +#include <linux/clk.h> +#include <linux/list.h> +#include <linux/device.h> +#include <linux/workqueue.h> +#include <linux/platform_device.h> +#include <linux/atomic.h> +#include <linux/dma-mapping.h> +#include <linux/dma-buf.h> + +#define FIMG2D_MINOR (240) +#define to_fimg2d_plat(d) (to_platform_device(d)->dev.platform_data) + +#ifdef CONFIG_VIDEO_FIMG2D_DEBUG +#define fimg2d_debug(fmt, arg...) printk(KERN_INFO "[%s] " fmt, __func__, ## arg) +#else +#define fimg2d_debug(fmt, arg...) do { } while (0) +#endif + +#endif /* __KERNEL__ */ + +#define FIMG2D_MAX_PLANES 2 + +/* ioctl commands */ +#define FIMG2D_IOCTL_MAGIC 'F' +#define FIMG2D_BITBLT_BLIT _IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit) +#define FIMG2D_BITBLT_SYNC _IOW(FIMG2D_IOCTL_MAGIC, 1, int) +#define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version) + +struct fimg2d_version { + unsigned int hw; + unsigned int sw; +}; + +/** + * @BLIT_SYNC: sync mode, to wait for blit done irq + * @BLIT_ASYNC: async mode, not to wait for blit done irq + * + */ +enum blit_sync { + BLIT_SYNC, + BLIT_ASYNC, +}; + +/** + * @ADDR_NONE: no image/solid color + * @ADDR_DMA_BUF: dma-buf fds + */ +enum addr_space { + ADDR_NONE = 0, + ADDR_DMA_BUF, +}; + +/** + * Pixel order complies with little-endian style + * + * DO NOT CHANGE THIS ORDER + */ +enum pixel_order { + AX_RGB = 0, + RGB_AX, + AX_BGR, + BGR_AX, + ARGB_ORDER_END, + + P1_CRY1CBY0, + P1_CBY1CRY0, + P1_Y1CRY0CB, + P1_Y1CBY0CR, + P1_ORDER_END, + + P2_CRCB, + P2_CBCR, + P2_ORDER_END, +}; + +/** + * DO NOT CHANGE THIS ORDER + */ +enum color_format { + CF_XRGB_8888 = 0, + CF_ARGB_8888, + CF_RGB_565, + CF_XRGB_1555, + CF_ARGB_1555, + CF_XRGB_4444, + CF_ARGB_4444, + CF_RGB_888, + CF_YCBCR_444, + CF_YCBCR_422, + CF_YCBCR_420, + CF_A8, + CF_L8, + SRC_DST_FORMAT_END, + + CF_MSK_1BIT, + CF_MSK_4BIT, + CF_MSK_8BIT, + CF_MSK_16BIT_565, + CF_MSK_16BIT_1555, + CF_MSK_16BIT_4444, + CF_MSK_32BIT_8888, + MSK_FORMAT_END, +}; + +enum rotation { + ORIGIN, + ROT_90, /* clockwise */ + ROT_180, + ROT_270, + XFLIP, /* x-axis flip */ + YFLIP, /* y-axis flip */ +}; + +/** + * @NO_REPEAT: no effect + * @REPEAT_NORMAL: repeat horizontally and vertically + * @REPEAT_PAD: pad with pad color + * @REPEAT_REFLECT: reflect horizontally and vertically + * @REPEAT_CLAMP: pad with edge color of original image + * + * DO NOT CHANGE THIS ORDER + */ +enum repeat { + NO_REPEAT = 0, + REPEAT_NORMAL, /* default setting */ + REPEAT_PAD, + REPEAT_REFLECT, REPEAT_MIRROR = REPEAT_REFLECT, + REPEAT_CLAMP, +}; + +enum scaling { + NO_SCALING, + SCALING_NEAREST, + SCALING_BILINEAR, +}; + +/** + * @SCALING_PIXELS: ratio in pixels + * @SCALING_RATIO: ratio in fixed point 16 + */ +enum scaling_factor { + SCALING_PIXELS, + SCALING_RATIO, +}; + +/** + * premultiplied alpha + */ +enum premultiplied { + PREMULTIPLIED, + NON_PREMULTIPLIED, +}; + +/** + * @TRANSP: discard bluescreen color + * @BLUSCR: replace bluescreen color with background color + */ +enum bluescreen { + OPAQUE, + TRANSP, + BLUSCR, +}; + +/** + * DO NOT CHANGE THIS ORDER + */ +enum blit_op { + BLIT_OP_SOLID_FILL = 0, + + BLIT_OP_CLR, + BLIT_OP_SRC, BLIT_OP_SRC_COPY = BLIT_OP_SRC, + BLIT_OP_DST, + BLIT_OP_SRC_OVER, + BLIT_OP_DST_OVER, BLIT_OP_OVER_REV = BLIT_OP_DST_OVER, + BLIT_OP_SRC_IN, + BLIT_OP_DST_IN, BLIT_OP_IN_REV = BLIT_OP_DST_IN, + BLIT_OP_SRC_OUT, + BLIT_OP_DST_OUT, BLIT_OP_OUT_REV = BLIT_OP_DST_OUT, + BLIT_OP_SRC_ATOP, + BLIT_OP_DST_ATOP, BLIT_OP_ATOP_REV = BLIT_OP_DST_ATOP, + BLIT_OP_XOR, + + BLIT_OP_ADD, + BLIT_OP_MULTIPLY, + BLIT_OP_SCREEN, + BLIT_OP_DARKEN, + BLIT_OP_LIGHTEN, + + BLIT_OP_DISJ_SRC_OVER, + BLIT_OP_DISJ_DST_OVER, BLIT_OP_SATURATE = BLIT_OP_DISJ_DST_OVER, + BLIT_OP_DISJ_SRC_IN, + BLIT_OP_DISJ_DST_IN, BLIT_OP_DISJ_IN_REV = BLIT_OP_DISJ_DST_IN, + BLIT_OP_DISJ_SRC_OUT, + BLIT_OP_DISJ_DST_OUT, BLIT_OP_DISJ_OUT_REV = BLIT_OP_DISJ_DST_OUT, + BLIT_OP_DISJ_SRC_ATOP, + BLIT_OP_DISJ_DST_ATOP, BLIT_OP_DISJ_ATOP_REV = BLIT_OP_DISJ_DST_ATOP, + BLIT_OP_DISJ_XOR, + + BLIT_OP_CONJ_SRC_OVER, + BLIT_OP_CONJ_DST_OVER, BLIT_OP_CONJ_OVER_REV = BLIT_OP_CONJ_DST_OVER, + BLIT_OP_CONJ_SRC_IN, + BLIT_OP_CONJ_DST_IN, BLIT_OP_CONJ_IN_REV = BLIT_OP_CONJ_DST_IN, + BLIT_OP_CONJ_SRC_OUT, + BLIT_OP_CONJ_DST_OUT, BLIT_OP_CONJ_OUT_REV = BLIT_OP_CONJ_DST_OUT, + BLIT_OP_CONJ_SRC_ATOP, + BLIT_OP_CONJ_DST_ATOP, BLIT_OP_CONJ_ATOP_REV = BLIT_OP_CONJ_DST_ATOP, + BLIT_OP_CONJ_XOR, + + /* user select coefficient manually */ + BLIT_OP_USER_COEFF, + + BLIT_OP_USER_SRC_GA, + + /* Add new operation type here */ + + /* end of blit operation */ + BLIT_OP_END, +}; +#define MAX_FIMG2D_BLIT_OP (int)BLIT_OP_END + +#ifdef __KERNEL__ + +/** + * @TMP: temporary buffer for 2-step blit at a single command + * + * DO NOT CHANGE THIS ORDER + */ +enum image_object { + IMAGE_SRC = 0, + IMAGE_MSK, + IMAGE_TMP, + IMAGE_DST, + IMAGE_END, +}; +#define MAX_IMAGES IMAGE_END +#define ISRC IMAGE_SRC +#define IMSK IMAGE_MSK +#define ITMP IMAGE_TMP +#define IDST IMAGE_DST +#define image_table(u) \ + { \ + (u)->src, \ + (u)->msk, \ + (u)->tmp, \ + (u)->dst \ + } + +struct fimg2d_dma { + struct dma_buf *dma_buf; + struct dma_buf_attachment *attachment; + struct sg_table *sg_table; + dma_addr_t dma_addr; + enum dma_data_direction direction; +}; + +#endif /* __KERNEL__ */ + +struct fimg2d_addr { + enum addr_space type; + int fd[FIMG2D_MAX_PLANES]; +}; + +struct fimg2d_rect { + int x1; + int y1; + int x2; /* x1 + width */ + int y2; /* y1 + height */ +}; + +/** + * pixels can be different from src, dst or clip rect + */ +struct fimg2d_scale { + enum scaling mode; + + /* ratio in pixels */ + int src_w, src_h; + int dst_w, dst_h; +}; + +struct fimg2d_clip { + __u32 enable; + int x1; + int y1; + int x2; /* x1 + width */ + int y2; /* y1 + height */ +}; + +struct fimg2d_repeat { + enum repeat mode; + unsigned long pad_color; +}; + +/** + * @bg_color: bg_color is valid only if bluescreen mode is BLUSCR. + */ +struct fimg2d_bluscr { + enum bluescreen mode; + unsigned long bs_color; + unsigned long bg_color; +}; + +/** + * @plane2: address info for CbCr in YCbCr 2plane mode + * @rect: crop/clip rect + */ +struct fimg2d_image { + int width; + int height; + int stride; + enum pixel_order order; + enum color_format fmt; + struct fimg2d_addr addr; + struct fimg2d_rect rect; +}; + +/** + * @solid_color: + * src color instead of src image + * color format and order must be ARGB8888(A is MSB). + * @g_alpha: global(constant) alpha. 0xff is opaque, 0 is transparnet + * @dither: dithering + * @rotate: rotation degree in clockwise + * @premult: alpha premultiplied mode for read & write + * @scaling: common scaling info for src and mask image. + * @repeat: repeat type (tile mode) + * @bluscr: blue screen and transparent mode + * @clipping: clipping rect within dst rect + */ +struct fimg2d_param { + unsigned long solid_color; + unsigned char g_alpha; + __u32 dither; + enum rotation rotate; + enum premultiplied premult; + struct fimg2d_scale scaling; + struct fimg2d_repeat repeat; + struct fimg2d_bluscr bluscr; + struct fimg2d_clip clipping; +}; + +/** + * @op: blit operation mode + * @src: set when using src image + * @msk: set when using mask image + * @tmp: set when using 2-step blit at a single command + * @dst: dst must not be null + * * tmp image must be the same to dst except memory address + * @seq_no: user debugging info. + * for example, user can set sequence number or pid. + */ +struct fimg2d_blit { + enum blit_op op; + struct fimg2d_param param; + struct fimg2d_image *src; + struct fimg2d_image *msk; + struct fimg2d_image *tmp; + struct fimg2d_image *dst; + enum blit_sync sync; + unsigned int seq_no; +}; + +#ifdef __KERNEL__ + +/** + * @ncmd: request count in blit command queue + * @wait_q: conext wait queue head +*/ +struct fimg2d_context { + atomic_t ncmd; + wait_queue_head_t wait_q; +}; + +/** + * @op: blit operation mode + * @sync: sync/async blit mode (currently support sync mode only) + * @image: array of image object. + * [0] is for src image + * [1] is for mask image + * [2] is for temporary buffer + * set when using 2-step blit at a single command + * [3] is for dst, dst must not be null + * * tmp image must be the same to dst except memory address + * @seq_no: user debugging info. + * for example, user can set sequence number or pid. + * @dma_all: total dma size of src, msk, dst + * @dma: array of dma info for each src, msk, tmp and dst + * @ctx: context is created when user open fimg2d device. + * @node: list head of blit command queue + */ +struct fimg2d_bltcmd { + enum blit_op op; + enum blit_sync sync; + unsigned int seq_no; + struct fimg2d_param param; + struct fimg2d_image image[MAX_IMAGES]; + struct fimg2d_dma dma[MAX_IMAGES][FIMG2D_MAX_PLANES]; + struct fimg2d_context *ctx; + struct list_head node; +}; + +/** + * @suspended: in suspend mode + * @clkon: power status for runtime pm + * @mem: resource platform device + * @regs: base address of hardware + * @dev: pointer to device struct + * @err: true if hardware is timed out while blitting + * @irq: irq number + * @nctx: context count + * @busy: 1 if hardware is running + * @bltlock: spinlock for blit + * @wait_q: blit wait queue head + * @cmd_q: blit command queue + * @workqueue: workqueue_struct for kfimg2dd +*/ +struct fimg2d_control { + atomic_t suspended; + atomic_t clkon; + struct clk *clock; + struct device *dev; + struct resource *mem; + void __iomem *regs; + + bool err; + int irq; + atomic_t nctx; + atomic_t busy; + atomic_t active; + spinlock_t bltlock; + wait_queue_head_t wait_q; + struct list_head cmd_q; + struct workqueue_struct *work_q; + + void (*blit)(struct fimg2d_control *info); + int (*configure)(struct fimg2d_control *info, + struct fimg2d_bltcmd *cmd); + void (*run)(struct fimg2d_control *info); + void (*stop)(struct fimg2d_control *info); + void (*dump)(struct fimg2d_control *info); + void (*finalize)(struct fimg2d_control *info); +}; + +int fimg2d_register_ops(struct fimg2d_control *info); + +#endif /* __KERNEL__ */ + +#endif /* __FIMG2D_H__ */ |