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