Commit | Line | Data |
---|---|---|
47bd9530 JC |
1 | /* |
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> | |
3b540849 | 36 | #include <system/graphics.h> |
47bd9530 JC |
37 | |
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 | ||
3b540849 | 48 | #ifdef ENABLE_FIMC |
47bd9530 JC |
49 | #include "hwconverter_wrapper.h" |
50 | #endif | |
51 | ||
3b540849 | 52 | #ifdef ENABLE_GSCALER |
47bd9530 JC |
53 | #include "exynos_gscaler.h" |
54 | #endif | |
55 | ||
56 | #define GSCALER_IMG_ALIGN 16 | |
47bd9530 JC |
57 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) |
58 | ||
59 | typedef 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 | ||
67 | typedef enum _CSC_HW_TYPE { | |
68 | CSC_HW_TYPE_FIMC = 0, | |
69 | CSC_HW_TYPE_GSCALER | |
70 | } CSC_HW_TYPE; | |
71 | ||
72 | typedef 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; | |
3b540849 | 81 | unsigned int mode_drm; |
47bd9530 JC |
82 | } CSC_FORMAT; |
83 | ||
84 | typedef struct _CSC_BUFFER { | |
f77a2a9d | 85 | void *planes[CSC_MAX_PLANES]; |
47bd9530 JC |
86 | } CSC_BUFFER; |
87 | ||
3b540849 JC |
88 | typedef struct _CSC_HW_PROPERTY { |
89 | int fixed_node; | |
90 | int mode_drm; | |
91 | } CSC_HW_PROPERTY; | |
92 | ||
47bd9530 JC |
93 | typedef 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; | |
3b540849 | 101 | CSC_HW_PROPERTY hw_property; |
47bd9530 JC |
102 | } CSC_HANDLE; |
103 | ||
47bd9530 JC |
104 | /* source is RGB888 */ |
105 | static 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 */ | |
139 | static 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 */ | |
181 | static 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 */ | |
219 | static 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 | ||
253 | static 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; | |
ae570c5d | 268 | case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: |
47bd9530 JC |
269 | ret = conv_sw_src_argb888(handle); |
270 | break; | |
271 | default: | |
272 | ret = CSC_ErrorUnsupportFormat; | |
273 | break; | |
274 | } | |
275 | ||
276 | return ret; | |
277 | } | |
278 | ||
279 | static CSC_ERRORCODE conv_hw( | |
280 | CSC_HANDLE *handle) | |
281 | { | |
282 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
47bd9530 | 283 | switch (handle->csc_hw_type) { |
3b540849 | 284 | #ifdef ENABLE_FIMC |
47bd9530 JC |
285 | case CSC_HW_TYPE_FIMC: |
286 | { | |
287 | void *src_addr[3]; | |
288 | void *dst_addr[3]; | |
3b540849 JC |
289 | OMX_COLOR_FORMATTYPE src_omx_format; |
290 | OMX_COLOR_FORMATTYPE dst_omx_format; | |
47bd9530 JC |
291 | 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]; | |
3b540849 JC |
296 | 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); | |
47bd9530 JC |
298 | 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, | |
3b540849 JC |
304 | dst_omx_format, |
305 | src_omx_format); | |
47bd9530 JC |
306 | break; |
307 | } | |
308 | #endif | |
3b540849 | 309 | #ifdef ENABLE_GSCALER |
47bd9530 | 310 | case CSC_HW_TYPE_GSCALER: |
3b540849 JC |
311 | if (exynos_gsc_convert(handle->csc_hw_handle) != 0) { |
312 | ALOGE("%s:: exynos_gsc_convert() fail", __func__); | |
313 | ret = CSC_Error; | |
314 | } | |
47bd9530 JC |
315 | break; |
316 | #endif | |
317 | default: | |
3b540849 JC |
318 | ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type); |
319 | ret = CSC_ErrorNotImplemented; | |
47bd9530 JC |
320 | break; |
321 | } | |
322 | ||
3b540849 | 323 | return ret; |
47bd9530 JC |
324 | } |
325 | ||
3b540849 JC |
326 | static CSC_ERRORCODE csc_init_hw( |
327 | void *handle) | |
47bd9530 JC |
328 | { |
329 | CSC_HANDLE *csc_handle; | |
3b540849 | 330 | CSC_ERRORCODE ret = CSC_ErrorNone; |
47bd9530 | 331 | |
3b540849 JC |
332 | csc_handle = (CSC_HANDLE *)handle; |
333 | if (csc_handle->csc_method == CSC_METHOD_HW) { | |
334 | #ifdef ENABLE_FIMC | |
47bd9530 JC |
335 | csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC; |
336 | #endif | |
3b540849 | 337 | #ifdef ENABLE_GSCALER |
47bd9530 JC |
338 | csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER; |
339 | #endif | |
340 | switch (csc_handle->csc_hw_type) { | |
3b540849 | 341 | #ifdef ENABLE_FIMC |
47bd9530 JC |
342 | case CSC_HW_TYPE_FIMC: |
343 | csc_handle->csc_hw_handle = csc_hwconverter_open(); | |
3b540849 | 344 | ALOGV("%s:: CSC_HW_TYPE_FIMC", __func__); |
47bd9530 JC |
345 | break; |
346 | #endif | |
3b540849 | 347 | #ifdef ENABLE_GSCALER |
47bd9530 | 348 | case CSC_HW_TYPE_GSCALER: |
3b540849 | 349 | if (csc_handle->hw_property.fixed_node >= 0) |
33aa35f1 | 350 | csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0, 0); |
3b540849 | 351 | else |
47bd9530 | 352 | csc_handle->csc_hw_handle = exynos_gsc_create(); |
3b540849 | 353 | ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__); |
47bd9530 JC |
354 | break; |
355 | #endif | |
356 | default: | |
baa53d4c | 357 | ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__); |
47bd9530 JC |
358 | csc_handle->csc_hw_handle == NULL; |
359 | break; | |
360 | } | |
361 | } | |
362 | ||
47bd9530 JC |
363 | if (csc_handle->csc_method == CSC_METHOD_HW) { |
364 | if (csc_handle->csc_hw_handle == NULL) { | |
baa53d4c | 365 | ALOGE("%s:: CSC_METHOD_HW can't open HW", __func__); |
47bd9530 JC |
366 | free(csc_handle); |
367 | csc_handle = NULL; | |
368 | } | |
369 | } | |
370 | ||
3b540849 JC |
371 | ALOGV("%s:: CSC_METHOD=%d", __func__, csc_handle->csc_method); |
372 | ||
373 | return ret; | |
374 | } | |
375 | ||
376 | static CSC_ERRORCODE csc_set_format( | |
377 | void *handle) | |
378 | { | |
379 | CSC_HANDLE *csc_handle; | |
380 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
381 | ||
382 | if (handle == NULL) | |
383 | return CSC_ErrorNotInit; | |
384 | ||
385 | csc_handle = (CSC_HANDLE *)handle; | |
386 | if (csc_handle->csc_method == CSC_METHOD_HW) { | |
387 | switch (csc_handle->csc_hw_type) { | |
388 | case CSC_HW_TYPE_FIMC: | |
389 | break; | |
390 | #ifdef ENABLE_GSCALER | |
391 | case CSC_HW_TYPE_GSCALER: | |
392 | exynos_gsc_set_src_format( | |
393 | csc_handle->csc_hw_handle, | |
394 | ALIGN(csc_handle->src_format.width, GSCALER_IMG_ALIGN), | |
395 | ALIGN(csc_handle->src_format.height, GSCALER_IMG_ALIGN), | |
396 | csc_handle->src_format.crop_left, | |
397 | csc_handle->src_format.crop_top, | |
d50f650b JC |
398 | csc_handle->src_format.crop_width, |
399 | csc_handle->src_format.crop_height, | |
3b540849 JC |
400 | HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format), |
401 | csc_handle->src_format.cacheable, | |
402 | csc_handle->hw_property.mode_drm); | |
403 | ||
404 | exynos_gsc_set_dst_format( | |
405 | csc_handle->csc_hw_handle, | |
406 | ALIGN(csc_handle->dst_format.width, GSCALER_IMG_ALIGN), | |
407 | ALIGN(csc_handle->dst_format.height, GSCALER_IMG_ALIGN), | |
408 | csc_handle->dst_format.crop_left, | |
409 | csc_handle->dst_format.crop_top, | |
d50f650b JC |
410 | csc_handle->dst_format.crop_width, |
411 | csc_handle->dst_format.crop_height, | |
3b540849 JC |
412 | HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format), |
413 | csc_handle->dst_format.cacheable, | |
bcd3f11d GH |
414 | csc_handle->hw_property.mode_drm, |
415 | 0); | |
3b540849 JC |
416 | break; |
417 | #endif | |
418 | default: | |
419 | ALOGE("%s:: unsupported csc_hw_type", __func__); | |
420 | break; | |
421 | } | |
422 | } | |
423 | ||
424 | return ret; | |
425 | } | |
426 | ||
427 | static CSC_ERRORCODE csc_set_buffer( | |
428 | void *handle) | |
429 | { | |
430 | CSC_HANDLE *csc_handle; | |
431 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
3b540849 JC |
432 | |
433 | if (handle == NULL) | |
434 | return CSC_ErrorNotInit; | |
435 | ||
436 | csc_handle = (CSC_HANDLE *)handle; | |
437 | if (csc_handle->csc_method == CSC_METHOD_HW) { | |
3b540849 JC |
438 | switch (csc_handle->csc_hw_type) { |
439 | case CSC_HW_TYPE_FIMC: | |
440 | break; | |
441 | #ifdef ENABLE_GSCALER | |
442 | case CSC_HW_TYPE_GSCALER: | |
9f6d8287 BG |
443 | exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, -1); |
444 | exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, -1); | |
3b540849 JC |
445 | break; |
446 | #endif | |
447 | default: | |
448 | ALOGE("%s:: unsupported csc_hw_type", __func__); | |
449 | break; | |
450 | } | |
451 | } | |
452 | ||
453 | return ret; | |
454 | } | |
455 | ||
456 | void *csc_init( | |
457 | CSC_METHOD method) | |
458 | { | |
459 | CSC_HANDLE *csc_handle; | |
460 | csc_handle = (CSC_HANDLE *)malloc(sizeof(CSC_HANDLE)); | |
461 | if (csc_handle == NULL) | |
462 | return NULL; | |
463 | ||
464 | memset(csc_handle, 0, sizeof(CSC_HANDLE)); | |
465 | csc_handle->hw_property.fixed_node = -1; | |
466 | csc_handle->hw_property.mode_drm = 0; | |
467 | csc_handle->csc_method = method; | |
47bd9530 JC |
468 | |
469 | return (void *)csc_handle; | |
470 | } | |
471 | ||
472 | CSC_ERRORCODE csc_deinit( | |
473 | void *handle) | |
474 | { | |
475 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
476 | CSC_HANDLE *csc_handle; | |
477 | ||
478 | csc_handle = (CSC_HANDLE *)handle; | |
479 | if (csc_handle->csc_method == CSC_METHOD_HW) { | |
480 | switch (csc_handle->csc_hw_type) { | |
3b540849 | 481 | #ifdef ENABLE_FIMC |
47bd9530 JC |
482 | case CSC_HW_TYPE_FIMC: |
483 | csc_hwconverter_close(csc_handle->csc_hw_handle); | |
484 | break; | |
485 | #endif | |
3b540849 | 486 | #ifdef ENABLE_GSCALER |
47bd9530 JC |
487 | case CSC_HW_TYPE_GSCALER: |
488 | exynos_gsc_destroy(csc_handle->csc_hw_handle); | |
489 | break; | |
490 | #endif | |
491 | default: | |
baa53d4c | 492 | ALOGE("%s:: unsupported csc_hw_type", __func__); |
47bd9530 JC |
493 | break; |
494 | } | |
495 | } | |
496 | ||
497 | if (csc_handle != NULL) { | |
498 | free(csc_handle); | |
499 | ret = CSC_ErrorNone; | |
500 | } | |
501 | ||
502 | return ret; | |
503 | } | |
504 | ||
505 | CSC_ERRORCODE csc_get_method( | |
506 | void *handle, | |
507 | CSC_METHOD *method) | |
508 | { | |
509 | CSC_HANDLE *csc_handle; | |
510 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
511 | ||
512 | if (handle == NULL) | |
513 | return CSC_ErrorNotInit; | |
514 | ||
515 | csc_handle = (CSC_HANDLE *)handle; | |
516 | *method = csc_handle->csc_method; | |
517 | ||
518 | return ret; | |
519 | } | |
520 | ||
3b540849 JC |
521 | CSC_ERRORCODE csc_set_hw_property( |
522 | void *handle, | |
523 | CSC_HW_PROPERTY_TYPE property, | |
524 | int value) | |
525 | { | |
526 | CSC_HANDLE *csc_handle; | |
527 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
528 | ||
529 | if (handle == NULL) | |
530 | return CSC_ErrorNotInit; | |
531 | ||
532 | csc_handle = (CSC_HANDLE *)handle; | |
533 | switch (property) { | |
534 | case CSC_HW_PROPERTY_FIXED_NODE: | |
535 | csc_handle->hw_property.fixed_node = value; | |
536 | break; | |
537 | case CSC_HW_PROPERTY_MODE_DRM: | |
538 | csc_handle->hw_property.mode_drm = value; | |
539 | break; | |
540 | default: | |
541 | ALOGE("%s:: not supported hw property", __func__); | |
542 | ret = CSC_ErrorUnsupportFormat; | |
543 | } | |
544 | ||
545 | return ret; | |
546 | } | |
547 | ||
47bd9530 JC |
548 | CSC_ERRORCODE csc_get_src_format( |
549 | void *handle, | |
550 | unsigned int *width, | |
551 | unsigned int *height, | |
552 | unsigned int *crop_left, | |
553 | unsigned int *crop_top, | |
554 | unsigned int *crop_width, | |
555 | unsigned int *crop_height, | |
556 | unsigned int *color_format, | |
557 | unsigned int *cacheable) | |
558 | { | |
559 | CSC_HANDLE *csc_handle; | |
560 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
561 | ||
562 | if (handle == NULL) | |
563 | return CSC_ErrorNotInit; | |
564 | ||
565 | csc_handle = (CSC_HANDLE *)handle; | |
566 | *width = csc_handle->src_format.width; | |
567 | *height = csc_handle->src_format.height; | |
568 | *crop_left = csc_handle->src_format.crop_left; | |
569 | *crop_top = csc_handle->src_format.crop_top; | |
570 | *crop_width = csc_handle->src_format.crop_width; | |
571 | *crop_height = csc_handle->src_format.crop_height; | |
572 | *color_format = csc_handle->src_format.color_format; | |
573 | *cacheable = csc_handle->src_format.cacheable; | |
574 | ||
575 | return ret; | |
576 | } | |
577 | ||
578 | CSC_ERRORCODE csc_set_src_format( | |
579 | void *handle, | |
580 | unsigned int width, | |
581 | unsigned int height, | |
582 | unsigned int crop_left, | |
583 | unsigned int crop_top, | |
584 | unsigned int crop_width, | |
585 | unsigned int crop_height, | |
586 | unsigned int color_format, | |
587 | unsigned int cacheable) | |
588 | { | |
589 | CSC_HANDLE *csc_handle; | |
590 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
591 | ||
592 | if (handle == NULL) | |
593 | return CSC_ErrorNotInit; | |
594 | ||
595 | csc_handle = (CSC_HANDLE *)handle; | |
596 | csc_handle->src_format.width = width; | |
597 | csc_handle->src_format.height = height; | |
598 | csc_handle->src_format.crop_left = crop_left; | |
599 | csc_handle->src_format.crop_top = crop_top; | |
600 | csc_handle->src_format.crop_width = crop_width; | |
601 | csc_handle->src_format.crop_height = crop_height; | |
602 | csc_handle->src_format.color_format = color_format; | |
603 | csc_handle->src_format.cacheable = cacheable; | |
604 | ||
47bd9530 JC |
605 | return ret; |
606 | } | |
607 | ||
608 | CSC_ERRORCODE csc_get_dst_format( | |
609 | void *handle, | |
610 | unsigned int *width, | |
611 | unsigned int *height, | |
612 | unsigned int *crop_left, | |
613 | unsigned int *crop_top, | |
614 | unsigned int *crop_width, | |
615 | unsigned int *crop_height, | |
616 | unsigned int *color_format, | |
617 | unsigned int *cacheable) | |
618 | { | |
619 | CSC_HANDLE *csc_handle; | |
620 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
621 | ||
622 | if (handle == NULL) | |
623 | return CSC_ErrorNotInit; | |
624 | ||
625 | csc_handle = (CSC_HANDLE *)handle; | |
626 | *width = csc_handle->dst_format.width; | |
627 | *height = csc_handle->dst_format.height; | |
628 | *crop_left = csc_handle->dst_format.crop_left; | |
629 | *crop_top = csc_handle->dst_format.crop_top; | |
630 | *crop_width = csc_handle->dst_format.crop_width; | |
631 | *crop_height = csc_handle->dst_format.crop_height; | |
632 | *color_format = csc_handle->dst_format.color_format; | |
633 | *cacheable = csc_handle->dst_format.cacheable; | |
634 | ||
635 | return ret; | |
636 | } | |
637 | ||
638 | CSC_ERRORCODE csc_set_dst_format( | |
639 | void *handle, | |
640 | unsigned int width, | |
641 | unsigned int height, | |
642 | unsigned int crop_left, | |
643 | unsigned int crop_top, | |
644 | unsigned int crop_width, | |
645 | unsigned int crop_height, | |
646 | unsigned int color_format, | |
647 | unsigned int cacheable) | |
648 | { | |
649 | CSC_HANDLE *csc_handle; | |
650 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
651 | ||
652 | if (handle == NULL) | |
653 | return CSC_ErrorNotInit; | |
654 | ||
655 | csc_handle = (CSC_HANDLE *)handle; | |
656 | csc_handle->dst_format.width = width; | |
657 | csc_handle->dst_format.height = height; | |
658 | csc_handle->dst_format.crop_left = crop_left; | |
659 | csc_handle->dst_format.crop_top = crop_top; | |
660 | csc_handle->dst_format.crop_width = crop_width; | |
661 | csc_handle->dst_format.crop_height = crop_height; | |
662 | csc_handle->dst_format.color_format = color_format; | |
663 | csc_handle->dst_format.cacheable = cacheable; | |
664 | ||
47bd9530 JC |
665 | return ret; |
666 | } | |
667 | ||
668 | CSC_ERRORCODE csc_set_src_buffer( | |
f77a2a9d SK |
669 | void *handle, |
670 | void *addr[3]) | |
47bd9530 JC |
671 | { |
672 | CSC_HANDLE *csc_handle; | |
673 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
47bd9530 JC |
674 | |
675 | if (handle == NULL) | |
676 | return CSC_ErrorNotInit; | |
677 | ||
678 | csc_handle = (CSC_HANDLE *)handle; | |
f77a2a9d SK |
679 | csc_handle->src_buffer.planes[CSC_Y_PLANE] = addr[0]; |
680 | csc_handle->src_buffer.planes[CSC_U_PLANE] = addr[1]; | |
681 | csc_handle->src_buffer.planes[CSC_V_PLANE] = addr[2]; | |
47bd9530 | 682 | |
47bd9530 JC |
683 | return ret; |
684 | } | |
685 | ||
686 | CSC_ERRORCODE csc_set_dst_buffer( | |
f77a2a9d SK |
687 | void *handle, |
688 | void *addr[3]) | |
47bd9530 JC |
689 | { |
690 | CSC_HANDLE *csc_handle; | |
691 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
47bd9530 JC |
692 | |
693 | if (handle == NULL) | |
694 | return CSC_ErrorNotInit; | |
695 | ||
696 | csc_handle = (CSC_HANDLE *)handle; | |
f77a2a9d SK |
697 | csc_handle->dst_buffer.planes[CSC_Y_PLANE] = addr[0]; |
698 | csc_handle->dst_buffer.planes[CSC_U_PLANE] = addr[1]; | |
699 | csc_handle->dst_buffer.planes[CSC_V_PLANE] = addr[2]; | |
47bd9530 | 700 | |
47bd9530 JC |
701 | return ret; |
702 | } | |
703 | ||
704 | CSC_ERRORCODE csc_convert( | |
705 | void *handle) | |
706 | { | |
707 | CSC_HANDLE *csc_handle = (CSC_HANDLE *)handle; | |
708 | CSC_ERRORCODE ret = CSC_ErrorNone; | |
709 | ||
710 | if (csc_handle == NULL) | |
711 | return CSC_ErrorNotInit; | |
712 | ||
3b540849 JC |
713 | if ((csc_handle->csc_method == CSC_METHOD_HW) && |
714 | (csc_handle->csc_hw_handle == NULL)) | |
715 | csc_init_hw(handle); | |
716 | ||
717 | csc_set_format(csc_handle); | |
718 | csc_set_buffer(csc_handle); | |
719 | ||
47bd9530 JC |
720 | if (csc_handle->csc_method == CSC_METHOD_HW) |
721 | ret = conv_hw(csc_handle); | |
722 | else | |
723 | ret = conv_sw(csc_handle); | |
724 | ||
725 | return ret; | |
726 | } |