blob: 385223c60b67bcc7319e12cbbca0ddfbae2c5d56 [file] [log] [blame]
Jiho Chang47bd9532012-03-24 05:56:11 +09001/*
2 *
3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * @file csc.c
20 *
21 * @brief color space convertion abstract source
22 *
23 * @author Pyoungjae Jung(pjet.jung@samsung.com)
24 *
25 * @version 1.0.0
26 *
27 * @history
28 * 2012.1.11 : Create
29 */
30#define LOG_TAG "libcsc"
31#include <cutils/log.h>
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <utils/Log.h>
Jiho Chang3b540842012-04-26 13:39:20 -070036#include <system/graphics.h>
Jiho Chang47bd9532012-03-24 05:56:11 +090037
38#include "csc.h"
39#include "exynos_format.h"
40#include "swconverter.h"
41
42#ifdef EXYNOS_OMX
43#include "Exynos_OMX_Def.h"
44#else
45#include "SEC_OMX_Def.h"
46#endif
47
Jiho Chang3b540842012-04-26 13:39:20 -070048#ifdef ENABLE_FIMC
Jiho Chang47bd9532012-03-24 05:56:11 +090049#include "hwconverter_wrapper.h"
50#endif
51
Jiho Chang3b540842012-04-26 13:39:20 -070052#ifdef ENABLE_GSCALER
Jiho Chang47bd9532012-03-24 05:56:11 +090053#include "exynos_gscaler.h"
54#endif
55
56#define GSCALER_IMG_ALIGN 16
Jiho Chang47bd9532012-03-24 05:56:11 +090057#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
58
59typedef enum _CSC_PLANE {
60 CSC_Y_PLANE = 0,
61 CSC_RGB_PLANE = 0,
62 CSC_U_PLANE = 1,
63 CSC_UV_PLANE = 1,
64 CSC_V_PLANE = 2
65} CSC_PLANE;
66
67typedef enum _CSC_HW_TYPE {
68 CSC_HW_TYPE_FIMC = 0,
69 CSC_HW_TYPE_GSCALER
70} CSC_HW_TYPE;
71
72typedef struct _CSC_FORMAT {
73 unsigned int width;
74 unsigned int height;
75 unsigned int crop_left;
76 unsigned int crop_top;
77 unsigned int crop_width;
78 unsigned int crop_height;
79 unsigned int color_format;
80 unsigned int cacheable;
Jiho Chang3b540842012-04-26 13:39:20 -070081 unsigned int mode_drm;
Jiho Chang47bd9532012-03-24 05:56:11 +090082} CSC_FORMAT;
83
84typedef struct _CSC_BUFFER {
SeungBeom Kimf77a2a92012-07-20 16:44:11 +090085 void *planes[CSC_MAX_PLANES];
Jiho Chang47bd9532012-03-24 05:56:11 +090086} CSC_BUFFER;
87
Jiho Chang3b540842012-04-26 13:39:20 -070088typedef struct _CSC_HW_PROPERTY {
89 int fixed_node;
90 int mode_drm;
91} CSC_HW_PROPERTY;
92
Jiho Chang47bd9532012-03-24 05:56:11 +090093typedef struct _CSC_HANDLE {
94 CSC_FORMAT dst_format;
95 CSC_FORMAT src_format;
96 CSC_BUFFER dst_buffer;
97 CSC_BUFFER src_buffer;
98 CSC_METHOD csc_method;
99 CSC_HW_TYPE csc_hw_type;
100 void *csc_hw_handle;
Jiho Chang3b540842012-04-26 13:39:20 -0700101 CSC_HW_PROPERTY hw_property;
Jiho Chang47bd9532012-03-24 05:56:11 +0900102} CSC_HANDLE;
103
Jiho Chang47bd9532012-03-24 05:56:11 +0900104/* source is RGB888 */
105static CSC_ERRORCODE conv_sw_src_argb888(
106 CSC_HANDLE *handle)
107{
108 CSC_ERRORCODE ret = CSC_ErrorNone;
109
110 switch (handle->dst_format.color_format) {
111 case HAL_PIXEL_FORMAT_YCbCr_420_P:
112 csc_ARGB8888_to_YUV420P(
113 (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
114 (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
115 (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
116 (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
117 handle->src_format.width,
118 handle->src_format.height);
119 ret = CSC_ErrorNone;
120 break;
121 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
122 csc_ARGB8888_to_YUV420SP_NEON(
123 (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
124 (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
125 (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
126 handle->src_format.width,
127 handle->src_format.height);
128 ret = CSC_ErrorNone;
129 break;
130 default:
131 ret = CSC_ErrorUnsupportFormat;
132 break;
133 }
134
135 return ret;
136}
137
138/* source is NV12T */
139static CSC_ERRORCODE conv_sw_src_nv12t(
140 CSC_HANDLE *handle)
141{
142 CSC_ERRORCODE ret = CSC_ErrorNone;
143
144 switch (handle->dst_format.color_format) {
145 case HAL_PIXEL_FORMAT_YCbCr_420_P:
146 csc_tiled_to_linear_y_neon(
147 (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
148 (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
149 handle->src_format.width,
150 handle->src_format.height);
151 csc_tiled_to_linear_uv_deinterleave_neon(
152 (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
153 (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
154 (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
155 handle->src_format.width,
156 handle->src_format.height / 2);
157 ret = CSC_ErrorNone;
158 break;
159 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
160 csc_tiled_to_linear_y_neon(
161 (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
162 (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
163 handle->src_format.width,
164 handle->src_format.height);
165 csc_tiled_to_linear_uv_neon(
166 (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
167 (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
168 handle->src_format.width,
169 handle->src_format.height / 2);
170 ret = CSC_ErrorNone;
171 break;
172 default:
173 ret = CSC_ErrorUnsupportFormat;
174 break;
175 }
176
177 return ret;
178}
179
180/* source is YUV420P */
181static CSC_ERRORCODE conv_sw_src_yuv420p(
182 CSC_HANDLE *handle)
183{
184 CSC_ERRORCODE ret = CSC_ErrorNone;
185
186 switch (handle->dst_format.color_format) {
187 case HAL_PIXEL_FORMAT_YCbCr_420_P: /* bypass */
188 memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
189 (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
190 handle->src_format.width * handle->src_format.height);
191 memcpy((unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
192 (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE],
193 (handle->src_format.width * handle->src_format.height) >> 2);
194 memcpy((unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
195 (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE],
196 (handle->src_format.width * handle->src_format.height) >> 2);
197 ret = CSC_ErrorNone;
198 break;
199 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
200 memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
201 (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
202 handle->src_format.width * handle->src_format.height);
203 csc_interleave_memcpy_neon(
204 (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
205 (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE],
206 (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE],
207 (handle->src_format.width * handle->src_format.height) >> 2);
208 ret = CSC_ErrorNone;
209 break;
210 default:
211 ret = CSC_ErrorUnsupportFormat;
212 break;
213 }
214
215 return ret;
216}
217
218/* source is YUV420SP */
219static CSC_ERRORCODE conv_sw_src_yuv420sp(
220 CSC_HANDLE *handle)
221{
222 CSC_ERRORCODE ret = CSC_ErrorNone;
223
224 switch (handle->dst_format.color_format) {
225 case HAL_PIXEL_FORMAT_YCbCr_420_P:
226 memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
227 (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
228 handle->src_format.width * handle->src_format.height);
229 csc_deinterleave_memcpy(
230 (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
231 (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
232 (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
233 handle->src_format.width * handle->src_format.height >> 1);
234 ret = CSC_ErrorNone;
235 break;
236 case HAL_PIXEL_FORMAT_YCbCr_420_SP: /* bypass */
237 memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
238 (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
239 handle->src_format.width * handle->src_format.height);
240 memcpy((unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
241 (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
242 handle->src_format.width * handle->src_format.height >> 1);
243 ret = CSC_ErrorNone;
244 break;
245 default:
246 ret = CSC_ErrorUnsupportFormat;
247 break;
248 }
249
250 return ret;
251}
252
253static CSC_ERRORCODE conv_sw(
254 CSC_HANDLE *handle)
255{
256 CSC_ERRORCODE ret = CSC_ErrorNone;
257
258 switch (handle->src_format.color_format) {
259 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
260 ret = conv_sw_src_nv12t(handle);
261 break;
262 case HAL_PIXEL_FORMAT_YCbCr_420_P:
263 ret = conv_sw_src_yuv420p(handle);
264 break;
265 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
266 ret = conv_sw_src_yuv420sp(handle);
267 break;
Greg Hackmannae570c52013-01-03 11:22:37 -0800268 case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
Jiho Chang47bd9532012-03-24 05:56:11 +0900269 ret = conv_sw_src_argb888(handle);
270 break;
271 default:
272 ret = CSC_ErrorUnsupportFormat;
273 break;
274 }
275
276 return ret;
277}
278
279static CSC_ERRORCODE conv_hw(
280 CSC_HANDLE *handle)
281{
282 CSC_ERRORCODE ret = CSC_ErrorNone;
Jiho Chang47bd9532012-03-24 05:56:11 +0900283 switch (handle->csc_hw_type) {
Jiho Chang3b540842012-04-26 13:39:20 -0700284#ifdef ENABLE_FIMC
Jiho Chang47bd9532012-03-24 05:56:11 +0900285 case CSC_HW_TYPE_FIMC:
286 {
287 void *src_addr[3];
288 void *dst_addr[3];
Jiho Chang3b540842012-04-26 13:39:20 -0700289 OMX_COLOR_FORMATTYPE src_omx_format;
290 OMX_COLOR_FORMATTYPE dst_omx_format;
Jiho Chang47bd9532012-03-24 05:56:11 +0900291 src_addr[0] = handle->src_buffer.planes[CSC_Y_PLANE];
292 src_addr[1] = handle->src_buffer.planes[CSC_UV_PLANE];
293 dst_addr[0] = handle->dst_buffer.planes[CSC_Y_PLANE];
294 dst_addr[1] = handle->dst_buffer.planes[CSC_U_PLANE];
295 dst_addr[2] = handle->dst_buffer.planes[CSC_V_PLANE];
Jiho Chang3b540842012-04-26 13:39:20 -0700296 src_omx_format = hal_2_omx_pixel_format(handle->src_format.color_format);
297 dst_omx_format = hal_2_omx_pixel_format(handle->dst_format.color_format);
Jiho Chang47bd9532012-03-24 05:56:11 +0900298 csc_hwconverter_convert_nv12t(
299 handle->csc_hw_handle,
300 dst_addr,
301 src_addr,
302 handle->dst_format.width,
303 handle->dst_format.height,
Jiho Chang3b540842012-04-26 13:39:20 -0700304 dst_omx_format,
305 src_omx_format);
Jiho Chang47bd9532012-03-24 05:56:11 +0900306 break;
307 }
308#endif
Jiho Chang3b540842012-04-26 13:39:20 -0700309#ifdef ENABLE_GSCALER
Jiho Chang47bd9532012-03-24 05:56:11 +0900310 case CSC_HW_TYPE_GSCALER:
Jiho Chang3b540842012-04-26 13:39:20 -0700311 if (exynos_gsc_convert(handle->csc_hw_handle) != 0) {
312 ALOGE("%s:: exynos_gsc_convert() fail", __func__);
313 ret = CSC_Error;
314 }
Jiho Chang47bd9532012-03-24 05:56:11 +0900315 break;
316#endif
317 default:
Jiho Chang3b540842012-04-26 13:39:20 -0700318 ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type);
319 ret = CSC_ErrorNotImplemented;
Jiho Chang47bd9532012-03-24 05:56:11 +0900320 break;
321 }
322
Jiho Chang3b540842012-04-26 13:39:20 -0700323 return ret;
Jiho Chang47bd9532012-03-24 05:56:11 +0900324}
325
Jiho Chang3b540842012-04-26 13:39:20 -0700326static CSC_ERRORCODE csc_init_hw(
327 void *handle)
Jiho Chang47bd9532012-03-24 05:56:11 +0900328{
329 CSC_HANDLE *csc_handle;
Jiho Chang3b540842012-04-26 13:39:20 -0700330 CSC_ERRORCODE ret = CSC_ErrorNone;
Jiho Chang47bd9532012-03-24 05:56:11 +0900331
Jiho Chang3b540842012-04-26 13:39:20 -0700332 csc_handle = (CSC_HANDLE *)handle;
333 if (csc_handle->csc_method == CSC_METHOD_HW) {
334#ifdef ENABLE_FIMC
Jiho Chang47bd9532012-03-24 05:56:11 +0900335 csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC;
336#endif
Jiho Chang3b540842012-04-26 13:39:20 -0700337#ifdef ENABLE_GSCALER
Jiho Chang47bd9532012-03-24 05:56:11 +0900338 csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER;
339#endif
340 switch (csc_handle->csc_hw_type) {
Jiho Chang3b540842012-04-26 13:39:20 -0700341#ifdef ENABLE_FIMC
Jiho Chang47bd9532012-03-24 05:56:11 +0900342 case CSC_HW_TYPE_FIMC:
343 csc_handle->csc_hw_handle = csc_hwconverter_open();
Jiho Chang3b540842012-04-26 13:39:20 -0700344 ALOGV("%s:: CSC_HW_TYPE_FIMC", __func__);
Jiho Chang47bd9532012-03-24 05:56:11 +0900345 break;
346#endif
Jiho Chang3b540842012-04-26 13:39:20 -0700347#ifdef ENABLE_GSCALER
Jiho Chang47bd9532012-03-24 05:56:11 +0900348 case CSC_HW_TYPE_GSCALER:
Jiho Chang3b540842012-04-26 13:39:20 -0700349 if (csc_handle->hw_property.fixed_node >= 0)
Dima Zavin33aa35f2012-10-05 16:04:52 -0700350 csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0, 0);
Jiho Chang3b540842012-04-26 13:39:20 -0700351 else
Jiho Chang47bd9532012-03-24 05:56:11 +0900352 csc_handle->csc_hw_handle = exynos_gsc_create();
Jiho Chang3b540842012-04-26 13:39:20 -0700353 ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__);
Jiho Chang47bd9532012-03-24 05:56:11 +0900354 break;
355#endif
356 default:
Dima Zavinbaa53d42012-04-02 23:44:05 -0700357 ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__);
Jiho Chang47bd9532012-03-24 05:56:11 +0900358 csc_handle->csc_hw_handle == NULL;
359 break;
360 }
361 }
362
Jiho Chang47bd9532012-03-24 05:56:11 +0900363 if (csc_handle->csc_method == CSC_METHOD_HW) {
364 if (csc_handle->csc_hw_handle == NULL) {
Dima Zavinbaa53d42012-04-02 23:44:05 -0700365 ALOGE("%s:: CSC_METHOD_HW can't open HW", __func__);
Greg Hackmann4328d392012-12-10 15:28:45 -0800366 ret = CSC_Error;
Jiho Chang47bd9532012-03-24 05:56:11 +0900367 }
368 }
369
Jiho Chang3b540842012-04-26 13:39:20 -0700370 ALOGV("%s:: CSC_METHOD=%d", __func__, csc_handle->csc_method);
371
372 return ret;
373}
374
375static CSC_ERRORCODE csc_set_format(
376 void *handle)
377{
378 CSC_HANDLE *csc_handle;
379 CSC_ERRORCODE ret = CSC_ErrorNone;
380
381 if (handle == NULL)
382 return CSC_ErrorNotInit;
383
384 csc_handle = (CSC_HANDLE *)handle;
385 if (csc_handle->csc_method == CSC_METHOD_HW) {
386 switch (csc_handle->csc_hw_type) {
387 case CSC_HW_TYPE_FIMC:
388 break;
389#ifdef ENABLE_GSCALER
390 case CSC_HW_TYPE_GSCALER:
391 exynos_gsc_set_src_format(
392 csc_handle->csc_hw_handle,
393 ALIGN(csc_handle->src_format.width, GSCALER_IMG_ALIGN),
394 ALIGN(csc_handle->src_format.height, GSCALER_IMG_ALIGN),
395 csc_handle->src_format.crop_left,
396 csc_handle->src_format.crop_top,
Jiho Changd50f6502012-06-01 20:40:47 +0000397 csc_handle->src_format.crop_width,
398 csc_handle->src_format.crop_height,
Jiho Chang3b540842012-04-26 13:39:20 -0700399 HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format),
400 csc_handle->src_format.cacheable,
401 csc_handle->hw_property.mode_drm);
402
403 exynos_gsc_set_dst_format(
404 csc_handle->csc_hw_handle,
405 ALIGN(csc_handle->dst_format.width, GSCALER_IMG_ALIGN),
406 ALIGN(csc_handle->dst_format.height, GSCALER_IMG_ALIGN),
407 csc_handle->dst_format.crop_left,
408 csc_handle->dst_format.crop_top,
Jiho Changd50f6502012-06-01 20:40:47 +0000409 csc_handle->dst_format.crop_width,
410 csc_handle->dst_format.crop_height,
Jiho Chang3b540842012-04-26 13:39:20 -0700411 HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format),
412 csc_handle->dst_format.cacheable,
Greg Hackmannbcd3f112012-10-11 14:22:43 -0700413 csc_handle->hw_property.mode_drm,
414 0);
Jiho Chang3b540842012-04-26 13:39:20 -0700415 break;
416#endif
417 default:
418 ALOGE("%s:: unsupported csc_hw_type", __func__);
419 break;
420 }
421 }
422
423 return ret;
424}
425
426static CSC_ERRORCODE csc_set_buffer(
427 void *handle)
428{
429 CSC_HANDLE *csc_handle;
430 CSC_ERRORCODE ret = CSC_ErrorNone;
Jiho Chang3b540842012-04-26 13:39:20 -0700431
432 if (handle == NULL)
433 return CSC_ErrorNotInit;
434
435 csc_handle = (CSC_HANDLE *)handle;
436 if (csc_handle->csc_method == CSC_METHOD_HW) {
Jiho Chang3b540842012-04-26 13:39:20 -0700437 switch (csc_handle->csc_hw_type) {
438 case CSC_HW_TYPE_FIMC:
439 break;
440#ifdef ENABLE_GSCALER
441 case CSC_HW_TYPE_GSCALER:
Benoit Goby9f6d8282012-10-04 13:25:29 -0700442 exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, -1);
443 exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, -1);
Jiho Chang3b540842012-04-26 13:39:20 -0700444 break;
445#endif
446 default:
447 ALOGE("%s:: unsupported csc_hw_type", __func__);
448 break;
449 }
450 }
451
452 return ret;
453}
454
455void *csc_init(
456 CSC_METHOD method)
457{
458 CSC_HANDLE *csc_handle;
459 csc_handle = (CSC_HANDLE *)malloc(sizeof(CSC_HANDLE));
460 if (csc_handle == NULL)
461 return NULL;
462
463 memset(csc_handle, 0, sizeof(CSC_HANDLE));
464 csc_handle->hw_property.fixed_node = -1;
465 csc_handle->hw_property.mode_drm = 0;
466 csc_handle->csc_method = method;
Jiho Chang47bd9532012-03-24 05:56:11 +0900467
468 return (void *)csc_handle;
469}
470
471CSC_ERRORCODE csc_deinit(
472 void *handle)
473{
474 CSC_ERRORCODE ret = CSC_ErrorNone;
475 CSC_HANDLE *csc_handle;
476
477 csc_handle = (CSC_HANDLE *)handle;
Greg Hackmann4f74fda2013-01-08 12:30:39 -0800478 if (csc_handle->csc_hw_handle) {
Jiho Chang47bd9532012-03-24 05:56:11 +0900479 switch (csc_handle->csc_hw_type) {
Jiho Chang3b540842012-04-26 13:39:20 -0700480#ifdef ENABLE_FIMC
Jiho Chang47bd9532012-03-24 05:56:11 +0900481 case CSC_HW_TYPE_FIMC:
482 csc_hwconverter_close(csc_handle->csc_hw_handle);
483 break;
484#endif
Jiho Chang3b540842012-04-26 13:39:20 -0700485#ifdef ENABLE_GSCALER
Jiho Chang47bd9532012-03-24 05:56:11 +0900486 case CSC_HW_TYPE_GSCALER:
487 exynos_gsc_destroy(csc_handle->csc_hw_handle);
488 break;
489#endif
490 default:
Dima Zavinbaa53d42012-04-02 23:44:05 -0700491 ALOGE("%s:: unsupported csc_hw_type", __func__);
Jiho Chang47bd9532012-03-24 05:56:11 +0900492 break;
493 }
494 }
495
496 if (csc_handle != NULL) {
497 free(csc_handle);
498 ret = CSC_ErrorNone;
499 }
500
501 return ret;
502}
503
504CSC_ERRORCODE csc_get_method(
505 void *handle,
506 CSC_METHOD *method)
507{
508 CSC_HANDLE *csc_handle;
509 CSC_ERRORCODE ret = CSC_ErrorNone;
510
511 if (handle == NULL)
512 return CSC_ErrorNotInit;
513
514 csc_handle = (CSC_HANDLE *)handle;
515 *method = csc_handle->csc_method;
516
517 return ret;
518}
519
Greg Hackmann4f74fda2013-01-08 12:30:39 -0800520CSC_ERRORCODE csc_set_method(
521 void *handle,
522 CSC_METHOD method)
523{
524 CSC_HANDLE *csc_handle;
525 CSC_ERRORCODE ret = CSC_ErrorNone;
526
527 if (handle == NULL)
528 return CSC_ErrorNotInit;
529
530 csc_handle = (CSC_HANDLE *)handle;
531 csc_handle->csc_method = method;
532
533 return ret;
534}
535
Jiho Chang3b540842012-04-26 13:39:20 -0700536CSC_ERRORCODE csc_set_hw_property(
537 void *handle,
538 CSC_HW_PROPERTY_TYPE property,
539 int value)
540{
541 CSC_HANDLE *csc_handle;
542 CSC_ERRORCODE ret = CSC_ErrorNone;
543
544 if (handle == NULL)
545 return CSC_ErrorNotInit;
546
547 csc_handle = (CSC_HANDLE *)handle;
548 switch (property) {
549 case CSC_HW_PROPERTY_FIXED_NODE:
550 csc_handle->hw_property.fixed_node = value;
551 break;
552 case CSC_HW_PROPERTY_MODE_DRM:
553 csc_handle->hw_property.mode_drm = value;
554 break;
555 default:
556 ALOGE("%s:: not supported hw property", __func__);
557 ret = CSC_ErrorUnsupportFormat;
558 }
559
560 return ret;
561}
562
Jiho Chang47bd9532012-03-24 05:56:11 +0900563CSC_ERRORCODE csc_get_src_format(
564 void *handle,
565 unsigned int *width,
566 unsigned int *height,
567 unsigned int *crop_left,
568 unsigned int *crop_top,
569 unsigned int *crop_width,
570 unsigned int *crop_height,
571 unsigned int *color_format,
572 unsigned int *cacheable)
573{
574 CSC_HANDLE *csc_handle;
575 CSC_ERRORCODE ret = CSC_ErrorNone;
576
577 if (handle == NULL)
578 return CSC_ErrorNotInit;
579
580 csc_handle = (CSC_HANDLE *)handle;
581 *width = csc_handle->src_format.width;
582 *height = csc_handle->src_format.height;
583 *crop_left = csc_handle->src_format.crop_left;
584 *crop_top = csc_handle->src_format.crop_top;
585 *crop_width = csc_handle->src_format.crop_width;
586 *crop_height = csc_handle->src_format.crop_height;
587 *color_format = csc_handle->src_format.color_format;
588 *cacheable = csc_handle->src_format.cacheable;
589
590 return ret;
591}
592
593CSC_ERRORCODE csc_set_src_format(
594 void *handle,
595 unsigned int width,
596 unsigned int height,
597 unsigned int crop_left,
598 unsigned int crop_top,
599 unsigned int crop_width,
600 unsigned int crop_height,
601 unsigned int color_format,
602 unsigned int cacheable)
603{
604 CSC_HANDLE *csc_handle;
605 CSC_ERRORCODE ret = CSC_ErrorNone;
606
607 if (handle == NULL)
608 return CSC_ErrorNotInit;
609
610 csc_handle = (CSC_HANDLE *)handle;
611 csc_handle->src_format.width = width;
612 csc_handle->src_format.height = height;
613 csc_handle->src_format.crop_left = crop_left;
614 csc_handle->src_format.crop_top = crop_top;
615 csc_handle->src_format.crop_width = crop_width;
616 csc_handle->src_format.crop_height = crop_height;
617 csc_handle->src_format.color_format = color_format;
618 csc_handle->src_format.cacheable = cacheable;
619
Jiho Chang47bd9532012-03-24 05:56:11 +0900620 return ret;
621}
622
623CSC_ERRORCODE csc_get_dst_format(
624 void *handle,
625 unsigned int *width,
626 unsigned int *height,
627 unsigned int *crop_left,
628 unsigned int *crop_top,
629 unsigned int *crop_width,
630 unsigned int *crop_height,
631 unsigned int *color_format,
632 unsigned int *cacheable)
633{
634 CSC_HANDLE *csc_handle;
635 CSC_ERRORCODE ret = CSC_ErrorNone;
636
637 if (handle == NULL)
638 return CSC_ErrorNotInit;
639
640 csc_handle = (CSC_HANDLE *)handle;
641 *width = csc_handle->dst_format.width;
642 *height = csc_handle->dst_format.height;
643 *crop_left = csc_handle->dst_format.crop_left;
644 *crop_top = csc_handle->dst_format.crop_top;
645 *crop_width = csc_handle->dst_format.crop_width;
646 *crop_height = csc_handle->dst_format.crop_height;
647 *color_format = csc_handle->dst_format.color_format;
648 *cacheable = csc_handle->dst_format.cacheable;
649
650 return ret;
651}
652
653CSC_ERRORCODE csc_set_dst_format(
654 void *handle,
655 unsigned int width,
656 unsigned int height,
657 unsigned int crop_left,
658 unsigned int crop_top,
659 unsigned int crop_width,
660 unsigned int crop_height,
661 unsigned int color_format,
662 unsigned int cacheable)
663{
664 CSC_HANDLE *csc_handle;
665 CSC_ERRORCODE ret = CSC_ErrorNone;
666
667 if (handle == NULL)
668 return CSC_ErrorNotInit;
669
670 csc_handle = (CSC_HANDLE *)handle;
671 csc_handle->dst_format.width = width;
672 csc_handle->dst_format.height = height;
673 csc_handle->dst_format.crop_left = crop_left;
674 csc_handle->dst_format.crop_top = crop_top;
675 csc_handle->dst_format.crop_width = crop_width;
676 csc_handle->dst_format.crop_height = crop_height;
677 csc_handle->dst_format.color_format = color_format;
678 csc_handle->dst_format.cacheable = cacheable;
679
Jiho Chang47bd9532012-03-24 05:56:11 +0900680 return ret;
681}
682
683CSC_ERRORCODE csc_set_src_buffer(
SeungBeom Kimf77a2a92012-07-20 16:44:11 +0900684 void *handle,
685 void *addr[3])
Jiho Chang47bd9532012-03-24 05:56:11 +0900686{
687 CSC_HANDLE *csc_handle;
688 CSC_ERRORCODE ret = CSC_ErrorNone;
Jiho Chang47bd9532012-03-24 05:56:11 +0900689
690 if (handle == NULL)
691 return CSC_ErrorNotInit;
692
693 csc_handle = (CSC_HANDLE *)handle;
SeungBeom Kimf77a2a92012-07-20 16:44:11 +0900694 csc_handle->src_buffer.planes[CSC_Y_PLANE] = addr[0];
695 csc_handle->src_buffer.planes[CSC_U_PLANE] = addr[1];
696 csc_handle->src_buffer.planes[CSC_V_PLANE] = addr[2];
Jiho Chang47bd9532012-03-24 05:56:11 +0900697
Jiho Chang47bd9532012-03-24 05:56:11 +0900698 return ret;
699}
700
701CSC_ERRORCODE csc_set_dst_buffer(
SeungBeom Kimf77a2a92012-07-20 16:44:11 +0900702 void *handle,
703 void *addr[3])
Jiho Chang47bd9532012-03-24 05:56:11 +0900704{
705 CSC_HANDLE *csc_handle;
706 CSC_ERRORCODE ret = CSC_ErrorNone;
Jiho Chang47bd9532012-03-24 05:56:11 +0900707
708 if (handle == NULL)
709 return CSC_ErrorNotInit;
710
711 csc_handle = (CSC_HANDLE *)handle;
SeungBeom Kimf77a2a92012-07-20 16:44:11 +0900712 csc_handle->dst_buffer.planes[CSC_Y_PLANE] = addr[0];
713 csc_handle->dst_buffer.planes[CSC_U_PLANE] = addr[1];
714 csc_handle->dst_buffer.planes[CSC_V_PLANE] = addr[2];
Jiho Chang47bd9532012-03-24 05:56:11 +0900715
Jiho Chang47bd9532012-03-24 05:56:11 +0900716 return ret;
717}
718
719CSC_ERRORCODE csc_convert(
720 void *handle)
721{
722 CSC_HANDLE *csc_handle = (CSC_HANDLE *)handle;
723 CSC_ERRORCODE ret = CSC_ErrorNone;
724
725 if (csc_handle == NULL)
726 return CSC_ErrorNotInit;
727
Jiho Chang3b540842012-04-26 13:39:20 -0700728 if ((csc_handle->csc_method == CSC_METHOD_HW) &&
Greg Hackmann4328d392012-12-10 15:28:45 -0800729 (csc_handle->csc_hw_handle == NULL)) {
730 ret = csc_init_hw(handle);
731 if (ret != CSC_ErrorNone)
732 return ret;
733 }
Jiho Chang3b540842012-04-26 13:39:20 -0700734
Greg Hackmann4328d392012-12-10 15:28:45 -0800735 ret = csc_set_format(csc_handle);
736 if (ret != CSC_ErrorNone)
737 return ret;
738
739 ret = csc_set_buffer(csc_handle);
740 if (ret != CSC_ErrorNone)
741 return ret;
Jiho Chang3b540842012-04-26 13:39:20 -0700742
Jiho Chang47bd9532012-03-24 05:56:11 +0900743 if (csc_handle->csc_method == CSC_METHOD_HW)
744 ret = conv_hw(csc_handle);
745 else
746 ret = conv_sw(csc_handle);
747
748 return ret;
749}