7fe7afe47ab926c5ce0aa9c9cd404b32da72c1e4
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / exynos / 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 #ifndef SLP_PLATFORM /* build env */
32 #include <cutils/log.h>
33 #endif
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #ifndef SLP_PLATFORM /* build env */
38 #include <utils/Log.h>
39 #include <system/graphics.h>
40 #else
41 #include "Exynos_OSAL_Log.h"
42 #endif
43
44
45 #include "csc.h"
46 #include "exynos_format.h"
47 #include "swconverter.h"
48
49 #ifdef SLP_PLATFORM /* build env */
50 #define EXYNOS_OMX
51 #endif
52
53 #ifdef EXYNOS_OMX
54 #include "Exynos_OMX_Def.h"
55 #else
56 #include "SEC_OMX_Def.h"
57 #endif
58
59 #ifdef ENABLE_FIMC
60 #include "hwconverter_wrapper.h"
61 #endif
62
63 #ifdef ENABLE_GSCALER
64 #include "exynos_gscaler.h"
65 #endif
66
67 #define GSCALER_IMG_ALIGN 16
68 #define CSC_MAX_PLANES 3
69 #define ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
70
71 typedef enum _CSC_PLANE {
72     CSC_Y_PLANE = 0,
73     CSC_RGB_PLANE = 0,
74     CSC_U_PLANE = 1,
75     CSC_UV_PLANE = 1,
76     CSC_V_PLANE = 2
77 } CSC_PLANE;
78
79 typedef enum _CSC_HW_TYPE {
80     CSC_HW_TYPE_FIMC = 0,
81     CSC_HW_TYPE_GSCALER
82 } CSC_HW_TYPE;
83
84 typedef struct _CSC_FORMAT {
85     unsigned int width;
86     unsigned int height;
87     unsigned int crop_left;
88     unsigned int crop_top;
89     unsigned int crop_width;
90     unsigned int crop_height;
91     unsigned int color_format;
92     unsigned int cacheable;
93     unsigned int mode_drm;
94 } CSC_FORMAT;
95
96 typedef struct _CSC_BUFFER {
97     unsigned char *planes[CSC_MAX_PLANES];
98     int ion_fd;
99 } CSC_BUFFER;
100
101 typedef struct _CSC_HW_PROPERTY {
102     int fixed_node;
103     int mode_drm;
104 } CSC_HW_PROPERTY;
105
106 typedef struct _CSC_HANDLE {
107     CSC_FORMAT      dst_format;
108     CSC_FORMAT      src_format;
109     CSC_BUFFER      dst_buffer;
110     CSC_BUFFER      src_buffer;
111     CSC_METHOD      csc_method;
112     CSC_HW_TYPE     csc_hw_type;
113     void           *csc_hw_handle;
114     CSC_HW_PROPERTY hw_property;
115 } CSC_HANDLE;
116
117 /* source is RGB888 */
118 static CSC_ERRORCODE conv_sw_src_argb888(
119     CSC_HANDLE *handle)
120 {
121     CSC_ERRORCODE ret = CSC_ErrorNone;
122
123     switch (handle->dst_format.color_format) {
124     case HAL_PIXEL_FORMAT_YCbCr_420_P:
125         csc_ARGB8888_to_YUV420P(
126             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
127             (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
128             (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
129             (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
130             handle->src_format.width,
131             handle->src_format.height);
132         ret = CSC_ErrorNone;
133         break;
134     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
135 #ifdef USE_NEON
136         csc_ARGB8888_to_YUV420SP_NEON(
137 #else
138         csc_ARGB8888_to_YUV420SP(
139 #endif
140             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
141             (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
142             (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
143             handle->src_format.width,
144             handle->src_format.height);
145         ret = CSC_ErrorNone;
146         break;
147     default:
148         ret = CSC_ErrorUnsupportFormat;
149         break;
150     }
151
152     return ret;
153 }
154
155 /* source is NV12T */
156 static CSC_ERRORCODE conv_sw_src_nv12t(
157     CSC_HANDLE *handle)
158 {
159     CSC_ERRORCODE ret = CSC_ErrorNone;
160
161     switch (handle->dst_format.color_format) {
162     case HAL_PIXEL_FORMAT_YCbCr_420_P:
163         ALOGE("dst_format HAL_PIXEL_FORMAT_YCbCr_420_P");
164 #ifdef USE_NEON
165         csc_tiled_to_linear_y_neon(
166 #else
167         csc_tiled_to_linear_y(
168 #endif
169             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
170             (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
171             handle->src_format.width,
172             handle->src_format.height);
173 #ifdef USE_NEON
174         csc_tiled_to_linear_uv_deinterleave_neon(
175 #else
176         csc_tiled_to_linear_uv_deinterleave(
177 #endif
178             (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
179             (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
180             (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
181             handle->src_format.width,
182             handle->src_format.height / 2);
183         ret = CSC_ErrorNone;
184         break;
185     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
186         ALOGE("dst_format HAL_PIXEL_FORMAT_YCbCr_420_SP");
187 #ifdef USE_NEON
188         csc_tiled_to_linear_y_neon(
189 #else
190         csc_tiled_to_linear_y(
191 #endif
192             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
193             (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
194             handle->src_format.width,
195             handle->src_format.height);
196 #ifdef USE_NEON
197         csc_tiled_to_linear_uv_neon(
198 #else
199         csc_tiled_to_linear_uv(
200 #endif
201             (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
202             (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
203             handle->src_format.width,
204             handle->src_format.height / 2);
205         ret = CSC_ErrorNone;
206 #ifdef OUTPUT_FILE_DUMP
207         {
208             FILE *pf;
209             char filename[100];
210             static int tmp_cnt=0;
211             int w = handle->dst_buffer.width;
212             int h = handle->dst_buffer.height;
213
214             memset(filename, 0x00, sizeof(filename));
215             sprintf(filename, "/tmp/dec_dump_%d_%d_%d.yuv", w, h, ++tmp_cnt);
216
217             pf = fopen(filename, "wb");
218             if (pf == NULL) {
219                 ALOGE("[file dump] filepoint NULL!");
220             } else {
221                 ALOGE("[file dump] fwrite[%d]", tmp_cnt);
222                 fwrite(handle->dst_buffer.planes[CSC_Y_PLANE], sizeof(char), w * h, pf);
223                 fwrite(handle->dst_buffer.planes[CSC_UV_PLANE], sizeof(char), w * h / 2, pf);
224             }
225             fclose(pf);
226         }
227 #endif
228         break;
229     default:
230         ALOGE("dst_format CSC_ErrorUnsupportFormat");
231         ret = CSC_ErrorUnsupportFormat;
232         break;
233     }
234
235     return ret;
236 }
237
238 /* source is YUV420P */
239 static CSC_ERRORCODE conv_sw_src_yuv420p(
240     CSC_HANDLE *handle)
241 {
242     CSC_ERRORCODE ret = CSC_ErrorNone;
243
244     switch (handle->dst_format.color_format) {
245     case HAL_PIXEL_FORMAT_YCbCr_420_P:  /* bypass */
246         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
247                (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
248                handle->src_format.width * handle->src_format.height);
249         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
250                (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE],
251                (handle->src_format.width * handle->src_format.height) >> 2);
252         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
253                (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE],
254                (handle->src_format.width * handle->src_format.height) >> 2);
255         ret = CSC_ErrorNone;
256         break;
257     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
258         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
259                (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
260                handle->src_format.width * handle->src_format.height);
261 #ifdef USE_NEON
262         csc_interleave_memcpy_neon(
263 #else
264         csc_interleave_memcpy(
265 #endif
266             (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
267             (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE],
268             (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE],
269             (handle->src_format.width * handle->src_format.height) >> 2);
270         ret = CSC_ErrorNone;
271         break;
272     default:
273         ret = CSC_ErrorUnsupportFormat;
274         break;
275     }
276
277     return ret;
278 }
279
280 /* source is YUV420SP */
281 static CSC_ERRORCODE conv_sw_src_yuv420sp(
282     CSC_HANDLE *handle)
283 {
284     CSC_ERRORCODE ret = CSC_ErrorNone;
285
286     switch (handle->dst_format.color_format) {
287     case HAL_PIXEL_FORMAT_YCbCr_420_P:
288         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
289                (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
290                handle->src_format.width * handle->src_format.height);
291         csc_deinterleave_memcpy(
292             (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
293             (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
294             (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
295             handle->src_format.width * handle->src_format.height >> 1);
296         ret = CSC_ErrorNone;
297         break;
298     case HAL_PIXEL_FORMAT_YCbCr_420_SP: /* bypass */
299         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
300                (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
301                handle->src_format.width * handle->src_format.height);
302         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
303                (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
304                handle->src_format.width * handle->src_format.height >> 1);
305         ret = CSC_ErrorNone;
306         break;
307     default:
308         ret = CSC_ErrorUnsupportFormat;
309         break;
310     }
311
312     return ret;
313 }
314
315 static CSC_ERRORCODE conv_sw(
316     CSC_HANDLE *handle)
317 {
318     CSC_ERRORCODE ret = CSC_ErrorNone;
319
320     ALOGE("%s:: handle->src_format.color_format = %d", __func__, handle->src_format.color_format);
321     switch (handle->src_format.color_format) {
322     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
323     ALOGE("src_format HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED");
324         ret = conv_sw_src_nv12t(handle);
325         break;
326     case HAL_PIXEL_FORMAT_YCbCr_420_P:
327     ALOGE("src_format HAL_PIXEL_FORMAT_YCbCr_420_P");
328         ret = conv_sw_src_yuv420p(handle);
329         break;
330     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
331     ALOGE("src_format HAL_PIXEL_FORMAT_YCbCr_420_SP");
332         ret = conv_sw_src_yuv420sp(handle);
333         break;
334     case HAL_PIXEL_FORMAT_ARGB888:
335     ALOGE("src_format HAL_PIXEL_FORMAT_ARGB888");
336         ret = conv_sw_src_argb888(handle);
337         break;
338     default:
339         ret = CSC_ErrorUnsupportFormat;
340         break;
341     }
342
343     return ret;
344 }
345
346 static CSC_ERRORCODE conv_hw(
347     CSC_HANDLE *handle)
348 {
349     CSC_ERRORCODE ret = CSC_ErrorNone;
350     switch (handle->csc_hw_type) {
351 #ifdef ENABLE_FIMC
352     case CSC_HW_TYPE_FIMC:
353     {
354         void *src_addr[3];
355         void *dst_addr[3];
356         OMX_COLOR_FORMATTYPE src_omx_format;
357         OMX_COLOR_FORMATTYPE dst_omx_format;
358         src_addr[0] = handle->src_buffer.planes[CSC_Y_PLANE];
359         src_addr[1] = handle->src_buffer.planes[CSC_UV_PLANE];
360         dst_addr[0] = handle->dst_buffer.planes[CSC_Y_PLANE];
361         dst_addr[1] = handle->dst_buffer.planes[CSC_U_PLANE];
362         dst_addr[2] = handle->dst_buffer.planes[CSC_V_PLANE];
363         src_omx_format = hal_2_omx_pixel_format(handle->src_format.color_format);
364         dst_omx_format = hal_2_omx_pixel_format(handle->dst_format.color_format);
365         csc_hwconverter_convert_nv12t(
366             handle->csc_hw_handle,
367             dst_addr,
368             src_addr,
369             handle->dst_format.width,
370             handle->dst_format.height,
371             dst_omx_format,
372             src_omx_format);
373         break;
374     }
375 #endif
376 #ifdef ENABLE_GSCALER
377     case CSC_HW_TYPE_GSCALER:
378         if (exynos_gsc_convert(handle->csc_hw_handle) != 0) {
379             ALOGE("%s:: exynos_gsc_convert() fail", __func__);
380             ret = CSC_Error;
381         }
382         break;
383 #endif
384     default:
385         ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type);
386         ret = CSC_ErrorNotImplemented;
387         break;
388     }
389
390     return ret;
391 }
392
393 static CSC_ERRORCODE csc_init_hw(
394     void *handle)
395 {
396     CSC_HANDLE *csc_handle;
397     CSC_ERRORCODE ret = CSC_ErrorNone;
398
399     csc_handle = (CSC_HANDLE *)handle;
400     if (csc_handle->csc_method == CSC_METHOD_HW) {
401 #ifdef ENABLE_FIMC
402         csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC;
403 #endif
404 #ifdef ENABLE_GSCALER
405         csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER;
406 #endif
407         switch (csc_handle->csc_hw_type) {
408 #ifdef ENABLE_FIMC
409         case CSC_HW_TYPE_FIMC:
410             csc_handle->csc_hw_handle = csc_hwconverter_open();
411             ALOGV("%s:: CSC_HW_TYPE_FIMC", __func__);
412             break;
413 #endif
414 #ifdef ENABLE_GSCALER
415         case CSC_HW_TYPE_GSCALER:
416             if (csc_handle->hw_property.fixed_node >= 0)
417                 csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0);
418             else
419             csc_handle->csc_hw_handle = exynos_gsc_create();
420             ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__);
421             break;
422 #endif
423         default:
424             ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__);
425             csc_handle->csc_hw_handle == NULL;
426             break;
427         }
428     }
429
430     if (csc_handle->csc_method == CSC_METHOD_HW) {
431         if (csc_handle->csc_hw_handle == NULL) {
432             ALOGE("%s:: CSC_METHOD_HW can't open HW", __func__);
433             free(csc_handle);
434             csc_handle = NULL;
435         }
436     }
437
438     ALOGV("%s:: CSC_METHOD=%d", __func__, csc_handle->csc_method);
439
440     return ret;
441 }
442
443 static CSC_ERRORCODE csc_set_format(
444     void *handle)
445 {
446     CSC_HANDLE *csc_handle;
447     CSC_ERRORCODE ret = CSC_ErrorNone;
448
449     if (handle == NULL)
450         return CSC_ErrorNotInit;
451
452     csc_handle = (CSC_HANDLE *)handle;
453     if (csc_handle->csc_method == CSC_METHOD_HW) {
454         switch (csc_handle->csc_hw_type) {
455         case CSC_HW_TYPE_FIMC:
456             break;
457 #ifdef ENABLE_GSCALER
458         case CSC_HW_TYPE_GSCALER:
459             exynos_gsc_set_src_format(
460                 csc_handle->csc_hw_handle,
461                 ALIGN(csc_handle->src_format.width, GSCALER_IMG_ALIGN),
462                 ALIGN(csc_handle->src_format.height, GSCALER_IMG_ALIGN),
463                 csc_handle->src_format.crop_left,
464                 csc_handle->src_format.crop_top,
465                 csc_handle->src_format.crop_width,
466                 csc_handle->src_format.crop_height,
467                 HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format),
468                 csc_handle->src_format.cacheable,
469                 csc_handle->hw_property.mode_drm);
470
471             exynos_gsc_set_dst_format(
472                 csc_handle->csc_hw_handle,
473                 ALIGN(csc_handle->dst_format.width, GSCALER_IMG_ALIGN),
474                 ALIGN(csc_handle->dst_format.height, GSCALER_IMG_ALIGN),
475                 csc_handle->dst_format.crop_left,
476                 csc_handle->dst_format.crop_top,
477                 csc_handle->dst_format.crop_width,
478                 csc_handle->dst_format.crop_height,
479                 HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format),
480                 csc_handle->dst_format.cacheable,
481                 csc_handle->hw_property.mode_drm);
482             break;
483 #endif
484         default:
485             ALOGE("%s:: unsupported csc_hw_type", __func__);
486             break;
487         }
488     }
489
490     return ret;
491 }
492
493 static CSC_ERRORCODE csc_set_buffer(
494     void *handle)
495 {
496     CSC_HANDLE *csc_handle;
497     CSC_ERRORCODE ret = CSC_ErrorNone;
498     void *src_addr[3] = {NULL, };
499     void *dst_addr[3] = {NULL, };
500
501     if (handle == NULL)
502         return CSC_ErrorNotInit;
503
504     csc_handle = (CSC_HANDLE *)handle;
505     if (csc_handle->csc_method == CSC_METHOD_HW) {
506         src_addr[0] = csc_handle->src_buffer.planes[CSC_Y_PLANE];
507         src_addr[1] = csc_handle->src_buffer.planes[CSC_U_PLANE];
508         src_addr[2] = csc_handle->src_buffer.planes[CSC_V_PLANE];
509         dst_addr[0] = csc_handle->dst_buffer.planes[CSC_Y_PLANE];
510         dst_addr[1] = csc_handle->dst_buffer.planes[CSC_U_PLANE];
511         dst_addr[2] = csc_handle->dst_buffer.planes[CSC_V_PLANE];
512
513         switch (csc_handle->csc_hw_type) {
514         case CSC_HW_TYPE_FIMC:
515             break;
516 #ifdef ENABLE_GSCALER
517         case CSC_HW_TYPE_GSCALER:
518             exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, src_addr);
519             exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, dst_addr);
520             break;
521 #endif
522         default:
523             ALOGE("%s:: unsupported csc_hw_type", __func__);
524             break;
525         }
526     }
527
528     return ret;
529 }
530
531 void *csc_init(
532     CSC_METHOD method)
533 {
534     CSC_HANDLE *csc_handle;
535     csc_handle = (CSC_HANDLE *)malloc(sizeof(CSC_HANDLE));
536     if (csc_handle == NULL)
537         return NULL;
538
539     memset(csc_handle, 0, sizeof(CSC_HANDLE));
540     csc_handle->hw_property.fixed_node = -1;
541     csc_handle->hw_property.mode_drm = 0;
542     csc_handle->csc_method = method;
543
544     return (void *)csc_handle;
545 }
546
547 CSC_ERRORCODE csc_deinit(
548     void *handle)
549 {
550     CSC_ERRORCODE ret = CSC_ErrorNone;
551     CSC_HANDLE *csc_handle;
552
553     csc_handle = (CSC_HANDLE *)handle;
554     if (csc_handle->csc_method == CSC_METHOD_HW) {
555         switch (csc_handle->csc_hw_type) {
556 #ifdef ENABLE_FIMC
557         case CSC_HW_TYPE_FIMC:
558             csc_hwconverter_close(csc_handle->csc_hw_handle);
559             break;
560 #endif
561 #ifdef ENABLE_GSCALER
562         case CSC_HW_TYPE_GSCALER:
563             exynos_gsc_destroy(csc_handle->csc_hw_handle);
564             break;
565 #endif
566         default:
567             ALOGE("%s:: unsupported csc_hw_type", __func__);
568             break;
569         }
570     }
571
572     if (csc_handle != NULL) {
573         free(csc_handle);
574         ret = CSC_ErrorNone;
575     }
576
577     return ret;
578 }
579
580 CSC_ERRORCODE csc_get_method(
581     void           *handle,
582     CSC_METHOD     *method)
583 {
584     CSC_HANDLE *csc_handle;
585     CSC_ERRORCODE ret = CSC_ErrorNone;
586
587     if (handle == NULL)
588         return CSC_ErrorNotInit;
589
590     csc_handle = (CSC_HANDLE *)handle;
591     *method = csc_handle->csc_method;
592
593     return ret;
594 }
595
596 CSC_ERRORCODE csc_set_hw_property(
597     void                *handle,
598     CSC_HW_PROPERTY_TYPE property,
599     int                  value)
600 {
601     CSC_HANDLE *csc_handle;
602     CSC_ERRORCODE ret = CSC_ErrorNone;
603
604     if (handle == NULL)
605         return CSC_ErrorNotInit;
606
607     csc_handle = (CSC_HANDLE *)handle;
608     switch (property) {
609     case CSC_HW_PROPERTY_FIXED_NODE:
610         csc_handle->hw_property.fixed_node = value;
611         break;
612     case CSC_HW_PROPERTY_MODE_DRM:
613         csc_handle->hw_property.mode_drm = value;
614         break;
615     default:
616         ALOGE("%s:: not supported hw property", __func__);
617         ret = CSC_ErrorUnsupportFormat;
618     }
619
620     return ret;
621 }
622
623 CSC_ERRORCODE csc_get_src_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->src_format.width;
642     *height = csc_handle->src_format.height;
643     *crop_left = csc_handle->src_format.crop_left;
644     *crop_top = csc_handle->src_format.crop_top;
645     *crop_width = csc_handle->src_format.crop_width;
646     *crop_height = csc_handle->src_format.crop_height;
647     *color_format = csc_handle->src_format.color_format;
648     *cacheable = csc_handle->src_format.cacheable;
649
650     return ret;
651 }
652
653 CSC_ERRORCODE csc_set_src_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->src_format.width = width;
672     csc_handle->src_format.height = height;
673     csc_handle->src_format.crop_left = crop_left;
674     csc_handle->src_format.crop_top = crop_top;
675     csc_handle->src_format.crop_width = crop_width;
676     csc_handle->src_format.crop_height = crop_height;
677     csc_handle->src_format.color_format = color_format;
678     csc_handle->src_format.cacheable = cacheable;
679
680     return ret;
681 }
682
683 CSC_ERRORCODE csc_get_dst_format(
684     void           *handle,
685     unsigned int   *width,
686     unsigned int   *height,
687     unsigned int   *crop_left,
688     unsigned int   *crop_top,
689     unsigned int   *crop_width,
690     unsigned int   *crop_height,
691     unsigned int   *color_format,
692     unsigned int   *cacheable)
693 {
694     CSC_HANDLE *csc_handle;
695     CSC_ERRORCODE ret = CSC_ErrorNone;
696
697     if (handle == NULL)
698         return CSC_ErrorNotInit;
699
700     csc_handle = (CSC_HANDLE *)handle;
701     *width = csc_handle->dst_format.width;
702     *height = csc_handle->dst_format.height;
703     *crop_left = csc_handle->dst_format.crop_left;
704     *crop_top = csc_handle->dst_format.crop_top;
705     *crop_width = csc_handle->dst_format.crop_width;
706     *crop_height = csc_handle->dst_format.crop_height;
707     *color_format = csc_handle->dst_format.color_format;
708     *cacheable = csc_handle->dst_format.cacheable;
709
710     return ret;
711 }
712
713 CSC_ERRORCODE csc_set_dst_format(
714     void           *handle,
715     unsigned int    width,
716     unsigned int    height,
717     unsigned int    crop_left,
718     unsigned int    crop_top,
719     unsigned int    crop_width,
720     unsigned int    crop_height,
721     unsigned int    color_format,
722     unsigned int    cacheable)
723 {
724     CSC_HANDLE *csc_handle;
725     CSC_ERRORCODE ret = CSC_ErrorNone;
726
727     if (handle == NULL)
728         return CSC_ErrorNotInit;
729
730     csc_handle = (CSC_HANDLE *)handle;
731     csc_handle->dst_format.width = width;
732     csc_handle->dst_format.height = height;
733     csc_handle->dst_format.crop_left = crop_left;
734     csc_handle->dst_format.crop_top = crop_top;
735     csc_handle->dst_format.crop_width = crop_width;
736     csc_handle->dst_format.crop_height = crop_height;
737     csc_handle->dst_format.color_format = color_format;
738     csc_handle->dst_format.cacheable = cacheable;
739
740     return ret;
741 }
742
743 CSC_ERRORCODE csc_set_src_buffer(
744     void           *handle,
745     unsigned char  *y,
746     unsigned char  *u,
747     unsigned char  *v,
748     int             ion_fd)
749 {
750     CSC_HANDLE *csc_handle;
751     CSC_ERRORCODE ret = CSC_ErrorNone;
752     void *addr[3] = {NULL, };
753
754     if (handle == NULL)
755         return CSC_ErrorNotInit;
756
757     csc_handle = (CSC_HANDLE *)handle;
758     csc_handle->src_buffer.planes[CSC_Y_PLANE] = y;
759     csc_handle->src_buffer.planes[CSC_U_PLANE] = u;
760     csc_handle->src_buffer.planes[CSC_V_PLANE] = v;
761
762     return ret;
763 }
764
765 CSC_ERRORCODE csc_set_dst_buffer(
766     void           *handle,
767     unsigned char  *y,
768     unsigned char  *u,
769     unsigned char  *v,
770     int             ion_fd)
771 {
772     CSC_HANDLE *csc_handle;
773     CSC_ERRORCODE ret = CSC_ErrorNone;
774     void *addr[3] = {NULL, };
775
776     if (handle == NULL)
777         return CSC_ErrorNotInit;
778
779     csc_handle = (CSC_HANDLE *)handle;
780     csc_handle->dst_buffer.planes[CSC_Y_PLANE] = y;
781     csc_handle->dst_buffer.planes[CSC_U_PLANE] = u;
782     csc_handle->dst_buffer.planes[CSC_V_PLANE] = v;
783
784     return ret;
785 }
786
787 CSC_ERRORCODE csc_convert(
788     void *handle)
789 {
790     CSC_HANDLE *csc_handle = (CSC_HANDLE *)handle;
791     CSC_ERRORCODE ret = CSC_ErrorNone;
792
793     if (csc_handle == NULL)
794         return CSC_ErrorNotInit;
795
796     if ((csc_handle->csc_method == CSC_METHOD_HW) &&
797         (csc_handle->csc_hw_handle == NULL))
798         csc_init_hw(handle);
799
800     csc_set_format(csc_handle);
801     csc_set_buffer(csc_handle);
802
803     if (csc_handle->csc_method == CSC_METHOD_HW) {
804     ALOGE("conv_hw");
805         ret = conv_hw(csc_handle);
806         }
807     else {
808     ALOGE("conv_sw");
809         ret = conv_sw(csc_handle);
810     ALOGE("after conv_sw");
811         }
812
813     return ret;
814 }