From 5d926760d6287638066c9f4ac03414c99661f816 Mon Sep 17 00:00:00 2001 From: Yunji Kim Date: Fri, 12 Oct 2012 05:05:39 +0000 Subject: [PATCH] libcsc has moved from hardware/samsung_slsi/exynos5 Change-Id: Iff9ebd8826fcc6c0b94b2e33f2c894a74850d4c1 Signed-off-by: Yunji Kim --- Android.mk | 20 ++ libcsc/Android.mk | 68 +++++ libcsc/csc.c | 726 ++++++++++++++++++++++++++++++++++++++++++++ libcsc/csc.h | 375 +++++++++++++++++++++++ libcsc/csc_helper.c | 86 ++++++ 5 files changed, 1275 insertions(+) create mode 100644 Android.mk create mode 100644 libcsc/Android.mk create mode 100644 libcsc/csc.c create mode 100644 libcsc/csc.h create mode 100644 libcsc/csc_helper.c diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..a93a9a8 --- /dev/null +++ b/Android.mk @@ -0,0 +1,20 @@ +# +# 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. +# + +common_exynos_dirs := \ + libcsc + +include $(call all-named-subdir-makefiles,$(common_exynos_dirs)) diff --git a/libcsc/Android.mk b/libcsc/Android.mk new file mode 100644 index 0000000..eeeae2f --- /dev/null +++ b/libcsc/Android.mk @@ -0,0 +1,68 @@ +LOCAL_PATH := $(call my-dir) + +OMX_NAME := exynos + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + csc_helper.c + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) + +LOCAL_C_INCLUDES := \ + system/core/include \ + $(LOCAL_PATH)/../../openmax/include/khronos \ + $(LOCAL_PATH)/../../openmax/include/$(OMX_NAME) \ + hardware/samsung_slsi/exynos5/include \ + hardware/samsung_slsi/exynos/include + +LOCAL_CFLAGS := \ + -DUSE_SAMSUNG_COLORFORMAT \ + -DEXYNOS_OMX + +LOCAL_MODULE := libcsc_helper +LOCAL_MODULE_TAGS := optional +LOCAL_STATIC_LIBRARIES := liblog + +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + csc.c + +LOCAL_C_INCLUDES := \ + hardware/samsung_slsi/exynos5/include \ + $(LOCAL_PATH)/../../openmax/include/khronos \ + $(LOCAL_PATH)/../../openmax/include/$(OMX_NAME) \ + $(LOCAL_PATH)/../libexynosutils + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) + +LOCAL_CFLAGS := + +LOCAL_MODULE := libcsc + +LOCAL_PRELINK_MODULE := false + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libswconverter +LOCAL_WHOLE_STATIC_LIBRARIES := libcsc_helper +LOCAL_SHARED_LIBRARIES := liblog libexynosutils + +LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../include +LOCAL_CFLAGS += -DENABLE_GSCALER +LOCAL_SHARED_LIBRARIES += libexynosgscaler + +LOCAL_CFLAGS += -DUSE_ION +LOCAL_SHARED_LIBRARIES += libion_exynos + +LOCAL_CFLAGS += -DEXYNOS_OMX + +include $(BUILD_SHARED_LIBRARY) diff --git a/libcsc/csc.c b/libcsc/csc.c new file mode 100644 index 0000000..4f2aac6 --- /dev/null +++ b/libcsc/csc.c @@ -0,0 +1,726 @@ +/* + * + * 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 + +#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 ENABLE_FIMC +#include "hwconverter_wrapper.h" +#endif + +#ifdef ENABLE_GSCALER +#include "exynos_gscaler.h" +#endif + +#define GSCALER_IMG_ALIGN 16 +#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; + unsigned int mode_drm; +} CSC_FORMAT; + +typedef struct _CSC_BUFFER { + void *planes[CSC_MAX_PLANES]; +} CSC_BUFFER; + +typedef struct _CSC_HW_PROPERTY { + int fixed_node; + int mode_drm; +} CSC_HW_PROPERTY; + +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_HW_PROPERTY hw_property; +} CSC_HANDLE; + +/* 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 ENABLE_FIMC + case CSC_HW_TYPE_FIMC: + { + void *src_addr[3]; + void *dst_addr[3]; + OMX_COLOR_FORMATTYPE src_omx_format; + OMX_COLOR_FORMATTYPE dst_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]; + src_omx_format = hal_2_omx_pixel_format(handle->src_format.color_format); + dst_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, + dst_omx_format, + src_omx_format); + break; + } +#endif +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + if (exynos_gsc_convert(handle->csc_hw_handle) != 0) { + ALOGE("%s:: exynos_gsc_convert() fail", __func__); + ret = CSC_Error; + } + break; +#endif + default: + ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type); + ret = CSC_ErrorNotImplemented; + break; + } + + return ret; +} + +static CSC_ERRORCODE csc_init_hw( + void *handle) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + 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: + csc_handle->csc_hw_handle = csc_hwconverter_open(); + ALOGV("%s:: CSC_HW_TYPE_FIMC", __func__); + break; +#endif +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + if (csc_handle->hw_property.fixed_node >= 0) + csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0, 0); + else + csc_handle->csc_hw_handle = exynos_gsc_create(); + ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__); + break; +#endif + default: + ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__); + csc_handle->csc_hw_handle == NULL; + break; + } + } + + 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; + } + } + + ALOGV("%s:: CSC_METHOD=%d", __func__, csc_handle->csc_method); + + return ret; +} + +static CSC_ERRORCODE csc_set_format( + void *handle) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + if (csc_handle->csc_method == CSC_METHOD_HW) { + switch (csc_handle->csc_hw_type) { + case CSC_HW_TYPE_FIMC: + break; +#ifdef ENABLE_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, + csc_handle->src_format.crop_width, + csc_handle->src_format.crop_height, + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format), + csc_handle->src_format.cacheable, + csc_handle->hw_property.mode_drm); + + 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, + csc_handle->dst_format.crop_width, + csc_handle->dst_format.crop_height, + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format), + csc_handle->dst_format.cacheable, + csc_handle->hw_property.mode_drm, + 0); + break; +#endif + default: + ALOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + return ret; +} + +static CSC_ERRORCODE csc_set_buffer( + void *handle) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + if (csc_handle->csc_method == CSC_METHOD_HW) { + switch (csc_handle->csc_hw_type) { + case CSC_HW_TYPE_FIMC: + break; +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, -1); + exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, -1); + break; +#endif + default: + ALOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + return ret; +} + +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->hw_property.fixed_node = -1; + csc_handle->hw_property.mode_drm = 0; + csc_handle->csc_method = 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 ENABLE_FIMC + case CSC_HW_TYPE_FIMC: + csc_hwconverter_close(csc_handle->csc_hw_handle); + break; +#endif +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_destroy(csc_handle->csc_hw_handle); + break; +#endif + default: + ALOGE("%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_set_hw_property( + void *handle, + CSC_HW_PROPERTY_TYPE property, + int value) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + switch (property) { + case CSC_HW_PROPERTY_FIXED_NODE: + csc_handle->hw_property.fixed_node = value; + break; + case CSC_HW_PROPERTY_MODE_DRM: + csc_handle->hw_property.mode_drm = value; + break; + default: + ALOGE("%s:: not supported hw property", __func__); + ret = CSC_ErrorUnsupportFormat; + } + + 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; + + 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; + + return ret; +} + +CSC_ERRORCODE csc_set_src_buffer( + void *handle, + void *addr[3]) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + csc_handle->src_buffer.planes[CSC_Y_PLANE] = addr[0]; + csc_handle->src_buffer.planes[CSC_U_PLANE] = addr[1]; + csc_handle->src_buffer.planes[CSC_V_PLANE] = addr[2]; + + return ret; +} + +CSC_ERRORCODE csc_set_dst_buffer( + void *handle, + void *addr[3]) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + csc_handle->dst_buffer.planes[CSC_Y_PLANE] = addr[0]; + csc_handle->dst_buffer.planes[CSC_U_PLANE] = addr[1]; + csc_handle->dst_buffer.planes[CSC_V_PLANE] = addr[2]; + + 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) && + (csc_handle->csc_hw_handle == NULL)) + csc_init_hw(handle); + + csc_set_format(csc_handle); + csc_set_buffer(csc_handle); + + 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..5fc50a2 --- /dev/null +++ b/libcsc/csc.h @@ -0,0 +1,375 @@ +/* + * 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 + +#define CSC_MAX_PLANES 3 + +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; + +typedef enum _CSC_HW_PROPERTY_TYPE { + CSC_HW_PROPERTY_FIXED_NODE = 0, + CSC_HW_PROPERTY_MODE_DRM, +} CSC_HW_PROPERTY_TYPE; + +/* + * 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); + +/* + * Set hw property + * + * @param handle + * CSC handle[in] + * + * @param property + * csc hw property[in] + * + * @param value + * csc hw property value[in] + * + * @return + * csc handle + */ +CSC_ERRORCODE csc_set_hw_property( + void *handle, + CSC_HW_PROPERTY_TYPE property, + int value); + +/* + * 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, + void *addr[CSC_MAX_PLANES]); + +/* + * 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, + void *addr[CSC_MAX_PLANES]); + +/* + * 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/csc_helper.c b/libcsc/csc_helper.c new file mode 100644 index 0000000..9f13d62 --- /dev/null +++ b/libcsc/csc_helper.c @@ -0,0 +1,86 @@ +/* + * + * 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. + */ + +#define LOG_TAG "libcsc_helper" +#include + +#include + +#include "Exynos_OMX_Def.h" + +#include "csc.h" +#include "exynos_format.h" + +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_422_I: + omx_format = OMX_COLOR_FormatYCbYCr; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P: + omx_format = OMX_COLOR_FormatYUV420Planar; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + omx_format = OMX_COLOR_FormatYUV420SemiPlanar; + break; + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + omx_format = OMX_SEC_COLOR_FormatNV12TPhysicalAddress; + 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_FormatYCbYCr: + hal_format = HAL_PIXEL_FORMAT_YCbCr_422_I; + break; + case OMX_COLOR_FormatYUV420Planar: + hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP; + break; + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + hal_format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; + break; + case OMX_COLOR_Format32bitARGB8888: + hal_format = HAL_PIXEL_FORMAT_ARGB888; + break; + default: + hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + } + return hal_format; +} -- 2.20.1