merge in jb-mr1-release history after reset to jb-mr1-dev
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos5.git] / libcsc / csc.c
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>
36 #include <system/graphics.h>
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
48 #ifdef ENABLE_FIMC
49 #include "hwconverter_wrapper.h"
50 #endif
51
52 #ifdef ENABLE_GSCALER
53 #include "exynos_gscaler.h"
54 #endif
55
56 #define GSCALER_IMG_ALIGN 16
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;
81 unsigned int mode_drm;
82 } CSC_FORMAT;
83
84 typedef struct _CSC_BUFFER {
85 void *planes[CSC_MAX_PLANES];
86 } CSC_BUFFER;
87
88 typedef struct _CSC_HW_PROPERTY {
89 int fixed_node;
90 int mode_drm;
91 } CSC_HW_PROPERTY;
92
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;
101 CSC_HW_PROPERTY hw_property;
102 } CSC_HANDLE;
103
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;
268 case HAL_PIXEL_FORMAT_ARGB888:
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;
283 switch (handle->csc_hw_type) {
284 #ifdef ENABLE_FIMC
285 case CSC_HW_TYPE_FIMC:
286 {
287 void *src_addr[3];
288 void *dst_addr[3];
289 OMX_COLOR_FORMATTYPE src_omx_format;
290 OMX_COLOR_FORMATTYPE dst_omx_format;
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];
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);
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,
304 dst_omx_format,
305 src_omx_format);
306 break;
307 }
308 #endif
309 #ifdef ENABLE_GSCALER
310 case CSC_HW_TYPE_GSCALER:
311 if (exynos_gsc_convert(handle->csc_hw_handle) != 0) {
312 ALOGE("%s:: exynos_gsc_convert() fail", __func__);
313 ret = CSC_Error;
314 }
315 break;
316 #endif
317 default:
318 ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type);
319 ret = CSC_ErrorNotImplemented;
320 break;
321 }
322
323 return ret;
324 }
325
326 static CSC_ERRORCODE csc_init_hw(
327 void *handle)
328 {
329 CSC_HANDLE *csc_handle;
330 CSC_ERRORCODE ret = CSC_ErrorNone;
331
332 csc_handle = (CSC_HANDLE *)handle;
333 if (csc_handle->csc_method == CSC_METHOD_HW) {
334 #ifdef ENABLE_FIMC
335 csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC;
336 #endif
337 #ifdef ENABLE_GSCALER
338 csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER;
339 #endif
340 switch (csc_handle->csc_hw_type) {
341 #ifdef ENABLE_FIMC
342 case CSC_HW_TYPE_FIMC:
343 csc_handle->csc_hw_handle = csc_hwconverter_open();
344 ALOGV("%s:: CSC_HW_TYPE_FIMC", __func__);
345 break;
346 #endif
347 #ifdef ENABLE_GSCALER
348 case CSC_HW_TYPE_GSCALER:
349 if (csc_handle->hw_property.fixed_node >= 0)
350 csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0, 0);
351 else
352 csc_handle->csc_hw_handle = exynos_gsc_create();
353 ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__);
354 break;
355 #endif
356 default:
357 ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__);
358 csc_handle->csc_hw_handle == NULL;
359 break;
360 }
361 }
362
363 if (csc_handle->csc_method == CSC_METHOD_HW) {
364 if (csc_handle->csc_hw_handle == NULL) {
365 ALOGE("%s:: CSC_METHOD_HW can't open HW", __func__);
366 free(csc_handle);
367 csc_handle = NULL;
368 }
369 }
370
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,
398 csc_handle->src_format.crop_width,
399 csc_handle->src_format.crop_height,
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,
410 csc_handle->dst_format.crop_width,
411 csc_handle->dst_format.crop_height,
412 HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format),
413 csc_handle->dst_format.cacheable,
414 csc_handle->hw_property.mode_drm,
415 0);
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;
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) {
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:
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);
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;
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) {
481 #ifdef ENABLE_FIMC
482 case CSC_HW_TYPE_FIMC:
483 csc_hwconverter_close(csc_handle->csc_hw_handle);
484 break;
485 #endif
486 #ifdef ENABLE_GSCALER
487 case CSC_HW_TYPE_GSCALER:
488 exynos_gsc_destroy(csc_handle->csc_hw_handle);
489 break;
490 #endif
491 default:
492 ALOGE("%s:: unsupported csc_hw_type", __func__);
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
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
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
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
665 return ret;
666 }
667
668 CSC_ERRORCODE csc_set_src_buffer(
669 void *handle,
670 void *addr[3])
671 {
672 CSC_HANDLE *csc_handle;
673 CSC_ERRORCODE ret = CSC_ErrorNone;
674
675 if (handle == NULL)
676 return CSC_ErrorNotInit;
677
678 csc_handle = (CSC_HANDLE *)handle;
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];
682
683 return ret;
684 }
685
686 CSC_ERRORCODE csc_set_dst_buffer(
687 void *handle,
688 void *addr[3])
689 {
690 CSC_HANDLE *csc_handle;
691 CSC_ERRORCODE ret = CSC_ErrorNone;
692
693 if (handle == NULL)
694 return CSC_ErrorNotInit;
695
696 csc_handle = (CSC_HANDLE *)handle;
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];
700
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
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
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 }