libcsc has moved from hardware/samsung_slsi/exynos5
authorYunji Kim <yunji.kim@samsung.com>
Fri, 12 Oct 2012 05:05:39 +0000 (05:05 +0000)
committerHuisung Kang <hs1218.kang@samsung.com>
Sun, 28 Oct 2012 22:42:21 +0000 (07:42 +0900)
Change-Id: Iff9ebd8826fcc6c0b94b2e33f2c894a74850d4c1
Signed-off-by: Yunji Kim <yunji.kim@samsung.com>
Android.mk [new file with mode: 0644]
libcsc/Android.mk [new file with mode: 0644]
libcsc/csc.c [new file with mode: 0644]
libcsc/csc.h [new file with mode: 0644]
libcsc/csc_helper.c [new file with mode: 0644]

diff --git a/Android.mk b/Android.mk
new file mode 100644 (file)
index 0000000..a93a9a8
--- /dev/null
@@ -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 (file)
index 0000000..eeeae2f
--- /dev/null
@@ -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 (file)
index 0000000..4f2aac6
--- /dev/null
@@ -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 <cutils/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <utils/Log.h>
+#include <system/graphics.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 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 (file)
index 0000000..5fc50a2
--- /dev/null
@@ -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 (file)
index 0000000..9f13d62
--- /dev/null
@@ -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 <cutils/log.h>
+
+#include <system/graphics.h>
+
+#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;
+}