• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
conv_sw_src_argb888(CSC_HANDLE * handle)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 */
conv_sw_src_nv12t(CSC_HANDLE * handle)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 */
conv_sw_src_yuv420p(CSC_HANDLE * handle)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 */
conv_sw_src_yuv420sp(CSC_HANDLE * handle)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 
conv_sw(CSC_HANDLE * handle)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 
conv_hw(CSC_HANDLE * handle)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 
csc_init_hw(void * handle)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 
csc_set_format(void * handle)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 
csc_set_buffer(void * handle)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 
csc_init(CSC_METHOD method)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 
csc_deinit(void * handle)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 
csc_get_method(void * handle,CSC_METHOD * method)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 
csc_set_hw_property(void * handle,CSC_HW_PROPERTY_TYPE property,int value)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 
csc_get_src_format(void * handle,unsigned int * width,unsigned int * height,unsigned int * crop_left,unsigned int * crop_top,unsigned int * crop_width,unsigned int * crop_height,unsigned int * color_format,unsigned int * cacheable)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 
csc_set_src_format(void * handle,unsigned int width,unsigned int height,unsigned int crop_left,unsigned int crop_top,unsigned int crop_width,unsigned int crop_height,unsigned int color_format,unsigned int cacheable)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 
csc_get_dst_format(void * handle,unsigned int * width,unsigned int * height,unsigned int * crop_left,unsigned int * crop_top,unsigned int * crop_width,unsigned int * crop_height,unsigned int * color_format,unsigned int * cacheable)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 
csc_set_dst_format(void * handle,unsigned int width,unsigned int height,unsigned int crop_left,unsigned int crop_top,unsigned int crop_width,unsigned int crop_height,unsigned int color_format,unsigned int cacheable)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 
csc_set_src_buffer(void * handle,void * addr[3])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 
csc_set_dst_buffer(void * handle,void * addr[3])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 
csc_convert(void * handle)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 }
727