--- /dev/null
+/*
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * 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