From 47bd95305f14b3b8e2a52fcf817f112b1e9bb92f Mon Sep 17 00:00:00 2001 From: Jiho Chang Date: Sat, 24 Mar 2012 05:56:11 +0900 Subject: hardware: exynos5: add initial libcsc Change-Id: Ia8ba645f1389f86f8aa5136f462607ebae11f656 Signed-off-by: Jiho Chang --- libcsc/Android.mk | 56 ++++ libcsc/csc.c | 739 +++++++++++++++++++++++++++++++++++++++++ libcsc/csc.h | 355 ++++++++++++++++++++ libcsc/hwconverter_wrapper.cpp | 135 ++++++++ libcsc/hwconverter_wrapper.h | 107 ++++++ 5 files changed, 1392 insertions(+) create mode 100644 libcsc/Android.mk create mode 100644 libcsc/csc.c create mode 100644 libcsc/csc.h create mode 100644 libcsc/hwconverter_wrapper.cpp create mode 100644 libcsc/hwconverter_wrapper.h (limited to 'libcsc') diff --git a/libcsc/Android.mk b/libcsc/Android.mk new file mode 100644 index 0000000..6be148c --- /dev/null +++ b/libcsc/Android.mk @@ -0,0 +1,56 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_COPY_HEADERS_TO := libsecmm +LOCAL_COPY_HEADERS := \ + csc.h + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + csc.c + +ifeq ($(BOARD_USE_EXYNOS_OMX), true) +OMX_NAME := exynos +else +OMX_NAME := sec +endif + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../exynos_omx/openmax/$(OMX_NAME)_omx/include/khronos \ + $(LOCAL_PATH)/../exynos_omx/openmax/$(OMX_NAME)_omx/include/$(OMX_NAME) \ + $(LOCAL_PATH)/../libexynosutils + +LOCAL_CFLAGS := + +LOCAL_MODULE := libcsc + +LOCAL_PRELINK_MODULE := false + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libswconverter +LOCAL_SHARED_LIBRARIES := liblog libexynosutils + +ifeq ($(BOARD_USE_SAMSUNG_COLORFORMAT), true) +LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT +endif + +ifeq ($(TARGET_BOARD_PLATFORM), exynos5) +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../include +LOCAL_CFLAGS += -DUSE_GSCALER +LOCAL_SHARED_LIBRARIES += libexynosgscaler +endif + +ifeq ($(BOARD_USE_V4L2_ION),true) +LOCAL_CFLAGS += -DUSE_ION +LOCAL_SHARED_LIBRARIES += libion +endif + +ifeq ($(BOARD_USE_EXYNOS_OMX), true) +LOCAL_CFLAGS += -DEXYNOS_OMX +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/libcsc/csc.c b/libcsc/csc.c new file mode 100644 index 0000000..26b26cc --- /dev/null +++ b/libcsc/csc.c @@ -0,0 +1,739 @@ +/* + * + * Copyright 2012 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc.c + * + * @brief color space convertion abstract source + * + * @author Pyoungjae Jung(pjet.jung@samsung.com) + * + * @version 1.0.0 + * + * @history + * 2012.1.11 : Create + */ +#define LOG_TAG "libcsc" +#include + +#include +#include +#include + +#include "csc.h" +#include "exynos_format.h" +#include "swconverter.h" + +#ifdef EXYNOS_OMX +#include "Exynos_OMX_Def.h" +#else +#include "SEC_OMX_Def.h" +#endif + +#ifdef USE_FIMC +#include "hwconverter_wrapper.h" +#endif + +#ifdef USE_GSCALER +#include "exynos_gscaler.h" +#endif + +#define GSCALER_IMG_ALIGN 16 +#define CSC_MAX_PLANES 3 +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +typedef enum _CSC_PLANE { + CSC_Y_PLANE = 0, + CSC_RGB_PLANE = 0, + CSC_U_PLANE = 1, + CSC_UV_PLANE = 1, + 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; + unsigned int crop_left; + unsigned int crop_top; + unsigned int crop_width; + unsigned int crop_height; + unsigned int color_format; + unsigned int cacheable; +} CSC_FORMAT; + +typedef struct _CSC_BUFFER { + unsigned char *planes[CSC_MAX_PLANES]; + int ion_fd; +} CSC_BUFFER; + +typedef struct _CSC_HANDLE { + CSC_FORMAT dst_format; + CSC_FORMAT src_format; + CSC_BUFFER dst_buffer; + CSC_BUFFER src_buffer; + CSC_METHOD csc_method; + CSC_HW_TYPE csc_hw_type; + void *csc_hw_handle; +} CSC_HANDLE; + +OMX_COLOR_FORMATTYPE hal_2_omx_pixel_format( + unsigned int hal_format) +{ + OMX_COLOR_FORMATTYPE omx_format; + switch (hal_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_P: + omx_format = OMX_COLOR_FormatYUV420Planar; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + omx_format = OMX_COLOR_FormatYUV420SemiPlanar; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: + omx_format = OMX_SEC_COLOR_FormatNV12Tiled; + break; + case HAL_PIXEL_FORMAT_ARGB888: + omx_format = OMX_COLOR_Format32bitARGB8888; + break; + default: + omx_format = OMX_COLOR_FormatYUV420Planar; + break; + } + return omx_format; +} + +unsigned int omx_2_hal_pixel_format( + OMX_COLOR_FORMATTYPE omx_format) +{ + unsigned int hal_format; + switch (omx_format) { + case OMX_COLOR_FormatYUV420Planar: + hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; + break; + case OMX_COLOR_Format32bitARGB8888: + hal_format = HAL_PIXEL_FORMAT_ARGB888; + break; + default: + hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + } + return hal_format; +} + +/* source is RGB888 */ +static CSC_ERRORCODE conv_sw_src_argb888( + CSC_HANDLE *handle) +{ + CSC_ERRORCODE ret = CSC_ErrorNone; + + switch (handle->dst_format.color_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_P: + csc_ARGB8888_to_YUV420P( + (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], + (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE], + handle->src_format.width, + handle->src_format.height); + ret = CSC_ErrorNone; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + csc_ARGB8888_to_YUV420SP_NEON( + (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE], + handle->src_format.width, + handle->src_format.height); + ret = CSC_ErrorNone; + break; + default: + ret = CSC_ErrorUnsupportFormat; + break; + } + + return ret; +} + +/* source is NV12T */ +static CSC_ERRORCODE conv_sw_src_nv12t( + CSC_HANDLE *handle) +{ + CSC_ERRORCODE ret = CSC_ErrorNone; + + switch (handle->dst_format.color_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_P: + csc_tiled_to_linear_y_neon( + (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], + handle->src_format.width, + handle->src_format.height); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], + (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], + handle->src_format.width, + handle->src_format.height / 2); + ret = CSC_ErrorNone; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + csc_tiled_to_linear_y_neon( + (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], + handle->src_format.width, + handle->src_format.height); + csc_tiled_to_linear_uv_neon( + (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], + handle->src_format.width, + handle->src_format.height / 2); + ret = CSC_ErrorNone; + break; + default: + ret = CSC_ErrorUnsupportFormat; + break; + } + + return ret; +} + +/* source is YUV420P */ +static CSC_ERRORCODE conv_sw_src_yuv420p( + CSC_HANDLE *handle) +{ + CSC_ERRORCODE ret = CSC_ErrorNone; + + switch (handle->dst_format.color_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_P: /* bypass */ + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], + handle->src_format.width * handle->src_format.height); + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE], + (handle->src_format.width * handle->src_format.height) >> 2); + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE], + (handle->src_format.width * handle->src_format.height) >> 2); + ret = CSC_ErrorNone; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], + handle->src_format.width * handle->src_format.height); + csc_interleave_memcpy_neon( + (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE], + (handle->src_format.width * handle->src_format.height) >> 2); + ret = CSC_ErrorNone; + break; + default: + ret = CSC_ErrorUnsupportFormat; + break; + } + + return ret; +} + +/* source is YUV420SP */ +static CSC_ERRORCODE conv_sw_src_yuv420sp( + CSC_HANDLE *handle) +{ + CSC_ERRORCODE ret = CSC_ErrorNone; + + switch (handle->dst_format.color_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_P: + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], + handle->src_format.width * handle->src_format.height); + csc_deinterleave_memcpy( + (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], + (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], + handle->src_format.width * handle->src_format.height >> 1); + ret = CSC_ErrorNone; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: /* bypass */ + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], + handle->src_format.width * handle->src_format.height); + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], + handle->src_format.width * handle->src_format.height >> 1); + ret = CSC_ErrorNone; + break; + default: + ret = CSC_ErrorUnsupportFormat; + break; + } + + return ret; +} + +static CSC_ERRORCODE conv_sw( + CSC_HANDLE *handle) +{ + CSC_ERRORCODE ret = CSC_ErrorNone; + + switch (handle->src_format.color_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: + ret = conv_sw_src_nv12t(handle); + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P: + ret = conv_sw_src_yuv420p(handle); + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + ret = conv_sw_src_yuv420sp(handle); + break; + case HAL_PIXEL_FORMAT_ARGB888: + ret = conv_sw_src_argb888(handle); + break; + default: + ret = CSC_ErrorUnsupportFormat; + break; + } + + return ret; +} + +static CSC_ERRORCODE conv_hw( + CSC_HANDLE *handle) +{ + CSC_ERRORCODE ret = CSC_ErrorNone; + + switch (handle->csc_hw_type) { +#ifdef USE_FIMC + case CSC_HW_TYPE_FIMC: + { + void *src_addr[3]; + void *dst_addr[3]; + OMX_COLOR_FORMATTYPE omx_format; + src_addr[0] = handle->src_buffer.planes[CSC_Y_PLANE]; + src_addr[1] = handle->src_buffer.planes[CSC_UV_PLANE]; + dst_addr[0] = handle->dst_buffer.planes[CSC_Y_PLANE]; + dst_addr[1] = handle->dst_buffer.planes[CSC_U_PLANE]; + dst_addr[2] = handle->dst_buffer.planes[CSC_V_PLANE]; + omx_format = hal_2_omx_pixel_format(handle->dst_format.color_format); + csc_hwconverter_convert_nv12t( + handle->csc_hw_handle, + dst_addr, + src_addr, + handle->dst_format.width, + handle->dst_format.height, + omx_format); + break; + } +#endif +#ifdef USE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_convert(handle->csc_hw_handle); + break; +#endif + default: + LOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + + return CSC_ErrorNotImplemented; +} + +void *csc_init( + CSC_METHOD *method) +{ + CSC_HANDLE *csc_handle; + csc_handle = (CSC_HANDLE *)malloc(sizeof(CSC_HANDLE)); + if (csc_handle == NULL) + return NULL; + + memset(csc_handle, 0, sizeof(CSC_HANDLE)); + + csc_handle->csc_method = *method; + + if (csc_handle->csc_method == CSC_METHOD_HW || + csc_handle->csc_method == CSC_METHOD_PREFER_HW) { +#ifdef USE_FIMC + csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC; +#endif +#ifdef USE_GSCALER + csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER; +#endif + switch (csc_handle->csc_hw_type) { +#ifdef USE_FIMC + case CSC_HW_TYPE_FIMC: + csc_handle->csc_hw_handle = csc_hwconverter_open(); + LOGD("%s:: CSC_HW_TYPE_FIMC", __func__); + break; +#endif +#ifdef USE_GSCALER + case CSC_HW_TYPE_GSCALER: + csc_handle->csc_hw_handle = exynos_gsc_create(); + LOGD("%s:: CSC_HW_TYPE_GSCALER", __func__); + break; +#endif + default: + LOGE("%s:: unsupported csc_hw_type, csc use sw", __func__); + csc_handle->csc_hw_handle == NULL; + break; + } + } + + if (csc_handle->csc_method == CSC_METHOD_PREFER_HW) { + if (csc_handle->csc_hw_handle == NULL) { + csc_handle->csc_method = CSC_METHOD_SW; + *method = CSC_METHOD_SW; + } else { + csc_handle->csc_method = CSC_METHOD_HW; + *method = CSC_METHOD_HW; + } + } + + if (csc_handle->csc_method == CSC_METHOD_HW) { + if (csc_handle->csc_hw_handle == NULL) { + LOGE("%s:: CSC_METHOD_HW can't open HW", __func__); + free(csc_handle); + csc_handle = NULL; + } + } + + LOGD("%s:: CSC_METHOD=%d", __func__, csc_handle->csc_method); + + return (void *)csc_handle; +} + +CSC_ERRORCODE csc_deinit( + void *handle) +{ + CSC_ERRORCODE ret = CSC_ErrorNone; + CSC_HANDLE *csc_handle; + + csc_handle = (CSC_HANDLE *)handle; + if (csc_handle->csc_method == CSC_METHOD_HW) { + switch (csc_handle->csc_hw_type) { +#ifdef USE_FIMC + case CSC_HW_TYPE_FIMC: + csc_hwconverter_close(csc_handle->csc_hw_handle); + break; +#endif +#ifdef USE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_destroy(csc_handle->csc_hw_handle); + break; +#endif + default: + LOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + if (csc_handle != NULL) { + free(csc_handle); + ret = CSC_ErrorNone; + } + + return ret; +} + +CSC_ERRORCODE csc_get_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; + *method = csc_handle->csc_method; + + return ret; +} + +CSC_ERRORCODE csc_get_src_format( + void *handle, + unsigned int *width, + unsigned int *height, + unsigned int *crop_left, + unsigned int *crop_top, + unsigned int *crop_width, + unsigned int *crop_height, + unsigned int *color_format, + unsigned int *cacheable) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + *width = csc_handle->src_format.width; + *height = csc_handle->src_format.height; + *crop_left = csc_handle->src_format.crop_left; + *crop_top = csc_handle->src_format.crop_top; + *crop_width = csc_handle->src_format.crop_width; + *crop_height = csc_handle->src_format.crop_height; + *color_format = csc_handle->src_format.color_format; + *cacheable = csc_handle->src_format.cacheable; + + return ret; +} + +CSC_ERRORCODE csc_set_src_format( + void *handle, + unsigned int width, + unsigned int height, + unsigned int crop_left, + unsigned int crop_top, + unsigned int crop_width, + unsigned int crop_height, + unsigned int color_format, + unsigned int cacheable) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + csc_handle->src_format.width = width; + csc_handle->src_format.height = height; + csc_handle->src_format.crop_left = crop_left; + csc_handle->src_format.crop_top = crop_top; + csc_handle->src_format.crop_width = crop_width; + csc_handle->src_format.crop_height = crop_height; + csc_handle->src_format.color_format = color_format; + csc_handle->src_format.cacheable = cacheable; + + if (csc_handle->csc_method == CSC_METHOD_HW) { + switch (csc_handle->csc_hw_type) { + case CSC_HW_TYPE_FIMC: + break; +#ifdef USE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_set_src_format( + csc_handle->csc_hw_handle, + ALIGN(csc_handle->src_format.width, GSCALER_IMG_ALIGN), + ALIGN(csc_handle->src_format.height, GSCALER_IMG_ALIGN), + csc_handle->src_format.crop_left, + csc_handle->src_format.crop_top, + ALIGN(csc_handle->src_format.crop_width, GSCALER_IMG_ALIGN), + ALIGN(csc_handle->src_format.crop_height, GSCALER_IMG_ALIGN), + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format), + csc_handle->src_format.cacheable); + break; +#endif + default: + LOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + return ret; +} + +CSC_ERRORCODE csc_get_dst_format( + void *handle, + unsigned int *width, + unsigned int *height, + unsigned int *crop_left, + unsigned int *crop_top, + unsigned int *crop_width, + unsigned int *crop_height, + unsigned int *color_format, + unsigned int *cacheable) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + *width = csc_handle->dst_format.width; + *height = csc_handle->dst_format.height; + *crop_left = csc_handle->dst_format.crop_left; + *crop_top = csc_handle->dst_format.crop_top; + *crop_width = csc_handle->dst_format.crop_width; + *crop_height = csc_handle->dst_format.crop_height; + *color_format = csc_handle->dst_format.color_format; + *cacheable = csc_handle->dst_format.cacheable; + + return ret; +} + +CSC_ERRORCODE csc_set_dst_format( + void *handle, + unsigned int width, + unsigned int height, + unsigned int crop_left, + unsigned int crop_top, + unsigned int crop_width, + unsigned int crop_height, + unsigned int color_format, + unsigned int cacheable) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + csc_handle->dst_format.width = width; + csc_handle->dst_format.height = height; + csc_handle->dst_format.crop_left = crop_left; + csc_handle->dst_format.crop_top = crop_top; + csc_handle->dst_format.crop_width = crop_width; + csc_handle->dst_format.crop_height = crop_height; + csc_handle->dst_format.color_format = color_format; + csc_handle->dst_format.cacheable = cacheable; + + if (csc_handle->csc_method == CSC_METHOD_HW) { + switch (csc_handle->csc_hw_type) { + case CSC_HW_TYPE_FIMC: + break; +#ifdef USE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_set_dst_format( + csc_handle->csc_hw_handle, + ALIGN(csc_handle->dst_format.width, GSCALER_IMG_ALIGN), + ALIGN(csc_handle->dst_format.height, GSCALER_IMG_ALIGN), + csc_handle->dst_format.crop_left, + csc_handle->dst_format.crop_top, + ALIGN(csc_handle->dst_format.crop_width, GSCALER_IMG_ALIGN), + ALIGN(csc_handle->dst_format.crop_height, GSCALER_IMG_ALIGN), + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format), + csc_handle->dst_format.cacheable); + break; +#endif + default: + LOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + return ret; +} + +CSC_ERRORCODE csc_set_src_buffer( + void *handle, + unsigned char *y, + unsigned char *u, + unsigned char *v, + int ion_fd) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + void *addr[3] = {NULL, }; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + csc_handle->src_buffer.planes[CSC_Y_PLANE] = y; + csc_handle->src_buffer.planes[CSC_U_PLANE] = u; + csc_handle->src_buffer.planes[CSC_V_PLANE] = v; + + if (csc_handle->csc_method == CSC_METHOD_HW) { + addr[0] = csc_handle->src_buffer.planes[CSC_Y_PLANE]; + addr[1] = csc_handle->src_buffer.planes[CSC_U_PLANE]; + addr[2] = csc_handle->src_buffer.planes[CSC_V_PLANE]; + + switch (csc_handle->csc_hw_type) { + case CSC_HW_TYPE_FIMC: + break; +#ifdef USE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, addr); + break; +#endif + default: + LOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + return ret; +} + +CSC_ERRORCODE csc_set_dst_buffer( + void *handle, + unsigned char *y, + unsigned char *u, + unsigned char *v, + int ion_fd) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + void *addr[3] = {NULL, }; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + csc_handle->dst_buffer.planes[CSC_Y_PLANE] = y; + csc_handle->dst_buffer.planes[CSC_U_PLANE] = u; + csc_handle->dst_buffer.planes[CSC_V_PLANE] = v; + + if (csc_handle->csc_method == CSC_METHOD_HW) { + addr[0] = csc_handle->dst_buffer.planes[CSC_Y_PLANE]; + addr[1] = csc_handle->dst_buffer.planes[CSC_U_PLANE]; + addr[2] = csc_handle->dst_buffer.planes[CSC_V_PLANE]; + + switch (csc_handle->csc_hw_type) { + case CSC_HW_TYPE_FIMC: + break; +#ifdef USE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, addr); + break; +#endif + default: + LOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + return ret; +} + +CSC_ERRORCODE csc_convert( + void *handle) +{ + CSC_HANDLE *csc_handle = (CSC_HANDLE *)handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (csc_handle == NULL) + return CSC_ErrorNotInit; + + if (csc_handle->csc_method == CSC_METHOD_HW) + ret = conv_hw(csc_handle); + else + ret = conv_sw(csc_handle); + + return ret; +} diff --git a/libcsc/csc.h b/libcsc/csc.h new file mode 100644 index 0000000..9069392 --- /dev/null +++ b/libcsc/csc.h @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc.h + * + * @brief color space convertion abstract header + * + * @author Pyoungjae Jung (pjet.jung@samsung.com) + * + * @version 1.0 + * + * @history + * 2011.12.27 : Create + */ + +#ifndef CSC_H +#define CSC_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _CSC_ERRORCODE { + CSC_ErrorNone = 0, + CSC_Error, + CSC_ErrorNotInit, + CSC_ErrorInvalidAddress, + CSC_ErrorUnsupportFormat, + CSC_ErrorNotImplemented +} CSC_ERRORCODE; + +typedef enum _CSC_METHOD { + CSC_METHOD_SW = 0, + CSC_METHOD_HW, + CSC_METHOD_PREFER_HW +} CSC_METHOD; + +/* + * change hal pixel format to omx pixel format + * + * @param hal_format + * hal pixel format[in] + * + * @return + * omx pixel format + */ +unsigned int hal_2_omx_pixel_format( + unsigned int hal_format); + +/* + * change omx pixel format to hal pixel format + * + * @param hal_format + * omx pixel format[in] + * + * @return + * hal pixel format + */ +unsigned int omx_2_hal_pixel_format( + unsigned int omx_format); + +/* + * Init CSC handle + * + * @return + * csc handle + */ +void *csc_init( + CSC_METHOD *method); + +/* + * Deinit CSC handle + * + * @param handle + * CSC handle[in] + * + * @return + * error code + */ +CSC_ERRORCODE csc_deinit( + void *handle); + +/* + * get color space converter method + * + * @param handle + * CSC handle[in] + * + * @param method + * CSC method[out] + * + * @return + * error code + */ +CSC_ERRORCODE csc_get_method( + void *handle, + CSC_METHOD *method); + +/* + * Get source format. + * + * @param handle + * CSC handle[in] + * + * @param width + * address of image width[out] + * + * @param height + * address of image height[out] + * + * @param crop_left + * address of image left crop size[out] + * + * @param crop_top + * address of image top crop size[out] + * + * @param crop_width + * address of cropped image width[out] + * + * @param crop_height + * address of cropped image height[out] + * + * @param color_format + * address of source color format(HAL format)[out] + * + * @return + * error code + */ +CSC_ERRORCODE csc_get_src_format( + void *handle, + unsigned int *width, + unsigned int *height, + unsigned int *crop_left, + unsigned int *crop_top, + unsigned int *crop_width, + unsigned int *crop_height, + unsigned int *color_format, + unsigned int *cacheable); + +/* + * Set source format. + * Don't call each converting time. + * Pls call this function as below. + * 1. first converting time + * 2. format is changed + * + * @param handle + * CSC handle[in] + * + * @param width + * image width[in] + * + * @param height + * image height[in] + * + * @param crop_left + * image left crop size[in] + * + * @param crop_top + * image top crop size[in] + * + * @param crop_width + * cropped image width[in] + * + * @param crop_height + * cropped image height[in] + * + * @param color_format + * source color format(HAL format)[in] + * + * @return + * error code + */ +CSC_ERRORCODE csc_set_src_format( + void *handle, + unsigned int width, + unsigned int height, + unsigned int crop_left, + unsigned int crop_top, + unsigned int crop_width, + unsigned int crop_height, + unsigned int color_format, + unsigned int cacheable); + +/* + * Get destination format. + * + * @param handle + * CSC handle[in] + * + * @param width + * address of image width[out] + * + * @param height + * address of image height[out] + * + * @param crop_left + * address of image left crop size[out] + * + * @param crop_top + * address of image top crop size[out] + * + * @param crop_width + * address of cropped image width[out] + * + * @param crop_height + * address of cropped image height[out] + * + * @param color_format + * address of color format(HAL format)[out] + * + * @return + * error code + */ +CSC_ERRORCODE csc_get_dst_format( + void *handle, + unsigned int *width, + unsigned int *height, + unsigned int *crop_left, + unsigned int *crop_top, + unsigned int *crop_width, + unsigned int *crop_height, + unsigned int *color_format, + unsigned int *cacheable); + +/* + * Set destination format + * Don't call each converting time. + * Pls call this function as below. + * 1. first converting time + * 2. format is changed + * + * @param handle + * CSC handle[in] + * + * @param width + * image width[in] + * + * @param height + * image height[in] + * + * @param crop_left + * image left crop size[in] + * + * @param crop_top + * image top crop size[in] + * + * @param crop_width + * cropped image width[in] + * + * @param crop_height + * cropped image height[in] + * + * @param color_format + * destination color format(HAL format)[in] + * + * @return + * error code + */ +CSC_ERRORCODE csc_set_dst_format( + void *handle, + unsigned int width, + unsigned int height, + unsigned int crop_left, + unsigned int crop_top, + unsigned int crop_width, + unsigned int crop_height, + unsigned int color_format, + unsigned int cacheable); + +/* + * Setup source buffer + * set_format func should be called before this this func. + * + * @param handle + * CSC handle[in] + * + * @param src_buffer + * source buffer pointer array[in] + * + * @param y + * y or RGB destination pointer[in] + * + * @param u + * u or uv destination pointer[in] + * + * @param v + * v or none destination pointer[in] + * + * @return + * error code + */ +CSC_ERRORCODE csc_set_src_buffer( + void *handle, + unsigned char *y, + unsigned char *u, + unsigned char *v, + int ion_fd); + +/* + * Setup destination buffer + * + * @param handle + * CSC handle[in] + * + * @param y + * y or RGB destination pointer[in] + * + * @param u + * u or uv destination pointer[in] + * + * @param v + * v or none destination pointer[in] + * + * @return + * error code + */ +CSC_ERRORCODE csc_set_dst_buffer( + void *handle, + unsigned char *y, + unsigned char *u, + unsigned char *v, + int ion_fd); + +/* + * Convert color space with presetup color format + * + * @param handle + * CSC handle[in] + * + * @return + * error code + */ +CSC_ERRORCODE csc_convert( + void *handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libcsc/hwconverter_wrapper.cpp b/libcsc/hwconverter_wrapper.cpp new file mode 100644 index 0000000..9f6cd07 --- /dev/null +++ b/libcsc/hwconverter_wrapper.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file hwconverter_wrapper.cpp + * + * @brief hwconverter_wrapper abstract libhwconverter and support c functions + * + * @author ShinWon Lee (shinwon.lee@samsung.com) + * + * @version 1.0 + * + * @history + * 2012.02.01 : Create + */ + +#include +#include + +#include "SEC_OMX_Def.h" +#include "hwconverter_wrapper.h" +#include "HardwareConverter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * create hwconverter handle + * + * @return + * fimc handle + */ +void *csc_hwconverter_open() +{ + HardwareConverter *hw_converter = NULL; + + hw_converter = new HardwareConverter; + if (hw_converter->bHWconvert_flag == 0) { + delete hw_converter; + hw_converter = NULL; + LOGE("%s LINE = %d HardwareConverter failed", __func__, __LINE__); + } + + return (void *)hw_converter; +} + +/* + * destroy hwconverter handle + * + * @param handle + * fimc handle[in] + * + * @return + * pass or fail + */ +HWCONVERTER_ERROR_CODE csc_hwconverter_close( + void *handle) +{ + HardwareConverter *hw_converter = (HardwareConverter *)handle; + + if (hw_converter != NULL) + delete hw_converter; + + return HWCONVERTER_RET_OK; +} + +/* + * convert color space nv12t to omxformat + * + * @param handle + * hwconverter handle[in] + * + * @param dst_addr + * y,u,v address of dst_addr[out] + * + * @param src_addr + * y,uv address of src_addr.Format is nv12t[in] + * + * @param width + * width of dst image[in] + * + * @param height + * height of dst image[in] + * + * @param omxformat + * omxformat of dst image[in] + * + * @return + * pass or fail + */ +HWCONVERTER_ERROR_CODE csc_hwconverter_convert_nv12t( + void *handle, + void **dst_addr, + void **src_addr, + unsigned int width, + unsigned int height, + OMX_COLOR_FORMATTYPE omxformat) +{ + HWCONVERTER_ERROR_CODE ret = HWCONVERTER_RET_OK; + HardwareConverter *hw_converter = (HardwareConverter *)handle; + + if (hw_converter == NULL) { + ret = HWCONVERTER_RET_FAIL; + goto EXIT; + } + + hw_converter->convert( + (void *)src_addr, (void *)dst_addr, + (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12TPhysicalAddress, + width, height, omxformat); + + ret = HWCONVERTER_RET_OK; + +EXIT: + + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/libcsc/hwconverter_wrapper.h b/libcsc/hwconverter_wrapper.h new file mode 100644 index 0000000..292a680 --- /dev/null +++ b/libcsc/hwconverter_wrapper.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file hwconverter_wrapper.h + * + * @brief hwconverter_wrapper abstract libhwconverter and support c functions + * + * @author ShinWon Lee (shinwon.lee@samsung.com) + * + * @version 1.0 + * + * @history + * 2012.02.01 : Create + */ + +#ifndef HWCONVERTER_WRAPPER_H + +#define HWCONVERTER_WRAPPER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/*--------------------------------------------------------------------------------*/ +/* Structure and Type */ +/*--------------------------------------------------------------------------------*/ +typedef enum { + HWCONVERTER_RET_OK = 0, + HWCONVERTER_RET_FAIL = -1 +} HWCONVERTER_ERROR_CODE; + +/*--------------------------------------------------------------------------------*/ +/* CSC FIMC APIs */ +/*--------------------------------------------------------------------------------*/ +/* + * create hwconverter handle + * + * @return + * hwconverter handle + */ +void *csc_fimc_open(); + +/* + * destroy hwconverter handle + * + * @param handle + * hwconverter handle[in] + * + * @return + * error code + */ +HWCONVERTER_ERROR_CODE csc_fimc_close( + void *handle); + +/* + * convert color space nv12t to omxformat + * + * @param handle + * hwconverter handle[in] + * + * @param dst_addr + * y,u,v address of dst_addr[out] + * + * @param src_addr + * y,uv address of src_addr.Format is nv12t[in] + * + * @param width + * width of dst image[in] + * + * @param height + * height of dst image[in] + * + * @param omxformat + * omxformat of dst image[in] + * + * @return + * error code + */ +HWCONVERTER_ERROR_CODE csc_fimc_convert_nv12t( + void *handle, + void **dst_addr, + void **src_addr, + unsigned int width, + unsigned int height, + OMX_COLOR_FORMATTYPE omxformat); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3