summaryrefslogtreecommitdiff
path: root/libcsc
diff options
context:
space:
mode:
authorJiho Chang <jiho04.chang@samsung.com>2012-03-24 05:56:11 +0900
committerDima Zavin <dima@android.com>2012-04-17 21:46:55 -0700
commit47bd95305f14b3b8e2a52fcf817f112b1e9bb92f (patch)
tree79e953012dab036578522af829014dc3c5aa6993 /libcsc
parent20c516838913956e6f86347b305fe29506e2b491 (diff)
downloadexynos5-47bd95305f14b3b8e2a52fcf817f112b1e9bb92f.tar.gz
hardware: exynos5: add initial libcsc
Change-Id: Ia8ba645f1389f86f8aa5136f462607ebae11f656 Signed-off-by: Jiho Chang <jiho04.chang@samsung.com>
Diffstat (limited to 'libcsc')
-rw-r--r--libcsc/Android.mk56
-rw-r--r--libcsc/csc.c739
-rw-r--r--libcsc/csc.h355
-rw-r--r--libcsc/hwconverter_wrapper.cpp135
-rw-r--r--libcsc/hwconverter_wrapper.h107
5 files changed, 1392 insertions, 0 deletions
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 <cutils/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <utils/Log.h>
+
+#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 <utils/Log.h>
+#include <dlfcn.h>
+
+#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 <OMX_Video.h>
+
+/*--------------------------------------------------------------------------------*/
+/* 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